1use num_complex::Complex;
41use num_traits::{Float, FromPrimitive, NumAssign, NumCast, NumOps, ToPrimitive, Zero};
42use rand::{distributions::Standard, prelude::*};
43use serde::{Deserialize, Serialize};
44use std::fmt::{Debug, Display, LowerExp, UpperExp};
45use std::iter::{Product, Sum};
46use std::ops::Neg;
47
48pub use num_complex::Complex32 as c32;
49pub use num_complex::Complex64 as c64;
50
51pub trait Scalar:
52 NumAssign
53 + FromPrimitive
54 + NumCast
55 + Neg<Output = Self>
56 + Copy
57 + Clone
58 + Display
59 + Debug
60 + LowerExp
61 + UpperExp
62 + Sum
63 + Product
64 + Serialize
65 + for<'de> Deserialize<'de>
66 + 'static
67{
68 type Real: Scalar<Real = Self::Real, Complex = Self::Complex>
69 + NumOps<Self::Real, Self::Real>
70 + Float;
71 type Complex: Scalar<Real = Self::Real, Complex = Self::Complex>
72 + NumOps<Self::Real, Self::Complex>
73 + NumOps<Self::Complex, Self::Complex>;
74
75 fn real<T: ToPrimitive>(re: T) -> Self::Real;
77 fn complex<T: ToPrimitive>(re: T, im: T) -> Self::Complex;
79
80 fn from_real(re: Self::Real) -> Self;
81
82 fn add_real(self, re: Self::Real) -> Self;
83 fn sub_real(self, re: Self::Real) -> Self;
84 fn mul_real(self, re: Self::Real) -> Self;
85 fn div_real(self, re: Self::Real) -> Self;
86
87 fn add_complex(self, im: Self::Complex) -> Self::Complex;
88 fn sub_complex(self, im: Self::Complex) -> Self::Complex;
89 fn mul_complex(self, im: Self::Complex) -> Self::Complex;
90 fn div_complex(self, im: Self::Complex) -> Self::Complex;
91
92 fn pow(self, n: Self) -> Self;
93 fn powi(self, n: i32) -> Self;
94 fn powf(self, n: Self::Real) -> Self;
95 fn powc(self, n: Self::Complex) -> Self::Complex;
96
97 fn re(&self) -> Self::Real;
99 fn im(&self) -> Self::Real;
101 fn as_c(&self) -> Self::Complex;
103 fn conj(&self) -> Self;
105
106 fn abs(self) -> Self::Real;
108 fn square(self) -> Self::Real;
110
111 fn sqrt(self) -> Self;
112 fn exp(self) -> Self;
113 fn ln(self) -> Self;
114 fn sin(self) -> Self;
115 fn cos(self) -> Self;
116 fn tan(self) -> Self;
117 fn asin(self) -> Self;
118 fn acos(self) -> Self;
119 fn atan(self) -> Self;
120 fn sinh(self) -> Self;
121 fn cosh(self) -> Self;
122 fn tanh(self) -> Self;
123 fn asinh(self) -> Self;
124 fn acosh(self) -> Self;
125 fn atanh(self) -> Self;
126
127 fn rand(rng: &mut impl Rng) -> Self;
130}
131
132macro_rules! impl_float {
133 ($name:ident) => {
134 #[inline]
135 fn $name(self) -> Self {
136 Float::$name(self)
137 }
138 };
139}
140
141macro_rules! impl_complex {
142 ($name:ident) => {
143 #[inline]
144 fn $name(self) -> Self {
145 Complex::$name(self)
146 }
147 };
148}
149
150macro_rules! impl_with_real {
151 ($name:ident, $op:tt) => {
152 #[inline]
153 fn $name(self, re: Self::Real) -> Self {
154 self $op re
155 }
156 }
157}
158
159macro_rules! impl_with_complex {
160 ($name:ident, $op:tt) => {
161 #[inline]
162 fn $name(self, im: Self::Complex) -> Self::Complex {
163 self $op im
164 }
165 }
166}
167
168macro_rules! impl_scalar {
169 ($real:ty, $complex:ty) => {
170 impl Scalar for $real {
171 type Real = $real;
172 type Complex = $complex;
173
174 #[inline]
175 fn re(&self) -> Self::Real {
176 *self
177 }
178 #[inline]
179 fn im(&self) -> Self::Real {
180 0.0
181 }
182
183 #[inline]
184 fn from_real(re: Self::Real) -> Self {
185 re
186 }
187
188 fn pow(self, n: Self) -> Self {
189 self.powf(n)
190 }
191 fn powi(self, n: i32) -> Self {
192 Float::powi(self, n)
193 }
194 fn powf(self, n: Self::Real) -> Self {
195 Float::powf(self, n)
196 }
197 fn powc(self, n: Self::Complex) -> Self::Complex {
198 self.as_c().powc(n)
199 }
200
201 #[inline]
202 fn real<T: ToPrimitive>(re: T) -> Self::Real {
203 NumCast::from(re).unwrap()
204 }
205 #[inline]
206 fn complex<T: ToPrimitive>(re: T, im: T) -> Self::Complex {
207 Complex {
208 re: NumCast::from(re).unwrap(),
209 im: NumCast::from(im).unwrap(),
210 }
211 }
212 #[inline]
213 fn as_c(&self) -> Self::Complex {
214 Complex::new(*self, 0.0)
215 }
216 #[inline]
217 fn conj(&self) -> Self {
218 *self
219 }
220 #[inline]
221 fn square(self) -> Self::Real {
222 self * self
223 }
224
225 fn rand(rng: &mut impl Rng) -> Self {
226 rng.sample(Standard)
227 }
228
229 impl_with_real!(add_real, +);
230 impl_with_real!(sub_real, -);
231 impl_with_real!(mul_real, *);
232 impl_with_real!(div_real, /);
233 impl_with_complex!(add_complex, +);
234 impl_with_complex!(sub_complex, -);
235 impl_with_complex!(mul_complex, *);
236 impl_with_complex!(div_complex, /);
237
238 impl_float!(sqrt);
239 impl_float!(abs);
240 impl_float!(exp);
241 impl_float!(ln);
242 impl_float!(sin);
243 impl_float!(cos);
244 impl_float!(tan);
245 impl_float!(sinh);
246 impl_float!(cosh);
247 impl_float!(tanh);
248 impl_float!(asin);
249 impl_float!(acos);
250 impl_float!(atan);
251 impl_float!(asinh);
252 impl_float!(acosh);
253 impl_float!(atanh);
254 }
255
256 impl Scalar for $complex {
257 type Real = $real;
258 type Complex = $complex;
259
260 #[inline]
261 fn re(&self) -> Self::Real {
262 self.re
263 }
264 #[inline]
265 fn im(&self) -> Self::Real {
266 self.im
267 }
268
269 #[inline]
270 fn from_real(re: Self::Real) -> Self {
271 Self::new(re, Zero::zero())
272 }
273
274 fn pow(self, n: Self) -> Self {
275 self.powc(n)
276 }
277 fn powi(self, n: i32) -> Self {
278 self.powf(n as Self::Real)
279 }
280 fn powf(self, n: Self::Real) -> Self {
281 self.powf(n)
282 }
283 fn powc(self, n: Self::Complex) -> Self::Complex {
284 self.powc(n)
285 }
286
287 #[inline]
288 fn real<T: ToPrimitive>(re: T) -> Self::Real {
289 NumCast::from(re).unwrap()
290 }
291 #[inline]
292 fn complex<T: ToPrimitive>(re: T, im: T) -> Self::Complex {
293 Complex {
294 re: NumCast::from(re).unwrap(),
295 im: NumCast::from(im).unwrap(),
296 }
297 }
298 #[inline]
299 fn as_c(&self) -> Self::Complex {
300 *self
301 }
302 #[inline]
303 fn conj(&self) -> Self {
304 Complex::conj(self)
305 }
306 #[inline]
307 fn square(self) -> Self::Real {
308 Complex::norm_sqr(&self)
309 }
310 #[inline]
311 fn abs(self) -> Self::Real {
312 Complex::norm(self)
313 }
314
315 fn rand(rng: &mut impl Rng) -> Self {
316 rng.sample(Standard)
317 }
318
319 impl_with_real!(add_real, +);
320 impl_with_real!(sub_real, -);
321 impl_with_real!(mul_real, *);
322 impl_with_real!(div_real, /);
323 impl_with_complex!(add_complex, +);
324 impl_with_complex!(sub_complex, -);
325 impl_with_complex!(mul_complex, *);
326 impl_with_complex!(div_complex, /);
327
328 impl_complex!(sqrt);
329 impl_complex!(exp);
330 impl_complex!(ln);
331 impl_complex!(sin);
332 impl_complex!(cos);
333 impl_complex!(tan);
334 impl_complex!(sinh);
335 impl_complex!(cosh);
336 impl_complex!(tanh);
337 impl_complex!(asin);
338 impl_complex!(acos);
339 impl_complex!(atan);
340 impl_complex!(asinh);
341 impl_complex!(acosh);
342 impl_complex!(atanh);
343 }
344 }
345}
346
347impl_scalar!(f32, c32);
348impl_scalar!(f64, c64);