ppvm_traits/traits/
coefficient.rs1use num::traits::Float;
5
6pub trait Coefficient:
15 PartialEq
16 + Clone
17 + num::Zero
18 + From<f64>
19 + std::ops::Neg<Output = Self>
20 + std::ops::Add<f64, Output = Self>
21 + std::ops::Add<Self, Output = Self>
22 + std::ops::Sub<f64, Output = Self>
23 + std::ops::Sub<Self, Output = Self>
24 + std::ops::Mul<f64, Output = Self>
25 + std::ops::Mul<Self, Output = Self>
26 + std::ops::AddAssign<f64>
27 + std::ops::AddAssign<Self>
28 + std::ops::MulAssign<f64>
29 + std::ops::MulAssign<Self>
30 + std::iter::Sum
31 + Sync
32 + Send
33{
34 fn mul_sign(&self, sign: i8) -> Self;
36 fn half(&self) -> Self;
38 fn sin_cos(&self) -> (Self, Self);
40
41 fn cutoff(&self, threshold: f64) -> bool;
44}
45
46impl Coefficient for f64 {
47 fn mul_sign(&self, sign: i8) -> Self {
48 (sign as f64) * (*self)
49 }
50
51 fn half(&self) -> Self {
52 *self / 2.0
53 }
54
55 fn sin_cos(&self) -> (Self, Self) {
56 Float::sin_cos(*self)
57 }
58
59 #[inline]
60 fn cutoff(&self, threshold: f64) -> bool {
61 self.abs() < threshold
62 }
63}
64
65pub trait ComplexCoefficient: Coefficient {
68 fn mul_phase(&self, phase: u8) -> Self;
77}
78
79impl Coefficient for num::complex::Complex<f64> {
80 #[inline]
81 fn cutoff(&self, threshold: f64) -> bool {
82 self.norm() < threshold
83 }
84
85 fn half(&self) -> Self {
86 *self / 2.0
87 }
88
89 fn mul_sign(&self, sign: i8) -> Self {
90 (sign as f64) * (*self)
91 }
92
93 fn sin_cos(&self) -> (Self, Self) {
94 let (s, c) = Float::sin_cos(self.re);
95 (
96 num::complex::Complex::new(s, 0.0),
97 num::complex::Complex::new(c, 0.0),
98 )
99 }
100}
101
102impl ComplexCoefficient for num::complex::Complex<f64> {
103 fn mul_phase(&self, phase: u8) -> Self {
104 match phase % 4 {
105 0 => *self,
106 1 => num::complex::Complex::new(-self.im, self.re),
107 2 => -*self,
108 3 => num::complex::Complex::new(self.im, -self.re),
109 _ => unreachable!(),
110 }
111 }
112}