concision_core/traits/
num.rs1use nd::{Array, Dimension};
6use num::complex::Complex;
7use num::{Float, Num, Signed, Zero};
8
9pub trait AsComplex {
10 type Real;
11
12 fn as_complex(&self, real: bool) -> Complex<Self::Real>;
13
14 fn as_re(&self) -> Complex<Self::Real> {
15 self.as_complex(true)
16 }
17
18 fn as_im(&self) -> Complex<Self::Real> {
19 self.as_complex(false)
20 }
21}
22
23pub trait IntoComplex: AsComplex {
24 fn into_complex(self, real: bool) -> Complex<Self::Real>
25 where
26 Self: Sized,
27 {
28 self.as_complex(real)
29 }
30
31 fn into_re(self) -> Complex<Self::Real>
32 where
33 Self: Sized,
34 {
35 self.as_complex(true)
36 }
37}
38
39pub trait Conjugate {
40 type Output;
41
42 fn conj(&self) -> Self::Output;
43}
44
45pub trait FloorDiv<Rhs = Self> {
46 type Output;
47
48 fn floor_div(self, rhs: Rhs) -> Self::Output;
49}
50
51pub trait RoundTo {
52 fn round_to(&self, places: usize) -> Self;
53}
54
55impl<T> AsComplex for T
59where
60 T: Copy + Num,
61{
62 type Real = T;
63
64 fn as_complex(&self, real: bool) -> Complex<Self> {
65 match real {
66 true => Complex::new(*self, Self::zero()),
67 false => Complex::new(Self::zero(), *self),
68 }
69 }
70}
71
72impl<T> IntoComplex for T where T: AsComplex {}
73
74macro_rules! impl_conj {
75 ($($t:ident<$res:ident>),*) => {
76 $(
77 impl_conj!(@impl $t<$res>);
78 )*
79 };
80 (@impl $t:ident<$res:ident>) => {
81 impl Conjugate for $t {
82 type Output = $res<$t>;
83
84 fn conj(&self) -> Self::Output {
85 Complex { re: *self, im: -$t::zero() }
86 }
87 }
88 };
89}
90
91impl_conj!(f32<Complex>, f64<Complex>);
92
93impl<T> Conjugate for Complex<T>
94where
95 T: Clone + Signed,
96{
97 type Output = Complex<T>;
98
99 fn conj(&self) -> Self {
100 Complex::<T>::conj(self)
101 }
102}
103
104impl<T, D> Conjugate for Array<T, D>
105where
106 D: Dimension,
107 T: Clone + num::complex::ComplexFloat,
108{
109 type Output = Array<T, D>;
110 fn conj(&self) -> Self::Output {
111 self.mapv(|x| x.conj())
112 }
113}
114
115impl<T> FloorDiv for T
116where
117 T: Copy + Num,
118{
119 type Output = T;
120
121 fn floor_div(self, rhs: Self) -> Self::Output {
122 crate::floor_div(self, rhs)
123 }
124}
125
126impl<T> RoundTo for T
143where
144 T: Float,
145{
146 fn round_to(&self, places: usize) -> Self {
147 crate::round_to(*self, places)
148 }
149}