rsdiff_core/traits/
scalar.rs1use core::iter::{Product, Sum};
6use core::ops::Neg;
7use num::complex::Complex;
8use num::traits::{Float, FromPrimitive, Inv, NumAssign, NumCast, NumOps, Pow, ToPrimitive};
9
10pub trait Scalar:
11 Copy
12 + Default
13 + FromPrimitive
14 + Inv<Output = Self>
15 + Neg<Output = Self>
16 + NumAssign
17 + NumCast
18 + NumOps
19 + Pow<Self, Output = Self>
20 + Product
21 + Sum
22 + ToPrimitive
23 + 'static
24{
25 type Complex: Scalar<Complex = Self::Complex, Real = Self::Real>
26 + NumOps<Self::Real, Self::Complex>;
27 type Real: Scalar<Complex = Self::Complex, Real = Self::Real>
28 + NumOps<Self::Complex, Self::Complex>;
29
30 fn from_real(re: Self::Real) -> Self;
31
32 fn abs(self) -> Self::Real;
33
34 fn acos(self) -> Self;
35
36 fn acosh(self) -> Self;
37
38 fn asin(self) -> Self;
39
40 fn asinh(self) -> Self;
41
42 fn atan(self) -> Self;
43
44 fn atanh(self) -> Self;
45
46 fn add_complex(&self, other: Self::Complex) -> Self::Complex {
47 self.as_complex() + other
48 }
49
50 fn div_complex(&self, other: Self::Complex) -> Self::Complex {
51 self.as_complex() / other
52 }
53
54 fn mul_complex(&self, other: Self::Complex) -> Self::Complex {
55 self.as_complex() * other
56 }
57
58 fn sub_complex(&self, other: Self::Complex) -> Self::Complex {
59 self.as_complex() - other
60 }
61
62 fn as_complex(&self) -> Self::Complex;
63
64 fn cubed(&self) -> Self {
65 self.powi(3)
66 }
67
68 fn conj(&self) -> Self::Complex;
69
70 fn im(&self) -> Self::Real {
71 Default::default()
72 }
73
74 fn re(&self) -> Self::Real;
75
76 fn cos(self) -> Self;
77
78 fn cosh(self) -> Self;
79
80 fn exp(self) -> Self;
81
82 fn inv(self) -> Self {
83 Inv::inv(self)
84 }
85
86 fn ln(self) -> Self;
87
88 fn pow(self, exp: Self) -> Self;
89
90 fn powc(self, exp: Self::Complex) -> Self::Complex;
91
92 fn powf(self, exp: Self::Real) -> Self;
93
94 fn powi(self, exp: i32) -> Self {
95 let exp = Self::Real::from_i32(exp).unwrap();
96 self.powf(exp)
97 }
98
99 fn recip(self) -> Self {
100 Self::one() / self
101 }
102
103 fn sin(self) -> Self;
104
105 fn sinh(self) -> Self;
106
107 fn sqrt(self) -> Self;
108
109 fn sqr(self) -> Self {
110 self.powi(2)
111 }
112
113 fn tan(self) -> Self;
114
115 fn tanh(self) -> Self;
116}
117
118impl<T> Scalar for Complex<T>
119where
120 T: Scalar<Complex = Self, Real = T>,
121 T::Real: NumOps<Complex<T>, Complex<T>> + Float,
122{
123 type Complex = Self;
124 type Real = T;
125
126 fn from_real(re: Self::Real) -> Self {
127 Complex::new(re, Default::default())
128 }
129
130 fn abs(self) -> Self::Real {
131 Complex::norm(self)
132 }
133
134 fn acos(self) -> Self {
135 Complex::acos(self)
136 }
137
138 fn acosh(self) -> Self {
139 Complex::acosh(self)
140 }
141
142 fn asin(self) -> Self {
143 Complex::asin(self)
144 }
145
146 fn asinh(self) -> Self {
147 Complex::asinh(self)
148 }
149
150 fn atan(self) -> Self {
151 Complex::atan(self)
152 }
153
154 fn atanh(self) -> Self {
155 Complex::atanh(self)
156 }
157
158 fn as_complex(&self) -> Self::Complex {
159 *self
160 }
161
162 fn conj(&self) -> Self::Complex {
163 Complex::conj(self)
164 }
165
166 fn re(&self) -> Self::Real {
167 self.re
168 }
169
170 fn im(&self) -> Self::Real {
171 self.im
172 }
173
174 fn cos(self) -> Self {
175 Complex::cos(self)
176 }
177
178 fn cosh(self) -> Self {
179 Complex::cosh(self)
180 }
181
182 fn exp(self) -> Self {
183 Complex::exp(self)
184 }
185
186 fn ln(self) -> Self {
187 Complex::ln(self)
188 }
189
190 fn pow(self, exp: Self) -> Self {
191 Complex::powc(self, exp)
192 }
193
194 fn powc(self, exp: Self::Complex) -> Self::Complex {
195 Complex::powc(self, exp)
196 }
197
198 fn powf(self, exp: T) -> Self {
199 Complex::powf(self, exp)
200 }
201
202 fn powi(self, exp: i32) -> Self {
203 Complex::powi(&self, exp)
204 }
205
206 fn sin(self) -> Self {
207 Complex::sin(self)
208 }
209
210 fn sinh(self) -> Self {
211 Complex::sinh(self)
212 }
213
214 fn sqrt(self) -> Self {
215 Complex::sqrt(self)
216 }
217
218 fn tan(self) -> Self {
219 Complex::tan(self)
220 }
221
222 fn tanh(self) -> Self {
223 Complex::tanh(self)
224 }
225}
226
227macro_rules! impl_scalar {
228 ($($re:ty),*) => {
229 $(
230 impl_scalar!(@loop $re);
231 )*
232 };
233 ($re:ty) => {
234 impl_scalar!(@loop $re);
235 };
236 (@loop $re:ty) => {
237 impl Scalar for $re {
238 type Complex = Complex<$re>;
239 type Real = $re;
240
241 fn from_real(re: Self::Real) -> Self {
242 re
243 }
244
245 fn abs(self) -> Self::Real {
246 <$re>::abs(self)
247 }
248
249 fn acos(self) -> Self {
250 <$re>::acos(self)
251 }
252
253 fn acosh(self) -> Self {
254 <$re>::acosh(self)
255 }
256
257 fn asin(self) -> Self {
258 <$re>::asin(self)
259 }
260
261 fn asinh(self) -> Self {
262 <$re>::asinh(self)
263 }
264
265 fn atan(self) -> Self {
266 <$re>::atan(self)
267 }
268
269 fn atanh(self) -> Self {
270 <$re>::atanh(self)
271 }
272
273 fn as_complex(&self) -> Self::Complex {
274 Complex::new(*self, <$re>::default())
275 }
276
277 fn conj(&self) -> Self::Complex {
278 Complex::new(*self, -<$re>::default())
279 }
280
281 fn re(&self) -> Self::Real {
282 *self
283 }
284
285 fn cos(self) -> Self {
286 <$re>::cos(self)
287 }
288
289 fn cosh(self) -> Self {
290 <$re>::cosh(self)
291 }
292
293 fn exp(self) -> Self {
294 <$re>::exp(self)
295 }
296
297 fn ln(self) -> Self {
298 <$re>::ln(self)
299 }
300
301 fn pow(self, exp: Self) -> Self {
302 <$re>::powf(self, exp)
303 }
304
305 fn powc(self, exp: Self::Complex) -> Self::Complex {
306 Complex::new(self, <$re>::default()).powc(exp)
307 }
308
309 fn powf(self, exp: Self::Real) -> Self {
310 <$re>::powf(self, exp)
311 }
312
313 fn powi(self, exp: i32) -> Self {
314 <$re>::powi(self, exp)
315 }
316
317 fn sin(self) -> Self {
318 <$re>::sin(self)
319 }
320
321 fn sinh(self) -> Self {
322 <$re>::sinh(self)
323 }
324
325 fn sqrt(self) -> Self {
326 <$re>::sqrt(self)
327 }
328
329 fn tan(self) -> Self {
330 <$re>::tan(self)
331 }
332
333 fn tanh(self) -> Self {
334 <$re>::tanh(self)
335 }
336 }
337 };
338}
339
340impl_scalar!(f32, f64);