Skip to content

Commit 059856a

Browse files
authored
Merge pull request #20878 from tiehuis/std-math-complex-fixes
std.math.complex fixes
2 parents 7c5ee3e + 8438855 commit 059856a

File tree

19 files changed

+102
-120
lines changed

19 files changed

+102
-120
lines changed

lib/std/math/complex/abs.zig

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@ pub fn abs(z: anytype) @TypeOf(z.re, z.im) {
99
return math.hypot(z.re, z.im);
1010
}
1111

12-
const epsilon = 0.0001;
13-
1412
test abs {
13+
const epsilon = math.floatEps(f32);
1514
const a = Complex(f32).init(5, 3);
1615
const c = abs(a);
17-
try testing.expect(math.approxEqAbs(f32, c, 5.83095, epsilon));
16+
try testing.expectApproxEqAbs(5.8309517, c, epsilon);
1817
}

lib/std/math/complex/acos.zig

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,11 @@ pub fn acos(z: anytype) Complex(@TypeOf(z.re, z.im)) {
1111
return Complex(T).init(@as(T, math.pi) / 2 - q.re, -q.im);
1212
}
1313

14-
const epsilon = 0.0001;
15-
1614
test acos {
15+
const epsilon = math.floatEps(f32);
1716
const a = Complex(f32).init(5, 3);
1817
const c = acos(a);
1918

20-
try testing.expect(math.approxEqAbs(f32, c.re, 0.546975, epsilon));
21-
try testing.expect(math.approxEqAbs(f32, c.im, -2.452914, epsilon));
19+
try testing.expectApproxEqAbs(0.5469737, c.re, epsilon);
20+
try testing.expectApproxEqAbs(-2.4529128, c.im, epsilon);
2221
}

lib/std/math/complex/acosh.zig

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,18 @@ const Complex = cmath.Complex;
88
pub fn acosh(z: anytype) Complex(@TypeOf(z.re, z.im)) {
99
const T = @TypeOf(z.re, z.im);
1010
const q = cmath.acos(z);
11-
return Complex(T).init(-q.im, q.re);
12-
}
1311

14-
const epsilon = 0.0001;
12+
return if (math.signbit(z.im))
13+
Complex(T).init(q.im, -q.re)
14+
else
15+
Complex(T).init(-q.im, q.re);
16+
}
1517

1618
test acosh {
19+
const epsilon = math.floatEps(f32);
1720
const a = Complex(f32).init(5, 3);
1821
const c = acosh(a);
1922

20-
try testing.expect(math.approxEqAbs(f32, c.re, 2.452914, epsilon));
21-
try testing.expect(math.approxEqAbs(f32, c.im, 0.546975, epsilon));
23+
try testing.expectApproxEqAbs(2.4529128, c.re, epsilon);
24+
try testing.expectApproxEqAbs(0.5469737, c.im, epsilon);
2225
}

lib/std/math/complex/arg.zig

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@ pub fn arg(z: anytype) @TypeOf(z.re, z.im) {
99
return math.atan2(z.im, z.re);
1010
}
1111

12-
const epsilon = 0.0001;
13-
1412
test arg {
13+
const epsilon = math.floatEps(f32);
1514
const a = Complex(f32).init(5, 3);
1615
const c = arg(a);
17-
try testing.expect(math.approxEqAbs(f32, c, 0.540420, epsilon));
16+
try testing.expectApproxEqAbs(0.5404195, c, epsilon);
1817
}

lib/std/math/complex/asin.zig

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@ pub fn asin(z: anytype) Complex(@TypeOf(z.re, z.im)) {
1717
return Complex(T).init(r.im, -r.re);
1818
}
1919

20-
const epsilon = 0.0001;
21-
2220
test asin {
21+
const epsilon = math.floatEps(f32);
2322
const a = Complex(f32).init(5, 3);
2423
const c = asin(a);
2524

26-
try testing.expect(math.approxEqAbs(f32, c.re, 1.023822, epsilon));
27-
try testing.expect(math.approxEqAbs(f32, c.im, 2.452914, epsilon));
25+
try testing.expectApproxEqAbs(1.0238227, c.re, epsilon);
26+
try testing.expectApproxEqAbs(2.4529128, c.im, epsilon);
2827
}

lib/std/math/complex/asinh.zig

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@ pub fn asinh(z: anytype) Complex(@TypeOf(z.re, z.im)) {
1212
return Complex(T).init(r.im, -r.re);
1313
}
1414

15-
const epsilon = 0.0001;
16-
1715
test asinh {
16+
const epsilon = math.floatEps(f32);
1817
const a = Complex(f32).init(5, 3);
1918
const c = asinh(a);
2019

21-
try testing.expect(math.approxEqAbs(f32, c.re, 2.459831, epsilon));
22-
try testing.expect(math.approxEqAbs(f32, c.im, 0.533999, epsilon));
20+
try testing.expectApproxEqAbs(2.4598298, c.re, epsilon);
21+
try testing.expectApproxEqAbs(0.5339993, c.im, epsilon);
2322
}

lib/std/math/complex/atan.zig

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -32,37 +32,22 @@ fn redupif32(x: f32) f32 {
3232
t -= 0.5;
3333
}
3434

35-
const u = @as(f32, @floatFromInt(@as(i32, @intFromFloat(t))));
36-
return ((x - u * DP1) - u * DP2) - t * DP3;
35+
const u: f32 = @trunc(t);
36+
return ((x - u * DP1) - u * DP2) - u * DP3;
3737
}
3838

