unitforge/
prelude.rs

1use ndarray::{Array1, Array2, ArrayView1, ArrayView2};
2use num_traits::{FromPrimitive, Zero};
3use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
4
5#[macro_export]
6macro_rules! power {
7    ($x:expr, 1) => {
8        $x
9    };
10    ($x:expr, 2) => {
11        $x * $x
12    };
13    ($x:expr, 3) => {
14        $x * $x * $x
15    };
16    ($x:expr, 4) => {
17        $x * $x * $x * $x
18    };
19    ($x:expr, 5) => {
20        $x * $x * $x * $x * $x
21    };
22    ($x:expr, 6) => {
23        $x * $x * $x * $x * $x * $x
24    };
25}
26
27pub trait MulArray1<RHS> {
28    type Output;
29
30    fn mul_array1(self, rhs: Array1<RHS>) -> Self::Output;
31}
32
33pub trait MulArray2<RHS> {
34    type Output;
35
36    fn mul_array2(self, rhs: Array2<RHS>) -> Result<Self::Output, String>;
37}
38
39pub trait DivArray1<RHS> {
40    type Output;
41
42    fn div_array1(self, rhs: Array1<RHS>) -> Self::Output;
43}
44
45pub trait DivArray2<RHS> {
46    type Output;
47
48    fn div_array2(self, rhs: Array2<RHS>) -> Result<Self::Output, String>;
49}
50
51pub trait QuantityArray2<T> {
52    fn from_raw(raw: ArrayView2<f64>, unit: T) -> Self;
53    fn to_raw(&self) -> Array2<f64>;
54    fn to(&self, unit: T) -> Array2<f64>;
55}
56
57pub trait QuantityArray1<T> {
58    fn from_raw(raw: ArrayView1<f64>, unit: T) -> Self;
59    fn to_raw(&self) -> Array1<f64>;
60    fn to(&self, unit: T) -> Array1<f64>;
61}
62
63pub trait PhysicsQuantity:
64    Copy
65    + FromPrimitive
66    + Zero
67    + Add<Output = Self>
68    + AddAssign
69    + Div<f64, Output = Self>
70    + DivAssign<f64>
71    + Mul<f64, Output = Self>
72    + MulAssign<f64>
73    + Sub<Output = Self>
74    + SubAssign
75    + PartialOrd
76    + Neg<Output = Self>
77{
78    type Unit: PhysicsUnit;
79    fn new(value: f64, unit: Self::Unit) -> Self;
80    fn to(&self, unit: Self::Unit) -> f64;
81    fn zero() -> Self;
82    fn get_tuple(&self) -> (f64, i32);
83    fn abs(self) -> Self;
84    fn to_raw(&self) -> f64;
85    fn from_raw(value: f64) -> Self;
86    fn from_exponential(multiplier: f64, power: i32) -> Self;
87    fn min(self, other: Self) -> Self;
88    fn max(self, other: Self) -> Self;
89    fn get_value(&self) -> f64;
90    fn get_power(&self) -> i32;
91    fn get_multiplyer(&self) -> f64;
92    fn split_value(v: f64) -> (f64, i32);
93    const INFINITY: Self;
94    const NEG_INFINITY: Self;
95}
96
97pub trait Sqrt<T> {
98    fn sqrt(self) -> T;
99}
100
101impl PhysicsQuantity for f64 {
102    type Unit = NoUnit;
103
104    fn new(value: f64, _unit: Self::Unit) -> Self {
105        value
106    }
107
108    fn to(&self, _unit: Self::Unit) -> f64 {
109        self.to_raw()
110    }
111
112    fn zero() -> Self {
113        0.
114    }
115
116    fn get_tuple(&self) -> (f64, i32) {
117        (self.get_multiplyer() , self.get_power())
118    }
119
120    fn abs(self) -> Self {
121        self.abs()
122    }
123
124    fn to_raw(&self) -> f64 {
125        *self
126    }
127
128    fn from_raw(value: f64) -> Self {
129        value
130    }
131
132    fn from_exponential(multiplier: f64, power: i32) -> Self {
133        multiplier * 10_f64.powi(power)
134    }
135
136    fn min(self, other: Self) -> Self {
137        if self < other {
138            self
139        } else {
140            other
141        }
142    }
143
144    fn max(self, other: Self) -> Self {
145        if self > other {
146            self
147        } else {
148            other
149        }
150    }
151
152    fn get_value(&self) -> f64 {
153        *self
154    }
155
156    fn get_power(&self) -> i32 {
157        0
158    }
159
160    fn get_multiplyer(&self) -> f64 {
161        *self
162    }
163
164    fn split_value(v: f64) -> (f64, i32) {
165        let power = v.abs().log10().floor() as i32;
166        let multiplier = v / 10f64.powi(power);
167        (multiplier, power)
168    }
169
170    const INFINITY: Self = f64::INFINITY;
171    const NEG_INFINITY: Self = f64::NEG_INFINITY;
172}
173pub use crate::power;
174
175pub trait PhysicsUnit {
176    fn name(&self) -> &str;
177    fn base_per_x(&self) -> (f64, i32);
178}
179
180pub enum NoUnit {
181    no_unit,
182}
183
184impl PhysicsUnit for NoUnit {
185    fn name(&self) -> &str {
186        ""
187    }
188
189    fn base_per_x(&self) -> (f64, i32) {
190        (1., 0)
191    }
192}