tensor4all_tcicore/matrixluci/
scalar.rs1use num_complex::{Complex32, Complex64};
4use num_traits::{Float, One, Zero};
5
6pub trait Scalar:
8 Clone
9 + Copy
10 + Zero
11 + One
12 + std::ops::Add<Output = Self>
13 + std::ops::Sub<Output = Self>
14 + std::ops::Mul<Output = Self>
15 + std::ops::Div<Output = Self>
16 + std::ops::Neg<Output = Self>
17 + Default
18 + Send
19 + Sync
20 + 'static
21{
22 fn conj(self) -> Self;
24
25 fn abs_sq(self) -> f64;
27
28 fn abs(self) -> Self;
30
31 fn abs_val(self) -> f64 {
33 self.abs_sq().sqrt()
34 }
35
36 fn from_f64(val: f64) -> Self;
38
39 fn is_nan(self) -> bool;
41
42 fn epsilon() -> f64 {
44 f64::EPSILON
45 }
46}
47
48impl Scalar for f64 {
49 fn conj(self) -> Self {
50 self
51 }
52
53 fn abs_sq(self) -> f64 {
54 self * self
55 }
56
57 fn abs(self) -> Self {
58 Float::abs(self)
59 }
60
61 fn abs_val(self) -> f64 {
62 Float::abs(self)
63 }
64
65 fn from_f64(val: f64) -> Self {
66 val
67 }
68
69 fn is_nan(self) -> bool {
70 Float::is_nan(self)
71 }
72}
73
74impl Scalar for f32 {
75 fn conj(self) -> Self {
76 self
77 }
78
79 fn abs_sq(self) -> f64 {
80 (self * self) as f64
81 }
82
83 fn abs(self) -> Self {
84 Float::abs(self)
85 }
86
87 fn abs_val(self) -> f64 {
88 Float::abs(self) as f64
89 }
90
91 fn from_f64(val: f64) -> Self {
92 val as f32
93 }
94
95 fn is_nan(self) -> bool {
96 Float::is_nan(self)
97 }
98}
99
100impl Scalar for Complex64 {
101 fn conj(self) -> Self {
102 Complex64::conj(&self)
103 }
104
105 fn abs_sq(self) -> f64 {
106 self.norm_sqr()
107 }
108
109 fn abs(self) -> Self {
110 Complex64::new(self.norm(), 0.0)
111 }
112
113 fn abs_val(self) -> f64 {
114 self.norm()
115 }
116
117 fn from_f64(val: f64) -> Self {
118 Complex64::new(val, 0.0)
119 }
120
121 fn is_nan(self) -> bool {
122 self.re.is_nan() || self.im.is_nan()
123 }
124}
125
126impl Scalar for Complex32 {
127 fn conj(self) -> Self {
128 Complex32::conj(&self)
129 }
130
131 fn abs_sq(self) -> f64 {
132 self.norm_sqr() as f64
133 }
134
135 fn abs(self) -> Self {
136 Complex32::new(self.norm(), 0.0)
137 }
138
139 fn abs_val(self) -> f64 {
140 self.norm() as f64
141 }
142
143 fn from_f64(val: f64) -> Self {
144 Complex32::new(val as f32, 0.0)
145 }
146
147 fn is_nan(self) -> bool {
148 self.re.is_nan() || self.im.is_nan()
149 }
150}
151
152#[cfg(test)]
153mod tests;