3939
fn atan32(z: Complex(f32)) Complex(f32) {
40-
const maxnum = 1.0e38;
41-
4240
const x = z.re;
4341
const y = z.im;
4442

45-
if ((x == 0.0) and (y > 1.0)) {
46-
// overflow
47-
return Complex(f32).init(maxnum, maxnum);
48-
}
49-
5043
const x2 = x * x;
5144
var a = 1.0 - x2 - (y * y);
52-
if (a == 0.0) {
53-
// overflow
54-
return Complex(f32).init(maxnum, maxnum);
55-
}
5645

5746
var t = 0.5 * math.atan2(2.0 * x, a);
5847
const w = redupif32(t);
5948

6049
t = y - 1.0;
6150
a = x2 + t * t;
62-
if (a == 0.0) {
63-
// overflow
64-
return Complex(f32).init(maxnum, maxnum);
65-
}
6651

6752
t = y + 1.0;
6853
a = (x2 + (t * t)) / a;
@@ -81,57 +66,42 @@ fn redupif64(x: f64) f64 {
8166
t -= 0.5;
8267
}
8368

84-
const u = @as(f64, @floatFromInt(@as(i64, @intFromFloat(t))));
85-
return ((x - u * DP1) - u * DP2) - t * DP3;
69+
const u: f64 = @trunc(t);
70+
return ((x - u * DP1) - u * DP2) - u * DP3;
8671
}
8772

8873
fn atan64(z: Complex(f64)) Complex(f64) {
89-
const maxnum = 1.0e308;
90-
9174
const x = z.re;
9275
const y = z.im;
9376

94-
if ((x == 0.0) and (y > 1.0)) {
95-
// overflow
96-
return Complex(f64).init(maxnum, maxnum);
97-
}
98-
9977
const x2 = x * x;
10078
var a = 1.0 - x2 - (y * y);
101-
if (a == 0.0) {
102-
// overflow
103-
return Complex(f64).init(maxnum, maxnum);
104-
}
10579

10680
var t = 0.5 * math.atan2(2.0 * x, a);
10781
const w = redupif64(t);
10882

10983
t = y - 1.0;
11084
a = x2 + t * t;
111-
if (a == 0.0) {
112-
// overflow
113-
return Complex(f64).init(maxnum, maxnum);
114-
}
11585

11686
t = y + 1.0;
11787
a = (x2 + (t * t)) / a;
11888
return Complex(f64).init(w, 0.25 * @log(a));
11989
}
12090

121-
const epsilon = 0.0001;
122-
12391
test atan32 {
92+
const epsilon = math.floatEps(f32);
12493
const a = Complex(f32).init(5, 3);
12594
const c = atan(a);
12695

127-
try testing.expect(math.approxEqAbs(f32, c.re, 1.423679, epsilon));
128-
try testing.expect(math.approxEqAbs(f32, c.im, 0.086569, epsilon));
96+
try testing.expectApproxEqAbs(1.423679, c.re, epsilon);
97+
try testing.expectApproxEqAbs(0.086569, c.im, epsilon);
12998
}
13099

131100
test atan64 {
101+
const epsilon = math.floatEps(f64);
132102
const a = Complex(f64).init(5, 3);
133103
const c = atan(a);
134104

135-
try testing.expect(math.approxEqAbs(f64, c.re, 1.423679, epsilon));
136-
try testing.expect(math.approxEqAbs(f64, c.im, 0.086569, epsilon));
105+
try testing.expectApproxEqAbs(1.4236790442393028, c.re, epsilon);
106+
try testing.expectApproxEqAbs(0.08656905917945844, c.im, epsilon);
137107
}

lib/std/math/complex/atanh.zig

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@ pub fn atanh(z: anytype) Complex(@TypeOf(z.re, z.im)) {
1212
return Complex(T).init(r.im, -r.re);
1313
}
1414

15-
const epsilon = 0.0001;
16-
1715
test atanh {
16+
const epsilon = math.floatEps(f32);
1817
const a = Complex(f32).init(5, 3);
1918
const c = atanh(a);
2019

21-
try testing.expect(math.approxEqAbs(f32, c.re, 0.146947, epsilon));
22-
try testing.expect(math.approxEqAbs(f32, c.im, 1.480870, epsilon));
20+
try testing.expectApproxEqAbs(0.14694665, c.re, epsilon);
21+
try testing.expectApproxEqAbs(1.4808695, c.im, epsilon);
2322
}

lib/std/math/complex/conj.zig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ test conj {
1414
const a = Complex(f32).init(5, 3);
1515
const c = a.conjugate();
1616

17-
try testing.expect(c.re == 5 and c.im == -3);
17+
try testing.expectEqual(5, c.re);
18+
try testing.expectEqual(-3, c.im);
1819
}

lib/std/math/complex/cos.zig

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,11 @@ pub fn cos(z: anytype) Complex(@TypeOf(z.re, z.im)) {
1111
return cmath.cosh(p);
1212
}
1313

14-
const epsilon = 0.0001;
15-
1614
test cos {
15+
const epsilon = math.floatEps(f32);
1716
const a = Complex(f32).init(5, 3);
1817
const c = cos(a);
1918

20-
try testing.expect(math.approxEqAbs(f32, c.re, 2.855815, epsilon));
21-
try testing.expect(math.approxEqAbs(f32, c.im, 9.606383, epsilon));
19+
try testing.expectApproxEqAbs(2.8558152, c.re, epsilon);
20+
try testing.expectApproxEqAbs(9.606383, c.im, epsilon);
2221
}

0 commit comments

Comments
 (0)