peroxide_num/
lib.rs

1//! Missing operations & comprehensive number structures
2//!
3//! ## `Numeric` trait
4//!
5//! * `Numeric` requires `PowOps, TrigOps, ExpLogOps` & `std::Ops<Self>` & `std::Ops<f64>`
6
7use std::ops::{Add, Div, Mul, Neg, Sub};
8
9pub trait PowOps: Sized {
10    type Float;
11    fn powi(&self, n: i32) -> Self;
12    fn powf(&self, f: Self::Float) -> Self;
13    fn pow(&self, f: Self) -> Self;
14    fn sqrt(&self) -> Self;
15}
16
17pub trait TrigOps: Sized {
18    fn sin_cos(&self) -> (Self, Self);
19    fn sin(&self) -> Self {
20        let (s, _) = self.sin_cos();
21        s
22    }
23    fn cos(&self) -> Self {
24        let (_, c) = self.sin_cos();
25        c
26    }
27    fn tan(&self) -> Self;
28    fn sinh(&self) -> Self;
29    fn cosh(&self) -> Self;
30    fn tanh(&self) -> Self;
31    fn asin(&self) -> Self;
32    fn acos(&self) -> Self;
33    fn atan(&self) -> Self;
34    fn asin_acos(&self) -> (Self, Self) {
35        (self.asin(), self.acos())
36    }
37    fn asinh(&self) -> Self;
38    fn acosh(&self) -> Self;
39    fn atanh(&self) -> Self;
40    fn asinh_acosh(&self) -> (Self, Self) {
41        (self.asinh(), self.acosh())
42    }
43}
44
45pub trait ExpLogOps: Sized {
46    type Float;
47    fn exp(&self) -> Self;
48    fn ln(&self) -> Self;
49    fn log(&self, base: Self::Float) -> Self;
50    fn log2(&self) -> Self;
51    fn log10(&self) -> Self;
52}
53
54pub trait Float:
55    PowOps<Float = Self>
56    + TrigOps
57    + ExpLogOps<Float = Self>
58    + Neg<Output = Self>
59    + Add<Output = Self>
60    + Mul<Output = Self>
61    + Div<Output = Self>
62    + Sub<Output = Self>
63    + PartialOrd
64    + Copy
65    + Clone
66{
67}
68
69pub trait Numeric<T: Float>:
70    PowOps<Float = T>
71    + TrigOps
72    + ExpLogOps<Float = T>
73    + Neg<Output = Self>
74    + Add<Output = Self>
75    + Mul<Output = Self>
76    + Div<Output = Self>
77    + Sub<Output = Self>
78    + Add<T, Output = Self>
79    + Mul<T, Output = Self>
80    + Div<T, Output = Self>
81    + Sub<T, Output = Self>
82    + Clone
83{
84}
85
86// =============================================================================
87// Numeric Traits for f32, f64
88// =============================================================================
89
90macro_rules! impl_float {
91    ($($t:ty),*) => {
92        $(
93            impl PowOps for $t {
94                type Float = $t;
95                fn powi(&self, n: i32) -> Self {
96                    (*self).powi(n)
97                }
98
99                fn powf(&self, f: Self::Float) -> Self {
100                    (*self).powf(f)
101                }
102
103                fn pow(&self, f: Self) -> Self {
104                    (*self).powf(f)
105                }
106
107                fn sqrt(&self) -> Self {
108                    (*self).sqrt()
109                }
110            }
111
112            impl TrigOps for $t {
113                fn sin_cos(&self) -> (Self, Self) {
114                    (*self).sin_cos()
115                }
116
117                fn sin(&self) -> Self {
118                    (*self).sin()
119                }
120
121                fn cos(&self) -> Self {
122                    (*self).cos()
123                }
124
125                fn tan(&self) -> Self {
126                    (*self).tan()
127                }
128
129                fn sinh(&self) -> Self {
130                    (*self).sinh()
131                }
132
133                fn cosh(&self) -> Self {
134                    (*self).cosh()
135                }
136
137                fn tanh(&self) -> Self {
138                    (*self).tanh()
139                }
140
141                fn asin(&self) -> Self {
142                    (*self).asin()
143                }
144
145                fn acos(&self) -> Self {
146                    (*self).acos()
147                }
148
149                fn atan(&self) -> Self {
150                    (*self).atan()
151                }
152
153                fn asinh(&self) -> Self {
154                    (*self).asinh()
155                }
156
157                fn acosh(&self) -> Self {
158                    (*self).acosh()
159                }
160
161                fn atanh(&self) -> Self {
162                    (*self).atanh()
163                }
164            }
165
166            impl ExpLogOps for $t {
167                type Float = $t;
168                fn exp(&self) -> Self {
169                    (*self).exp()
170                }
171                fn ln(&self) -> Self {
172                    (*self).ln()
173                }
174                fn log(&self, base: Self::Float) -> Self {
175                    (*self).log(base)
176                }
177                fn log2(&self) -> Self {
178                    (*self).log2()
179                }
180                fn log10(&self) -> Self {
181                    (*self).log10()
182                }
183            }
184
185            impl Float for $t {}
186        )*
187    };
188}
189
190impl_float!(f32, f64);
191
192impl Numeric<f32> for f32 {}
193impl Numeric<f64> for f64 {}
194
195// ┌──────────────────────────────────────────────────────────┐
196//  Fundamental Traits
197// └──────────────────────────────────────────────────────────┘
198pub trait Group: Sized + Add<Self, Output = Self> {
199    fn zero() -> Self;
200}
201
202pub trait Ring: Group + Mul<Self, Output = Self> {
203    fn one() -> Self;
204}
205
206impl Group for f32 {
207    fn zero() -> Self {
208        0.0
209    }
210}
211
212impl Ring for f32 {
213    fn one() -> Self {
214        1.0
215    }
216}
217
218impl Group for f64 {
219    fn zero() -> Self {
220        0.0
221    }
222}
223
224impl Ring for f64 {
225    fn one() -> Self {
226        1.0
227    }
228}