authorgravatar for 77922942+expikr@users.noreply.github.comexpikr <77922942+expikr@users.noreply.github.com> 2024-01-20 14:32:07+08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-01-20 01:32:07-05:00
logb729a3f008304d464b431f8ac34ad16cde08ba7b
tree00b0c9c4d1c9c5a8f75bab77ce4b39a7748b173a
parent1a98fcd00abb7266418532a103214467497d58c6
signaturebadge-check Signed by PGP key B5690EEEBB952194

std.math: make hypot infer type from argument (#17910)

using peer type resolution

3 files changed, 21 insertions(+), 14 deletions(-)

lib/std/math/complex/abs.zig+2-3
...@@ -5,9 +5,8 @@ const cmath = math.complex;...@@ -5,9 +5,8 @@ const cmath = math.complex;
5const Complex = cmath.Complex;5const Complex = cmath.Complex;
66
7/// Returns the absolute value (modulus) of z.7/// Returns the absolute value (modulus) of z.
8pub fn abs(z: anytype) @TypeOf(z.re) {8pub fn abs(z: anytype) @TypeOf(z.re, z.im) {
9 const T = @TypeOf(z.re);9 return math.hypot(z.re, z.im);
10 return math.hypot(T, z.re, z.im);
11}10}
1211
13const epsilon = 0.0001;12const epsilon = 0.0001;
lib/std/math/complex/sqrt.zig+4-4
...@@ -56,13 +56,13 @@ fn sqrt32(z: Complex(f32)) Complex(f32) {...@@ -56,13 +56,13 @@ fn sqrt32(z: Complex(f32)) Complex(f32) {
56 const dy = @as(f64, y);56 const dy = @as(f64, y);
5757
58 if (dx >= 0) {58 if (dx >= 0) {
59 const t = @sqrt((dx + math.hypot(f64, dx, dy)) * 0.5);59 const t = @sqrt((dx + math.hypot(dx, dy)) * 0.5);
60 return Complex(f32).init(60 return Complex(f32).init(
61 @as(f32, @floatCast(t)),61 @as(f32, @floatCast(t)),
62 @as(f32, @floatCast(dy / (2.0 * t))),62 @as(f32, @floatCast(dy / (2.0 * t))),
63 );63 );
64 } else {64 } else {
65 const t = @sqrt((-dx + math.hypot(f64, dx, dy)) * 0.5);65 const t = @sqrt((-dx + math.hypot(dx, dy)) * 0.5);
66 return Complex(f32).init(66 return Complex(f32).init(
67 @as(f32, @floatCast(@abs(y) / (2.0 * t))),67 @as(f32, @floatCast(@abs(y) / (2.0 * t))),
68 @as(f32, @floatCast(math.copysign(t, y))),68 @as(f32, @floatCast(math.copysign(t, y))),
...@@ -112,10 +112,10 @@ fn sqrt64(z: Complex(f64)) Complex(f64) {...@@ -112,10 +112,10 @@ fn sqrt64(z: Complex(f64)) Complex(f64) {
112112
113 var result: Complex(f64) = undefined;113 var result: Complex(f64) = undefined;
114 if (x >= 0) {114 if (x >= 0) {
115 const t = @sqrt((x + math.hypot(f64, x, y)) * 0.5);115 const t = @sqrt((x + math.hypot(x, y)) * 0.5);
116 result = Complex(f64).init(t, y / (2.0 * t));116 result = Complex(f64).init(t, y / (2.0 * t));
117 } else {117 } else {
118 const t = @sqrt((-x + math.hypot(f64, x, y)) * 0.5);118 const t = @sqrt((-x + math.hypot(x, y)) * 0.5);
119 result = Complex(f64).init(@abs(y) / (2.0 * t), math.copysign(t, y));119 result = Complex(f64).init(@abs(y) / (2.0 * t), math.copysign(t, y));
120 }120 }
121121
lib/std/math/hypot.zig+15-7
...@@ -12,11 +12,15 @@ const maxInt = std.math.maxInt;...@@ -12,11 +12,15 @@ const maxInt = std.math.maxInt;
12/// Returns sqrt(x * x + y * y), avoiding unnecessary overflow and underflow.12/// Returns sqrt(x * x + y * y), avoiding unnecessary overflow and underflow.
13///13///
14/// Special Cases:14/// Special Cases:
15/// - hypot(+-inf, y) = +inf15///
16/// - hypot(x, +-inf) = +inf16/// | x | y | hypot |
17/// - hypot(nan, y) = nan17/// |-------|-------|-------|
18/// - hypot(x, nan) = nan18/// | +inf | num | +inf |
19pub fn hypot(comptime T: type, x: T, y: T) T {19/// | num | +-inf | +inf |
20/// | nan | any | nan |
21/// | any | nan | nan |
22pub fn hypot(x: anytype, y: anytype) @TypeOf(x, y) {
23 const T = @TypeOf(x, y);
20 return switch (T) {24 return switch (T) {
21 f32 => hypot32(x, y),25 f32 => hypot32(x, y),
22 f64 => hypot64(x, y),26 f64 => hypot64(x, y),
...@@ -121,8 +125,12 @@ fn hypot64(x: f64, y: f64) f64 {...@@ -121,8 +125,12 @@ fn hypot64(x: f64, y: f64) f64 {
121}125}
122126
123test "math.hypot" {127test "math.hypot" {
124 try expect(hypot(f32, 0.0, -1.2) == hypot32(0.0, -1.2));128 const x32: f32 = 0.0;
125 try expect(hypot(f64, 0.0, -1.2) == hypot64(0.0, -1.2));129 const y32: f32 = -1.2;
130 const x64: f64 = 0.0;
131 const y64: f64 = -1.2;
132 try expect(hypot(x32, y32) == hypot32(0.0, -1.2));
133 try expect(hypot(x64, y64) == hypot64(0.0, -1.2));
126}134}
127135
128test "math.hypot32" {136test "math.hypot32" {