authorgravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2024-07-29 16:26:09+12:00
committergravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2024-07-30 15:38:00+12:00
log2bd7af63d76d1c61bfd77a5402f94d105c375a1d
tree14f2fffdf23009c2a63fe2d4380d63c85c319eae
parentf219286573a7a1edafe3e1b5bc1e521a379ee2e2

std.math.complex: fix acosh/atan/cosh/sqrt

Some of these are upstream changes since the original port, others are translation errors.

4 files changed, 14 insertions(+), 40 deletions(-)

lib/std/math/complex/acosh.zig+5-1
...@@ -8,7 +8,11 @@ const Complex = cmath.Complex;...@@ -8,7 +8,11 @@ const Complex = cmath.Complex;
8pub fn acosh(z: anytype) Complex(@TypeOf(z.re, z.im)) {8pub fn acosh(z: anytype) Complex(@TypeOf(z.re, z.im)) {
9 const T = @TypeOf(z.re, z.im);9 const T = @TypeOf(z.re, z.im);
10 const q = cmath.acos(z);10 const q = cmath.acos(z);
11 return Complex(T).init(-q.im, q.re);11
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);
12}16}
1317
14const epsilon = 0.0001;18const epsilon = 0.0001;
lib/std/math/complex/atan.zig+4-34
...@@ -32,37 +32,22 @@ fn redupif32(x: f32) f32 {...@@ -32,37 +32,22 @@ fn redupif32(x: f32) f32 {
32 t -= 0.5;32 t -= 0.5;
33 }33 }
3434
35 const u = @as(f32, @floatFromInt(@as(i32, @intFromFloat(t))));35 const u: f32 = @trunc(t);
36 return ((x - u * DP1) - u * DP2) - t * DP3;36 return ((x - u * DP1) - u * DP2) - u * DP3;
37}37}
3838
39fn atan32(z: Complex(f32)) Complex(f32) {39fn atan32(z: Complex(f32)) Complex(f32) {
40 const maxnum = 1.0e38;
41
42 const x = z.re;40 const x = z.re;
43 const y = z.im;41 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
50 const x2 = x * x;43 const x2 = x * x;
51 var a = 1.0 - x2 - (y * y);44 var a = 1.0 - x2 - (y * y);
52 if (a == 0.0) {
53 // overflow
54 return Complex(f32).init(maxnum, maxnum);
55 }
5645
57 var t = 0.5 * math.atan2(2.0 * x, a);46 var t = 0.5 * math.atan2(2.0 * x, a);
58 const w = redupif32(t);47 const w = redupif32(t);
5948
60 t = y - 1.0;49 t = y - 1.0;
61 a = x2 + t * t;50 a = x2 + t * t;
62 if (a == 0.0) {
63 // overflow
64 return Complex(f32).init(maxnum, maxnum);
65 }
6651
67 t = y + 1.0;52 t = y + 1.0;
68 a = (x2 + (t * t)) / a;53 a = (x2 + (t * t)) / a;
...@@ -81,37 +66,22 @@ fn redupif64(x: f64) f64 {...@@ -81,37 +66,22 @@ fn redupif64(x: f64) f64 {
81 t -= 0.5;66 t -= 0.5;
82 }67 }
8368
84 const u = @as(f64, @floatFromInt(@as(i64, @intFromFloat(t))));69 const u: f64 = @trunc(t);
85 return ((x - u * DP1) - u * DP2) - t * DP3;70 return ((x - u * DP1) - u * DP2) - u * DP3;
86}71}
8772
88fn atan64(z: Complex(f64)) Complex(f64) {73fn atan64(z: Complex(f64)) Complex(f64) {
89 const maxnum = 1.0e308;
90
91 const x = z.re;74 const x = z.re;
92 const y = z.im;75 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
99 const x2 = x * x;77 const x2 = x * x;
100 var a = 1.0 - x2 - (y * y);78 var a = 1.0 - x2 - (y * y);
101 if (a == 0.0) {
102 // overflow
103 return Complex(f64).init(maxnum, maxnum);
104 }
10579
106 var t = 0.5 * math.atan2(2.0 * x, a);80 var t = 0.5 * math.atan2(2.0 * x, a);
107 const w = redupif64(t);81 const w = redupif64(t);
10882
109 t = y - 1.0;83 t = y - 1.0;
110 a = x2 + t * t;84 a = x2 + t * t;
111 if (a == 0.0) {
112 // overflow
113 return Complex(f64).init(maxnum, maxnum);
114 }
11585
116 t = y + 1.0;86 t = y + 1.0;
117 a = (x2 + (t * t)) / a;87 a = (x2 + (t * t)) / a;
lib/std/math/complex/cosh.zig+3-3
...@@ -34,7 +34,7 @@ fn cosh32(z: Complex(f32)) Complex(f32) {...@@ -34,7 +34,7 @@ fn cosh32(z: Complex(f32)) Complex(f32) {
3434
35 if (ix < 0x7f800000 and iy < 0x7f800000) {35 if (ix < 0x7f800000 and iy < 0x7f800000) {
36 if (iy == 0) {36 if (iy == 0) {
37 return Complex(f32).init(math.cosh(x), y);37 return Complex(f32).init(math.cosh(x), x * y);
38 }38 }
39 // small x: normal case39 // small x: normal case
40 if (ix < 0x41100000) {40 if (ix < 0x41100000) {
...@@ -45,7 +45,7 @@ fn cosh32(z: Complex(f32)) Complex(f32) {...@@ -45,7 +45,7 @@ fn cosh32(z: Complex(f32)) Complex(f32) {
45 if (ix < 0x42b17218) {45 if (ix < 0x42b17218) {
46 // x < 88.7: exp(|x|) won't overflow46 // x < 88.7: exp(|x|) won't overflow
47 const h = @exp(@abs(x)) * 0.5;47 const h = @exp(@abs(x)) * 0.5;
48 return Complex(f32).init(math.copysign(h, x) * @cos(y), h * @sin(y));48 return Complex(f32).init(h * @cos(y), math.copysign(h, x) * @sin(y));
49 }49 }
50 // x < 192.7: scale to avoid overflow50 // x < 192.7: scale to avoid overflow
51 else if (ix < 0x4340b1e7) {51 else if (ix < 0x4340b1e7) {
...@@ -68,7 +68,7 @@ fn cosh32(z: Complex(f32)) Complex(f32) {...@@ -68,7 +68,7 @@ fn cosh32(z: Complex(f32)) Complex(f32) {
68 if (hx & 0x7fffff == 0) {68 if (hx & 0x7fffff == 0) {
69 return Complex(f32).init(x * x, math.copysign(@as(f32, 0.0), x) * y);69 return Complex(f32).init(x * x, math.copysign(@as(f32, 0.0), x) * y);
70 }70 }
71 return Complex(f32).init(x, math.copysign(@as(f32, 0.0), (x + x) * y));71 return Complex(f32).init(x * x, math.copysign(@as(f32, 0.0), (x + x) * y));
72 }72 }
7373
74 if (ix < 0x7f800000 and iy >= 0x7f800000) {74 if (ix < 0x7f800000 and iy >= 0x7f800000) {
lib/std/math/complex/sqrt.zig+2-2
...@@ -43,7 +43,7 @@ fn sqrt32(z: Complex(f32)) Complex(f32) {...@@ -43,7 +43,7 @@ fn sqrt32(z: Complex(f32)) Complex(f32) {
43 // sqrt(-inf + i nan) = nan +- inf i43 // sqrt(-inf + i nan) = nan +- inf i
44 // sqrt(-inf + iy) = 0 + inf i44 // sqrt(-inf + iy) = 0 + inf i
45 if (math.signbit(x)) {45 if (math.signbit(x)) {
46 return Complex(f32).init(@abs(x - y), math.copysign(x, y));46 return Complex(f32).init(@abs(y - y), math.copysign(x, y));
47 } else {47 } else {
48 return Complex(f32).init(x, math.copysign(y - y, y));48 return Complex(f32).init(x, math.copysign(y - y, y));
49 }49 }
...@@ -94,7 +94,7 @@ fn sqrt64(z: Complex(f64)) Complex(f64) {...@@ -94,7 +94,7 @@ fn sqrt64(z: Complex(f64)) Complex(f64) {
94 // sqrt(-inf + i nan) = nan +- inf i94 // sqrt(-inf + i nan) = nan +- inf i
95 // sqrt(-inf + iy) = 0 + inf i95 // sqrt(-inf + iy) = 0 + inf i
96 if (math.signbit(x)) {96 if (math.signbit(x)) {
97 return Complex(f64).init(@abs(x - y), math.copysign(x, y));97 return Complex(f64).init(@abs(y - y), math.copysign(x, y));
98 } else {98 } else {
99 return Complex(f64).init(x, math.copysign(y - y, y));99 return Complex(f64).init(x, math.copysign(y - y, y));
100 }100 }