1use std::ops::{
2 Neg, Add, Sub, Mul, Div, Rem,
3 AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
4use std::cmp::{PartialEq, PartialOrd};
5
6pub trait Identity: Copy {
7 const ZERO: Self;
8 const ONE: Self;
9 const SEED: Self = Self::ONE;
10}
11pub trait UsefulReals: RealArithmetic {
12 const TWO: Self;
13 const E: Self;
14 const TAU: Self;
15 const PI: Self;
16 const HALFPI: Self;
17 const QTRPI: Self;
18}
19pub trait Inverse {
20 fn inv(self) -> Self;
21}
22pub trait PowersOfTen: Identity {
23 fn order_of(power: isize) -> Self;
24}
25pub trait PowersOfE:
26UsefulReals + Inverse + Identity
27+ MulAssign + Mul<Output = Self>
28{
29 fn etothe(power: isize) -> Self {
30 let mut running: Self = Self::ONE;
31 for _ in 0..power { running *= Self::E; }
32 for _ in power..0 { running *= Self::E; }
33 if power < 0 { running.inv() } else { running }
34 }
35}
36pub trait MagSquare: Identity + Mul<Output = Self> {
37 fn mag2(self) -> Self { self * self }
38}
39pub trait Magnitude: std::fmt::Debug + RealArithmetic + MagSquare + UsefulReals {
40 fn rrt(self, error: Self) -> Self {
41 let (mut t1, mut t2): (Self, Self) = (Self::SEED, Self::SEED + Self::ONE);
42 let mut counter: usize = 0;
43 while (t2 - t1).mag2() > error {
44 if counter > 20 { break }; counter += 1;
45 t1 = t2;
46 t2 -= (t2*t2 - self) / (Self::TWO * t2);
47 }
48 t2
49 }
50 fn mag1(self, error: Self) -> Self { self.mag2().rrt(error) }
51}
52
53pub trait RealArithmetic:
54 Identity
55+ MagSquare
56+ Copy
57+ Neg<Output = Self>
58+ PartialEq
59+ PartialOrd
60+ Add<Output = Self>
61+ Sub<Output = Self>
62+ Mul<Output = Self>
63+ Div<Output = Self>
64+ Rem<Output = Self>
65+ AddAssign
66+ SubAssign
67+ MulAssign
68+ DivAssign
69+ RemAssign
70{}
71pub trait Reals:
72 RealArithmetic
73+ Inverse
74+ Magnitude
75+ PowersOfTen
76+ PowersOfE
77+ UsefulReals
78{
79 const UNDEF: Self;
80 const INFINITE: Self;
81}
82
83impl Identity for u8 {
84 const ZERO: Self = 0;
85 const ONE: Self = 1;
86}
87impl Identity for u16 {
88 const ZERO: Self = 0;
89 const ONE: Self = 1;
90}
91impl Identity for u32 {
92 const ZERO: Self = 0;
93 const ONE: Self = 1;
94}
95impl Identity for u64 {
96 const ZERO: Self = 0;
97 const ONE: Self = 1;
98}
99impl Identity for usize {
100 const ZERO: Self = 0;
101 const ONE: Self = 1;
102}
103impl Identity for i8 {
104 const ZERO: Self = 0;
105 const ONE: Self = 1;
106}
107impl Identity for i16 {
108 const ZERO: Self = 0;
109 const ONE: Self = 1;
110}
111impl Identity for i32 {
112 const ZERO: Self = 0;
113 const ONE: Self = 1;
114}
115impl Identity for i64 {
116 const ZERO: Self = 0;
117 const ONE: Self = 1;
118}
119impl Identity for isize {
120 const ZERO: Self = 0;
121 const ONE: Self = 1;
122}
123impl Identity for f32 {
124 const ZERO: Self = 0.0;
125 const ONE: Self = 1.0;
126}
127impl Identity for f64 {
128 const ZERO: Self = 0.0;
129 const ONE: Self = 1.0;
130}
131
132impl MagSquare for i8 {}
133impl MagSquare for i16 {}
134impl MagSquare for i32 {}
135impl MagSquare for i64 {}
136impl MagSquare for isize {}
137impl MagSquare for f32 {}
138impl MagSquare for f64 {}
139
140impl RealArithmetic for i8 {}
141impl RealArithmetic for i16 {}
142impl RealArithmetic for i32 {}
143impl RealArithmetic for i64 {}
144impl RealArithmetic for isize {}
145impl RealArithmetic for f32 {}
146impl RealArithmetic for f64 {}
147
148impl PowersOfTen for u8 {
149 fn order_of(power: isize) -> Self {
150 if power < 0 { return 0 };
151 let mut running: Self = 1;
152 for _ in 0..power as usize {
153 running *= 10;
154 }
155 running
156 }
157}
158impl PowersOfTen for u16 {
159 fn order_of(power: isize) -> Self {
160 if power < 0 { return 0 };
161 let mut running: Self = 1;
162 for _ in 0..power as usize {
163 running *= 10;
164 }
165 running
166 }
167}
168impl PowersOfTen for u32 {
169 fn order_of(power: isize) -> Self {
170 if power < 0 { return 0 };
171 let mut running: Self = 1;
172 for _ in 0..power as usize {
173 running *= 10;
174 }
175 running
176 }
177}
178impl PowersOfTen for u64 {
179 fn order_of(power: isize) -> Self {
180 if power < 0 { return 0 };
181 let mut running: Self = 1;
182 for _ in 0..power as usize {
183 running *= 10;
184 }
185 running
186 }
187}
188impl PowersOfTen for usize {
189 fn order_of(power: isize) -> Self {
190 if power < 0 { return 0 };
191 let mut running: Self = 1;
192 for _ in 0..power as usize {
193 running *= 10;
194 }
195 running
196 }
197}
198impl PowersOfTen for i8 {
199 fn order_of(power: isize) -> Self {
200 if power < 0 { return 0 };
201 let mut running: Self = 1;
202 for _ in 0..power as usize {
203 running *= 10;
204 }
205 running
206 }
207}
208impl PowersOfTen for i16 {
209 fn order_of(power: isize) -> Self {
210 if power < 0 { return 0 };
211 let mut running: Self = 1;
212 for _ in 0..power as usize {
213 running *= 10;
214 }
215 running
216 }
217}
218impl PowersOfTen for i32 {
219 fn order_of(power: isize) -> Self {
220 if power < 0 { return 0 };
221 let mut running: Self = 1;
222 for _ in 0..power as usize {
223 running *= 10;
224 }
225 running
226 }
227}
228impl PowersOfTen for i64 {
229 fn order_of(power: isize) -> Self {
230 if power < 0 { return 0 };
231 let mut running: Self = 1;
232 for _ in 0..power as usize {
233 running *= 10;
234 }
235 running
236 }
237}
238impl PowersOfTen for isize {
239 fn order_of(power: isize) -> Self {
240 if power < 0 { return 0 };
241 let mut running: Self = 1;
242 for _ in 0..power as usize {
243 running *= 10;
244 }
245 running
246 }
247}
248impl PowersOfTen for f32 {
249 fn order_of(power: isize) -> Self {
250 let mut running: Self = 1.0;
251 if power < 0 {
252 for _ in power..0 { running *= 0.1; }
253 } else {
254 for _ in 0..power { running *= 10.0; }
255 }
256 running
257 }
258}
259impl PowersOfTen for f64 {
260 fn order_of(power: isize) -> Self {
261 let mut running: Self = 1.0;
262 if power < 0 {
263 for _ in power..0 { running *= 0.1; }
264 } else {
265 for _ in 0..power { running *= 10.0; }
266 }
267 running
268 }
269}
270
271impl UsefulReals for f32 {
272 const TWO: Self = 2.0;
273 const E: Self = 2.718281828459045;
274 const TAU: Self = 6.283185307179586;
275 const PI: Self = 3.141592653589793;
276 const HALFPI: Self = 1.5707963267948966;
277 const QTRPI: Self = 0.7853981633974483;
278}
279impl UsefulReals for f64 {
280 const TWO: Self = 2.0;
281 const E: Self = 2.718281828459045;
282 const TAU: Self = 6.283185307179586;
283 const PI: Self = 3.141592653589793;
284 const HALFPI: Self = 1.5707963267948966;
285 const QTRPI: Self = 0.7853981633974483;
286}
287impl Inverse for f32 {
288 fn inv(self) -> Self { 1.0 / self }
289}
290impl Inverse for f64 {
291 fn inv(self) -> Self { 1.0 / self }
292}
293impl PowersOfE for f32 {}
294impl PowersOfE for f64 {}
295impl Magnitude for f32 {}
296impl Magnitude for f64 {}
297
298impl Reals for f32 {
299 const UNDEF: Self = Self::NAN;
300 const INFINITE: Self = Self::INFINITY;
301}
302impl Reals for f64 {
303 const UNDEF: Self = Self::NAN;
304 const INFINITE: Self = Self::INFINITY;
305}
306
307pub trait LaTeX: std::fmt::Display {
308 fn latex(&self) -> String { format!("{}", self) }
309}
310
311impl LaTeX for u8 {}
312impl LaTeX for u16 {}
313impl LaTeX for u32 {}
314impl LaTeX for u64 {}
315impl LaTeX for usize {}
316impl LaTeX for i8 {}
317impl LaTeX for i16 {}
318impl LaTeX for i32 {}
319impl LaTeX for i64 {}
320impl LaTeX for isize {}
321
322impl LaTeX for f32 {}
323impl LaTeX for f64 {}