1use crate::complex::c64;
2
3pub trait WeakMul {
5 fn weak_mul(self, other: f64) -> Self;
6}
7
8impl WeakMul for c64 {
9 fn weak_mul(self, other: f64) -> Self {
10 c64::new(self.re() * other, self.im() * other)
11 }
12}
13
14impl WeakMul for f64 {
15 fn weak_mul(self, other: f64) -> Self {
16 self * other
17 }
18}
19
20impl WeakMul for i64 {
21 fn weak_mul(self, other: f64) -> Self {
22 (self as f64 * other) as i64
23 }
24}
25
26impl WeakMul for f32 {
28 fn weak_mul(self, other: f64) -> Self {
29 (self as f64 * other) as f32
30 }
31}
32
33
34pub trait TensorElement:
35 Copy + Clone +
36 std::ops::Add<Output = Self> +
37 std::ops::Sub<Output = Self> +
38 std::ops::Mul<Output = Self> +
39 std::ops::Div<Output = Self> +
40 std::ops::Neg<Output = Self> +
41 std::ops::AddAssign +
42 std::ops::SubAssign +
43 std::ops::MulAssign +
44 std::ops::DivAssign +
45 std::cmp::PartialEq +
46 std::cmp::PartialOrd +
47
48 WeakMul +
50
51 Into<c64> +
52 From<c64> +
53 std::fmt::Debug +
54 std::fmt::Display
55 {
56 fn zero() -> Self;
58 fn one() -> Self;
59
60 fn random(min: Self, max: Self) -> Self;
64
65fn mag(self) -> f64;
68
69 fn conjugate(self) -> Self;
70
71 const EPSILON: Self;
72
73}
74
75use rand::Rng;
76
77impl TensorElement for c64 {
78 fn zero() -> Self {
79 c64::ZERO
80 }
81 fn one() -> Self {
82 c64::ONE
83 }
84
85 fn random(min: Self, max: Self) -> Self {
86 let mut rng = rand::rng();
87 let a = rng.random::<f64>() * (max.re() - min.re()) + min.re();
88 let b = rng.random::<f64>() * (max.im() - min.im()) + min.im();
89 c64::new(a, b)
90 }
91
92 fn mag(self) -> f64 {
93 self.mag()
94 }
95
96 fn conjugate(self) -> Self {
97 self.conjugate()
98 }
99
100 const EPSILON: Self = c64::EPSILON;
101}
102
103impl TensorElement for f64 {
104 fn zero() -> Self {
105 0.0
106 }
107 fn one() -> Self {
108 1.0
109 }
110
111 fn random(min: Self, max: Self) -> Self {
112 let mut rng = rand::rng();
113 rng.random_range(min..max)
114 }
115
116 fn mag(self) -> f64 {
117 self.abs()
118 }
119
120 fn conjugate(self) -> Self {
121 self
122 }
123
124 const EPSILON: Self = 1e-10;
125}
126
127impl TensorElement for f32 {
128 fn zero() -> Self {
129 0.0
130 }
131 fn one() -> Self {
132 1.0
133 }
134
135 fn random(min: Self, max: Self) -> Self {
136 let mut rng = rand::rng();
137 rng.random_range(min..max)
138 }
139
140 fn mag(self) -> f64 {
141 self.abs() as f64
142 }
143
144 fn conjugate(self) -> Self {
145 self
146 }
147
148 const EPSILON: Self = 1e-20;
149}
150
151impl TensorElement for i64 {
152 fn zero() -> Self {
153 0
154 }
155 fn one() -> Self {
156 1
157 }
158
159 fn random(min: Self, max: Self) -> Self {
160 let mut rng = rand::rng();
161 rng.random_range(min..max)
162 }
163
164 fn mag(self) -> f64 {
165 self.abs() as f64
166 }
167
168 fn conjugate(self) -> Self {
169 self
170 }
171
172 const EPSILON: Self = 1;
173}