ndarray_unit/
lib.rs

1//! This crate provides a struct representing a [multidimensionnal array](https://docs.rs/ndarray/) together with a `Unit`.  
2//! It allows to do computations taking into account the unit of your n-dimensional array.
3//!
4//! # Examples
5//!
6//! ```
7//! use ndarray_unit::*;
8//!
9//! extern crate ndarray;
10//! use ndarray::Array;
11//!
12//! fn main() {
13//!     println!("meter / second = {}", &get_meter() / &get_second());
14//!
15//!     let arr1 = Array::linspace(30.0, 40.0, 11);
16//!     let arr_u1 = ArrayUnit::new(arr1, get_joule());
17//!
18//!     let arr2 = Array::linspace(10.0, 60.0, 11);
19//!     let arr_u2 = ArrayUnit::new(arr2, get_second());
20//!
21//!     let arr3 = ndarray::array![
22//!         [1.0, 0.0, 2.0, 6.0],
23//!         [1.0, 2.0, 3.0, 5.0],
24//!         [1.0, 2.0, 3.0, 6.0]
25//!     ];
26//!     let arr_u3 = ArrayUnit::new(arr3, get_meter());
27//!
28//!     println!("arr_u3 = {}", arr_u3);
29//!     println!("==========================================================");
30//!     println!("{}\n*{}\n={}", &arr_u1, &arr_u2, &arr_u1 * &arr_u2);
31//!     println!("==========================================================");
32//!     println!("{}\n/{}\n={}", &arr_u1, &arr_u2, &arr_u1 / &arr_u2);
33//!     println!("==========================================================");
34//!     println!("{}\n+{}\n={}", &arr_u1, &arr_u1, &arr_u1 + &arr_u1);
35//!     println!("==========================================================");
36//!     println!("{}\n-{}\n={}", &arr_u2, &arr_u2, &arr_u2 - &arr_u2);
37//!     println!("==========================================================");
38//! }
39//! ```
40//! **Output**
41//! ```
42//! // meter / second = m·s⁻¹
43//! // arr_u3 = [[1, 0, 2, 6],
44//! //  [1, 2, 3, 5],
45//! //  [1, 2, 3, 6]] m
46//! // ==========================================================
47//! // [30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40] m²·kg·s⁻²
48//! // *[10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60] s
49//! // =[300, 465, 640, 825, 1020, 1225, 1440, 1665, 1900, 2145, 2400] m²·kg·s⁻¹
50//! // ==========================================================
51//! // [30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40] m²·kg·s⁻²
52//! // /[10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60] s
53//! // =[3, 2.0666, 1.6, 1.32, 1.1333, 1, 0.9, 0.8222, 0.76, 0.7090, 0.6666] m²·kg·s⁻³
54//! // ==========================================================
55//! // [30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40] m²·kg·s⁻²
56//! // +[30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40] m²·kg·s⁻²
57//! // =[60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80] m²·kg·s⁻²
58//! // ==========================================================
59//! // [10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60] s
60//! // -[10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60] s
61//! // =[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] s
62//! // ==========================================================
63//! ```
64//!
65//! # Panics
66//! The program will panic when you try to add or substract two `ArrayUnit`s with different `Unit`s.
67//! ```
68//! extern crate ndarray;
69//! use ndarray::Array;
70//! use ndarray_unit::*;
71//!
72//! let arr1 = Array::linspace(30.0, 40.0, 11);
73//! let arr_u1 = ArrayUnit::new(arr1, get_joule());
74//!
75//! let arr2 = Array::linspace(10.0, 60.0, 11);
76//! let arr_u2 = ArrayUnit::new(arr2, get_second());
77//!
78//! // let result = &arr_u1 + &arr_u2; // ==> panicking
79//! ```
80
81#![crate_name = "ndarray_unit"]
82
83mod unit;
84pub use unit::BaseUnit;
85pub use unit::Unit;
86
87mod array_unit;
88pub use array_unit::ArrayUnit;
89
90//////////////////////////
91// Getters for base units
92//////////////////////////
93
94/// Utility method to get a Unit from a BaseUnit (BaseUnit::METER)
95pub fn get_meter() -> Unit {
96    Unit::from_vec(vec![(BaseUnit::METER, 1)])
97}
98
99/// Utility method to get a Unit from a BaseUnit (BaseUnit::SECOND)
100pub fn get_second() -> Unit {
101    Unit::from_vec(vec![(BaseUnit::SECOND, 1)])
102}
103
104/// Utility method to get a Unit from a BaseUnit (BaseUnit::CANDELA)
105pub fn get_candela() -> Unit {
106    Unit::from_vec(vec![(BaseUnit::CANDELA, 1)])
107}
108
109/// Utility method to get a Unit from a BaseUnit (BaseUnit::MOLE)
110pub fn get_mole() -> Unit {
111    Unit::from_vec(vec![(BaseUnit::MOLE, 1)])
112}
113
114/// Utility method to get a Unit from a BaseUnit (BaseUnit::KELVIN)
115pub fn get_kelvin() -> Unit {
116    Unit::from_vec(vec![(BaseUnit::KELVIN, 1)])
117}
118
119/// Utility method to get a Unit from a BaseUnit (BaseUnit::AMPERE)
120pub fn get_ampere() -> Unit {
121    Unit::from_vec(vec![(BaseUnit::AMPERE, 1)])
122}
123
124/////////////////////////////
125// Getters for other useful units
126/////////////////////////////
127
128/// Utility method to get a Unit from a BaseUnit (BaseUnit::RADIAN)
129pub fn get_radian() -> Unit {
130    Unit::from_vec(vec![(BaseUnit::RADIAN, 1)])
131}
132
133/// Utility method to get a Unit from a BaseUnit (BaseUnit::STERADIAN)
134pub fn get_steradian() -> Unit {
135    Unit::from_vec(vec![(BaseUnit::STERADIAN, 1)])
136}
137
138/////////////////////////////
139// Getters for economics indicators
140/////////////////////////////
141pub fn get_currency() -> Unit {
142    Unit::from_vec(vec![(BaseUnit::CURRENCY, 1)])
143}
144
145pub fn get_birth() -> Unit {
146    Unit::from_vec(vec![(BaseUnit::BIRTH, 1)])
147}
148
149pub fn get_death() -> Unit {
150    Unit::from_vec(vec![(BaseUnit::DEATH, 1)])
151}
152
153pub fn get_inhabitant() -> Unit {
154    Unit::from_vec(vec![(BaseUnit::INHABITANT, 1)])
155}
156
157/////////////////////////////
158// Getters for composed units
159/////////////////////////////
160
161/// Utility method to get the Joule Unit (composed)
162pub fn get_newton() -> Unit {
163    Unit::from_vec(vec![
164        (BaseUnit::KILOGRAM, 1),
165        (BaseUnit::METER, 1),
166        (BaseUnit::SECOND, -2),
167    ])
168}
169
170/// Utility method to get the Joule Unit (composed)
171pub fn get_joule() -> Unit {
172    &get_newton() * &get_meter()
173}
174
175/// Utility method to get the Watt Unit (composed)
176pub fn get_watt() -> Unit {
177    Unit::from_vec(vec![
178        (BaseUnit::KILOGRAM, 1),
179        (BaseUnit::METER, 2),
180        (BaseUnit::SECOND, -3),
181    ])
182}
183
184/// Utility method to get the Volt Unit (composed)
185pub fn get_volt() -> Unit {
186    &get_watt() * &get_ampere().get_inverse()
187}
188
189/// Utility method to get the Ohm Unit (composed)
190pub fn get_ohm() -> Unit {
191    &get_volt() / &get_ampere()
192}
193
194/// Utility method to get the Siemens Unit (composed)
195pub fn get_siemens() -> Unit {
196    get_ohm().get_inverse()
197}
198
199/// Utility metgod to get the Pascal Unit (composed)
200pub fn get_pascal() -> Unit {
201    Unit::from_vec(vec![
202        (BaseUnit::KILOGRAM, 1),
203        (BaseUnit::METER, -1),
204        (BaseUnit::SECOND, -2),
205    ])
206}
207
208/// Utility method to get the Coulomb Unit (composed)
209pub fn get_coulomb() -> Unit {
210    &get_ampere() * &get_second()
211}
212
213/// Utility method to get the Coulomb Unit (composed)
214pub fn get_farad() -> Unit {
215    &get_coulomb() / &get_volt()
216}
217
218/// Utility method to get the Henry Unit (composed)
219pub fn get_henry() -> Unit {
220    Unit::from_vec(vec![
221        (BaseUnit::KILOGRAM, 1),
222        (BaseUnit::METER, 2),
223        (BaseUnit::SECOND, -2),
224        (BaseUnit::AMPERE, -2),
225    ])
226}
227
228/// Utility method to get the Weber Unit (composed)
229pub fn get_weber() -> Unit {
230    &get_volt() * &get_second()
231}
232
233/// Utility method to get the becquerel Unit (composed)
234pub fn get_becquerel() -> Unit {
235    get_second().get_inverse()
236}
237
238/// Utility method to get the Hertz Unit (composed)
239pub fn get_hertz() -> Unit {
240    get_second().get_inverse()
241}
242
243/// Utility method to get the Tesla Unit (composed)
244pub fn get_tesla() -> Unit {
245    Unit::from_vec(vec![
246        (BaseUnit::KILOGRAM, 1),
247        (BaseUnit::SECOND, -2),
248        (BaseUnit::AMPERE, -1),
249    ])
250}
251
252#[cfg(test)]
253mod test;