1use 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
86macro_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
195pub 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}