diff options
| author | Nathan Reiner <nathan@nathanreiner.xyz> | 2024-01-18 00:04:25 +0100 |
|---|---|---|
| committer | Nathan Reiner <nathan@nathanreiner.xyz> | 2024-01-18 00:04:25 +0100 |
| commit | 670c1881af4680ce7c248498528d14b98210af3f (patch) | |
| tree | 41b6bd315ccbc7540f02b83f8e755dfc51770bee /src/complex.rs | |
| parent | 3cd19a42e1cc66b09f4279625385e00292b8900d (diff) | |
complex: use real pow on real only complex to gain precision
Diffstat (limited to 'src/complex.rs')
| -rw-r--r-- | src/complex.rs | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/src/complex.rs b/src/complex.rs index d120c29..5b95df4 100644 --- a/src/complex.rs +++ b/src/complex.rs @@ -1,6 +1,6 @@ +use std::f64::consts::E; use std::num::ParseFloatError; use std::str::FromStr; -use std::f64::consts::E; #[derive(Clone, Copy, Default, Debug)] pub struct Complex { @@ -13,12 +13,8 @@ impl Complex { Self { real, imag } } - pub fn div(&mut self, other: &Self) { - let z = other.real * other.real + other.imag * other.imag; - self.real = self.real * other.real + self.imag * other.imag; - self.real /= z; - self.imag = self.imag * other.real - self.real * other.imag; - self.imag /= z; + pub fn is_real(&self) -> bool { + self.imag == 0.0 } pub fn abs(&self) -> f64 { @@ -26,12 +22,16 @@ impl Complex { } pub fn pow(&self, rhs: Self) -> Self { - let r = self.abs(); - let x = (self.imag / self.real).atan(); - let lnr = r.ln(); - let alpha = lnr * rhs.imag + x * rhs.real; - let e_exp = E.powf(lnr * rhs.real - rhs.imag * x); - Complex::new(e_exp * alpha.cos(), e_exp * alpha.sin()) + if self.is_real() && rhs.is_real() { + Complex::new(self.real.powf(rhs.real), 0.0) + } else { + let r = self.abs(); + let x = (self.imag / self.real).atan(); + let lnr = r.ln(); + let alpha = lnr * rhs.imag + x * rhs.real; + let e_exp = E.powf(lnr * rhs.real - rhs.imag * x); + Complex::new(e_exp * alpha.cos(), e_exp * alpha.sin()) + } } pub fn sqrt(&self) -> Self { @@ -39,14 +39,14 @@ impl Complex { } pub fn cos(&self) -> Self { - let e : Complex = E.into(); + let e: Complex = E.into(); let i = Complex::new(0.0, 1.0); Complex::new(e.pow(&i * self).real, 0.0) } pub fn sin(&self) -> Self { - let e : Complex = E.into(); + let e: Complex = E.into(); let i = Complex::new(0.0, 1.0); Complex::new(e.pow(&i * self).imag, 0.0) |