a/math/complex/mod.rs
1//! Complex numbers: a [`Complex<T>`] is `re + im·i` with parts of the [`Float`] type `T`, `f32` or
2//! `f64`.
3//!
4//! They add with `+` and `+=`, subtract with `-` and `-=`, multiply with `*` and `*=` and divide
5//! with `/` and `/=`, each operand owned or borrowed, and take a float of their own type as an
6//! operand on either side. They negate with `-`, compare with `==`, add up with `Sum` and multiply
7//! with `Product`, and are written as `1+2i` by `Display`.
8//!
9//! [`Complex::abs`] and [`Complex::arg`] give the polar form, [`Complex::from_polar`] builds a
10//! number from it, and [`Complex::conj`], [`Complex::norm_sqr`] and [`Complex::recip`] the rest
11//! of the arithmetic. [`Complex::exp`], [`Complex::ln`], [`Complex::sqrt`], [`Complex::powi`],
12//! [`Complex::powf`] and [`Complex::powc`] are the principal values, with the branch cut of the
13//! logarithm and the square root along the negative real axis, where the sign of a zero imaginary
14//! part picks the side, as in C99's `<complex.h>`.
15
16mod float;
17mod ops;
18
19pub use float::Float;
20
21use core::fmt;
22
23/// The complex number `re + im·i`.
24///
25/// # Examples
26///
27/// ```
28/// use a::math::complex::Complex;
29///
30/// let z = Complex::new(3.0, 4.0);
31/// assert_eq!(z.abs(), 5.0);
32/// assert_eq!(z * z.conj(), Complex::new(25.0, 0.0));
33/// assert_eq!(Complex::new(-4.0, 0.0).sqrt(), Complex::new(0.0, 2.0));
34/// assert_eq!(format!("{}", z - 2.0 * Complex::I), "3+2i");
35/// ```
36#[derive(Clone, Copy, Debug, Default, PartialEq)]
37#[repr(C)]
38pub struct Complex<T> {
39 /// The real part.
40 pub re: T,
41 /// The imaginary part.
42 pub im: T,
43}
44
45impl<T> Complex<T> {
46 /// The number `re + im·i`.
47 #[inline]
48 pub const fn new(re: T, im: T) -> Self {
49 Complex { re, im }
50 }
51}
52
53impl<T: Float> Complex<T> {
54 /// Zero.
55 pub const ZERO: Self = Complex::new(T::ZERO, T::ZERO);
56 /// One.
57 pub const ONE: Self = Complex::new(T::ONE, T::ZERO);
58 /// The imaginary unit `i`.
59 pub const I: Self = Complex::new(T::ZERO, T::ONE);
60
61 /// The number with the absolute value `r` and the argument `theta`: `r·e^(i·theta)`.
62 #[inline]
63 pub fn from_polar(r: T, theta: T) -> Self {
64 let (sin, cos) = theta.sin_cos();
65 Complex::new(r * cos, r * sin)
66 }
67
68 /// The absolute value and the argument, as [`abs`](Self::abs) and [`arg`](Self::arg) give
69 /// them.
70 #[inline]
71 pub fn to_polar(self) -> (T, T) {
72 (self.abs(), self.arg())
73 }
74
75 /// The complex conjugate, `re - im·i`.
76 #[inline]
77 pub fn conj(self) -> Self {
78 Complex::new(self.re, -self.im)
79 }
80
81 /// The absolute value `√(re² + im²)`, without an overflow or underflow in the squares.
82 #[inline]
83 pub fn abs(self) -> T {
84 self.re.hypot(self.im)
85 }
86
87 /// The square of the absolute value, `re² + im²`: cheaper than `abs`, but it overflows and
88 /// underflows where the squares do.
89 #[inline]
90 pub fn norm_sqr(self) -> T {
91 self.re * self.re + self.im * self.im
92 }
93
94 /// The argument, the angle from the positive real axis, in `(-π, π]`; `-π` for a negative
95 /// real number with a negative zero imaginary part.
96 #[inline]
97 pub fn arg(self) -> T {
98 self.im.atan2(self.re)
99 }
100
101 /// `1 / self`.
102 #[inline]
103 pub fn recip(self) -> Self {
104 Self::ONE / self
105 }
106
107 /// Whether both parts are finite.
108 #[inline]
109 pub fn is_finite(self) -> bool {
110 self.re.is_finite() && self.im.is_finite()
111 }
112
113 /// Whether either part is NaN.
114 #[inline]
115 pub fn is_nan(self) -> bool {
116 self.re.is_nan() || self.im.is_nan()
117 }
118
119 /// `e^self`: `e^re·(cos im + i·sin im)`. A real number stays real, with the sign of its zero
120 /// imaginary part.
121 pub fn exp(self) -> Self {
122 let r = self.re.exp();
123 if self.im == T::ZERO {
124 return Complex::new(r, self.im);
125 }
126 let (sin, cos) = self.im.sin_cos();
127 if r.is_infinite() && self.re.is_finite() {
128 // `e^re` overflows where `e^re·cos` may not, as for `exp(710 + i·π/4)`: the
129 // trigonometric factor between two halves of the exponential.
130 let h = (self.re * T::HALF).exp();
131 return Complex::new(h * cos * h, h * sin * h);
132 }
133 Complex::new(r * cos, r * sin)
134 }
135
136 /// The principal natural logarithm, `ln |self| + i·arg(self)`, whose imaginary part is in
137 /// `(-π, π]`. The logarithm of zero is `-∞`. Near the unit circle the real part is
138 /// `ln(1 + (|self|² - 1)) / 2`, so that it keeps its digits where `ln |self|` is small; where
139 /// `|self|` overflows, or is subnormal, it is `ln(big) + ln(1 + (small/big)²) / 2` of the
140 /// larger and the smaller part, so that `ln(MAX + MAX·i)` is finite.
141 pub fn ln(self) -> Self {
142 let (a, b) = (self.re.abs(), self.im.abs());
143 let (big, small) = if a >= b { (a, b) } else { (b, a) };
144 let re = if big > T::HALF && big < T::TWO {
145 ((big - T::ONE) * (big + T::ONE) + small * small).ln_1p() * T::HALF
146 } else {
147 let m = self.abs();
148 if m.is_finite() && m >= T::MIN_POSITIVE {
149 m.ln()
150 } else {
151 Self::ln_of_extreme(m, big, small)
152 }
153 };
154 Complex::new(re, self.arg())
155 }
156
157 /// `ln |z|` from its absolute value `m` and its larger and smaller part, where `m` overflows
158 /// or is subnormal: `ln(big) + ln(1 + (small/big)²) / 2`. Zero, infinities and NaNs as
159 /// `ln m` gives them.
160 #[cold]
161 #[inline(never)]
162 fn ln_of_extreme(m: T, big: T, small: T) -> T {
163 if big == T::ZERO || !big.is_finite() || !small.is_finite() {
164 return m.ln();
165 }
166 let r = small / big;
167 big.ln() + (r * r).ln_1p() * T::HALF
168 }
169
170 /// The principal square root, whose real part is not negative, by Kahan's method, which
171 /// neither overflows nor cancels: for `re ≥ 0`, `t = √((re + |self|) / 2)` and the root
172 /// `t + i·im / (2t)`, and the other way round for `re < 0`. Infinities and NaNs give what
173 /// C99's `csqrt` gives.
174 pub fn sqrt(self) -> Self {
175 let (re, im) = (self.re, self.im);
176 if re == T::ZERO && im == T::ZERO {
177 return Complex::new(T::ZERO, im);
178 }
179 if im.is_infinite() {
180 return Complex::new(T::INFINITY, im);
181 }
182 if re.is_infinite() {
183 let zero_or_nan = if im.is_nan() {
184 im
185 } else {
186 T::ZERO.copysign(im)
187 };
188 return if re > T::ZERO {
189 Complex::new(re, zero_or_nan)
190 } else {
191 Complex::new(zero_or_nan.abs(), T::INFINITY.copysign(im))
192 };
193 }
194 if re.is_nan() || im.is_nan() {
195 return Complex::new(T::NAN, T::NAN);
196 }
197 let big = re.abs().max(im.abs());
198 if big < T::from_f64(4.0) * T::MIN_POSITIVE {
199 // Near the subnormals: scaled up by 2^64, exactly, and the root back by 2^32.
200 let up = T::from_f64(18_446_744_073_709_551_616.0);
201 return (self * up).sqrt() / T::from_f64(4_294_967_296.0);
202 }
203 if big > T::MAX / T::from_f64(4.0) {
204 return (self * T::from_f64(0.25)).sqrt() * T::TWO;
205 }
206 let t = ((re.abs() + self.abs()) * T::HALF).sqrt();
207 if re >= T::ZERO {
208 Complex::new(t, im / (T::TWO * t))
209 } else {
210 Complex::new(im.abs() / (T::TWO * t), t.copysign(im))
211 }
212 }
213
214 /// `self` to the integer power `n`, by repeated squaring: exact as long as the products are.
215 /// A negative power is the power of the reciprocal, and `0^0` is 1.
216 pub fn powi(self, n: i32) -> Self {
217 let mut base = if n < 0 { self.recip() } else { self };
218 let mut n = n.unsigned_abs();
219 let mut r = Self::ONE;
220 while n > 0 {
221 if n & 1 == 1 {
222 r *= base;
223 }
224 n >>= 1;
225 if n > 0 {
226 base *= base;
227 }
228 }
229 r
230 }
231
232 /// The principal value of `self` to the real power `x`: `e^(x·ln self)`, with `0^x = 0` for
233 /// `x ≠ 0` and `0^0 = 1`.
234 pub fn powf(self, x: T) -> Self {
235 if self.re == T::ZERO && self.im == T::ZERO {
236 return if x == T::ZERO { Self::ONE } else { Self::ZERO };
237 }
238 (self.ln() * x).exp()
239 }
240
241 /// The principal value of `self` to the complex power `w`: `e^(w·ln self)`, with `0^w = 0`
242 /// for `w ≠ 0` and `0^0 = 1`.
243 pub fn powc(self, w: Self) -> Self {
244 if self.re == T::ZERO && self.im == T::ZERO {
245 return if w == Self::ZERO {
246 Self::ONE
247 } else {
248 Self::ZERO
249 };
250 }
251 (self.ln() * w).exp()
252 }
253}
254
255impl<T: Float> From<T> for Complex<T> {
256 /// The real number `re + 0·i`.
257 #[inline]
258 fn from(re: T) -> Self {
259 Complex::new(re, T::ZERO)
260 }
261}
262
263impl<T: Float> fmt::Display for Complex<T> {
264 /// Writes `re+imi` or `re-imi`, each part as `Display` writes the float, with the precision
265 /// given: `1.5-2i`, or `1.50-2.00i` with `{:.2}`.
266 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
267 let sign = if self.im.is_sign_negative() { '-' } else { '+' };
268 match f.precision() {
269 Some(p) => write!(f, "{:.*}{}{:.*}i", p, self.re, sign, p, self.im.abs()),
270 None => write!(f, "{}{}{}i", self.re, sign, self.im.abs()),
271 }
272 }
273}