1use std::cmp::Ordering;
2use std::fmt::{self, Debug, Display, Formatter};
3use std::hash::{Hash, Hasher};
4use std::iter::Sum;
5use std::ops::{Add, Div, Mul, Neg, Rem, Sub};
6
7use crate::Numeric;
8
9#[derive(Default, Copy, Clone)]
15pub struct Scalar(f64);
16
17impl Scalar {
18 pub const ZERO: Self = Self(0.0);
20
21 pub const ONE: Self = Self(1.0);
23
24 pub const INFINITY: Self = Self(f64::INFINITY);
26
27 pub const fn new(x: f64) -> Self {
31 Self(if x.is_nan() { 0.0 } else { x })
32 }
33
34 pub const fn get(self) -> f64 {
36 self.0
37 }
38
39 pub fn sqrt(self) -> Self {
41 Self::new(self.get().sqrt())
42 }
43
44 pub fn powi(self, mut b: i32) -> Self {
46 let mut a = self.get();
50 let recip = b < 0;
51 let mut r = 1.0;
52 loop {
53 if (b & 1) != 0 {
54 r *= a;
55 }
56 b /= 2;
57 if b == 0 {
58 break;
59 }
60 a *= a;
61 }
62
63 if recip {
64 r = 1.0 / r;
65 }
66
67 Self::new(r)
68 }
69}
70
71impl Numeric for Scalar {
72 fn zero() -> Self {
73 Self(0.0)
74 }
75
76 fn is_finite(self) -> bool {
77 self.0.is_finite()
78 }
79}
80
81impl Debug for Scalar {
82 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
83 Debug::fmt(&self.0, f)
84 }
85}
86
87impl Display for Scalar {
88 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
89 Display::fmt(&self.0, f)
90 }
91}
92
93impl Eq for Scalar {}
94
95impl PartialEq for Scalar {
96 fn eq(&self, other: &Self) -> bool {
97 assert!(!self.0.is_nan() && !other.0.is_nan(), "float is NaN");
98 self.0 == other.0
99 }
100}
101
102impl PartialEq<f64> for Scalar {
103 fn eq(&self, other: &f64) -> bool {
104 self == &Self(*other)
105 }
106}
107
108impl Ord for Scalar {
109 fn cmp(&self, other: &Self) -> Ordering {
110 self.0.partial_cmp(&other.0).expect("float is NaN")
111 }
112}
113
114impl PartialOrd for Scalar {
115 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
116 Some(self.cmp(other))
117 }
118}
119
120impl Hash for Scalar {
121 fn hash<H: Hasher>(&self, state: &mut H) {
122 debug_assert!(!self.0.is_nan(), "float is NaN");
123 self.0.to_bits().hash(state);
124 }
125}
126
127impl From<f64> for Scalar {
128 fn from(float: f64) -> Self {
129 Self::new(float)
130 }
131}
132
133impl From<Scalar> for f64 {
134 fn from(scalar: Scalar) -> Self {
135 scalar.0
136 }
137}
138
139impl Neg for Scalar {
140 type Output = Self;
141
142 fn neg(self) -> Self::Output {
143 Self::new(-self.0)
144 }
145}
146
147impl Add<Self> for Scalar {
148 type Output = Self;
149
150 fn add(self, rhs: Self) -> Self::Output {
151 Self::new(self.0 + rhs.0)
152 }
153}
154
155impl Add<f64> for Scalar {
156 type Output = Self;
157
158 fn add(self, rhs: f64) -> Self::Output {
159 Self::new(self.0 + rhs)
160 }
161}
162
163impl Add<Scalar> for f64 {
164 type Output = Scalar;
165
166 fn add(self, rhs: Scalar) -> Self::Output {
167 Scalar::new(self + rhs.0)
168 }
169}
170
171impl Sub<Self> for Scalar {
172 type Output = Self;
173
174 fn sub(self, rhs: Self) -> Self::Output {
175 Self::new(self.0 - rhs.0)
176 }
177}
178
179impl Sub<f64> for Scalar {
180 type Output = Self;
181
182 fn sub(self, rhs: f64) -> Self::Output {
183 Self::new(self.0 - rhs)
184 }
185}
186
187impl Sub<Scalar> for f64 {
188 type Output = Scalar;
189
190 fn sub(self, rhs: Scalar) -> Self::Output {
191 Scalar::new(self - rhs.0)
192 }
193}
194
195impl Mul<Self> for Scalar {
196 type Output = Self;
197
198 fn mul(self, rhs: Self) -> Self::Output {
199 Self::new(self.0 * rhs.0)
200 }
201}
202
203impl Mul<f64> for Scalar {
204 type Output = Self;
205
206 fn mul(self, rhs: f64) -> Self::Output {
207 Self::new(self.0 * rhs)
208 }
209}
210
211impl Mul<Scalar> for f64 {
212 type Output = Scalar;
213
214 fn mul(self, rhs: Scalar) -> Self::Output {
215 Scalar::new(self * rhs.0)
216 }
217}
218
219impl Div<Self> for Scalar {
220 type Output = Self;
221
222 fn div(self, rhs: Self) -> Self::Output {
223 Self::new(self.0 / rhs.0)
224 }
225}
226
227impl Div<f64> for Scalar {
228 type Output = Self;
229
230 fn div(self, rhs: f64) -> Self::Output {
231 Self::new(self.0 / rhs)
232 }
233}
234
235impl Div<Scalar> for f64 {
236 type Output = Scalar;
237
238 fn div(self, rhs: Scalar) -> Self::Output {
239 Scalar::new(self / rhs.0)
240 }
241}
242
243impl Rem<Self> for Scalar {
244 type Output = Self;
245
246 fn rem(self, rhs: Self) -> Self::Output {
247 Self::new(self.0 % rhs.0)
248 }
249}
250
251impl Rem<f64> for Scalar {
252 type Output = Self;
253
254 fn rem(self, rhs: f64) -> Self::Output {
255 Self::new(self.0 % rhs)
256 }
257}
258
259impl Rem<Scalar> for f64 {
260 type Output = Scalar;
261
262 fn rem(self, rhs: Scalar) -> Self::Output {
263 Scalar::new(self % rhs.0)
264 }
265}
266
267impl Sum for Scalar {
268 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
269 Self::new(iter.map(|s| s.0).sum())
270 }
271}
272
273impl<'a> Sum<&'a Self> for Scalar {
274 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
275 Self::new(iter.map(|s| s.0).sum())
276 }
277}
278
279assign_impl!(Scalar += Scalar);
280assign_impl!(Scalar += f64);
281assign_impl!(Scalar -= Scalar);
282assign_impl!(Scalar -= f64);
283assign_impl!(Scalar *= Scalar);
284assign_impl!(Scalar *= f64);
285assign_impl!(Scalar /= Scalar);
286assign_impl!(Scalar /= f64);
287assign_impl!(Scalar %= Scalar);
288assign_impl!(Scalar %= f64);