rsdiff_core/traits/
scalar.rs

1/*
2    Appellation: scalar <mod>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use 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);