1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
// The `fn name[..][..](self: Self, ..)` shape is the macro DSL's, as in
// `thermite::math`, which allows this lint at its module root for the same reason.
//! The complex math trait family.
//!
//! Thermite's math families ([`CoreMath`](thermite::math::CoreMath),
//! [`TranscendentalMath`](thermite::math::TranscendentalMath),
//! [`SpatialMath`](thermite::math::SpatialMath),
//! [`RealMath`](thermite::math::RealMath)) are all `Self -> Self`, a real vector
//! having nothing else to return. A complex number does: its modulus and argument
//! are real, and its polar form is a pair of reals. Those operations get their own
//! family here, built the way the core ones are:
//!
//! - [`ComplexVector`] carries the structure: the associated real type
//! [`Real`](ComplexVector::Real), the component accessors, and the operations
//! that take no [`Policy`] (`conj`, `norm_sqr`, `inv`, `norm_l1`).
//! - [`SpecializedComplexMath`] carries the algorithms, mirroring
//! [`thermite::math::specialized`].
//! - [`ComplexMathWithPolicy`](crate::math::ComplexMathWithPolicy) and [`ComplexMath`](crate::math::ComplexMath) are generated from it by
//! `decl_complex_math!` (a copy of core's `decl_math!`), giving each operation a
//! `foo_p::<P>()` and a default-policy `foo()` form.
//!
//! So `z.norm_p::<Precision>()` behaves as `x.sin_p::<Precision>()` does, and
//! generic code bounds on `V: ComplexMath` as it would on `V: TranscendentalMath`.
use ;
use Policy;
use *;
use ;
use crateRealFloatVector;
pub use crateSpecializedComplexSpecialMath;
/// A vector of complex numbers over a real vector type.
///
/// The structural half of the complex math family: it names the underlying real
/// vector ([`Real`](ComplexVector::Real)) and the operations that take no
/// [`Policy`]. The policy-dependent ones (modulus, argument, polar form, ...) are
/// in [`ComplexMath`](crate::math::ComplexMath).
///
/// # Mixed complex/real arithmetic
///
/// The supertraits promise the binary operators against [`Real`](Self::Real), so
/// generic code can scale, offset and fuse by a real vector without widening it
/// into a complex one:
///
/// ```
/// use thermite::prelude::*;
/// use thermite_complex::prelude::*;
///
/// // Horner evaluation of a real-coefficient polynomial at a complex point.
/// fn horner<T: ComplexVector>(z: T, coeffs: &[T::Real]) -> T {
/// let mut acc = T::real(coeffs[0]);
///
/// for &c in &coeffs[1..] {
/// acc = acc * z + c; // Complex * Complex, then Complex + Real
/// }
///
/// acc
/// }
///
/// type V = Vector<f64>;
///
/// // z^2 + 3 at z = 1 + 2i is -3 + 4i + 3 = 4i
/// let z = Complex::new(V::splat(1.0), V::splat(2.0));
/// let r = horner(z, &[V::ONE, V::ZERO, V::splat(3.0)]);
///
/// assert_eq!((r.re.extract::<0>(), r.im.extract::<0>()), (0.0, 4.0));
/// ```
///
/// `Mul`/`Div` by a real cost two real multiplies, versus the four multiplies and
/// two adds of a complex multiply by `Complex::real(r)`, which the compiler cannot
/// recover from the widened form.
/// [`MulAddExt<Self::Real, Self>`](thermite::vector::ops::MulAddExt) is promised
/// for the same reason, and is a true single-rounding FMA (one fused op per
/// component) where the complex-by-complex FMA cannot be.
/// Element-parameterized implementations behind [`ComplexMath`](crate::math::ComplexMath).
///
/// The complex counterpart of [`thermite::math::specialized`]: implementing this
/// for a complex vector type gives it [`ComplexMath`](crate::math::ComplexMath) and
/// [`ComplexMathWithPolicy`](crate::math::ComplexMathWithPolicy), as implementing `SpecializedTranscendentalMath`
/// gives it `TranscendentalMath`.
///
/// Bound on [`ComplexMath`](crate::math::ComplexMath); this trait is for implementors.