dlt/
lib.rs

1#![feature(generic_const_exprs)]
2#![feature(trivial_bounds)]
3#![feature(generic_arg_infer)]
4#![allow(mixed_script_confusables)]
5
6pub mod tensor;
7
8
9pub mod dimension;
10use dimension::*;
11
12pub mod units;
13use units::*;
14
15pub mod si;
16
17
18pub mod complex;
19
20
21#[cfg(test)]
22mod tests {
23    use super::*;
24    use crate::si::*;
25    use crate::tensor::*;
26    use crate::complex::*;
27
28    #[test]
29    fn test_stuff() {
30        // Tensor of lengths
31        let mass = (10.0).scalar::<Kilogram>();
32        let force = Vec2::<f64,Force>::new::<Newton>([1.0, 2.0]);
33
34        //let error = mass + force; // error (expected)
35
36        let mass = mass + Scalar::<f64,Mass>::from::<Gram>(5.0); // works
37        println!("{}", mass);
38        /*
39        Tensor [1x1]: M^1
40        ( 10.005 )
41        */
42
43        let acc = force.scale(mass.inv()); // works
44        println!("{}", acc);
45        /*
46        Tensor [2x1]: L^1 * T^-2
47        ( 0.9995002 )
48        ( 1.9990004 )
49        */
50
51        let time = Scalar::<f64,Time>::new::<Second>([1.0]);
52        let vel1 = Vec2::<f64,Velocity>::new::<MetersPerSecond>([10.0, 20.0]);
53
54        let vel2 = vel1 + acc.scale(time); // works
55        println!("{:?}", vel2.get::<MetersPerSecond>());
56        /*
57        [c64 { a: 10.099950024987507, b: 0.0 }, c64 { a: 20.199900049975014, b: 0.0 }]
58        */
59
60        // try to transpose a tensor
61        let tensor = Tensor::<c64,Dimensionless, 1,1, 6>::new::<Unitless>([1.0, 2.0, 3.0, 4.0, 5.0, 6.0].complex());
62        let tensor_transposed = tensor.transpose();
63        println!("{}", tensor);
64        println!("{}", tensor_transposed);
65        /*
66        Tensor [1x6]: Dimensionless
67        ( 1  2  3  4  5  6 )
68
69        Tensor [6x1]: Dimensionless
70        ( 1 )
71        ( 2 )
72        ( 3 )
73        ( 4 )
74        ( 5 )
75        ( 6 )
76         */
77
78        let length = Vec2::<f64,Length>::new::<Meter>([10.0, 20.0]);
79
80        // now try and dot product length and force
81        let dot_product = dot!(length, force);
82        println!("{}", dot_product);
83        /*
84        Tensor [1x1]: L^2 * M^1 * T^-2
85        ( 50 )
86        */
87
88        assert_dimension!(dot_product, Energy); // works
89        //assert_dimension!(dot_product, Force); // error (expected)
90
91        let m1 = Matrix::<f64,Length, 2, 3>::new::<Meter>([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
92        let m2 = Matrix::<f64,Length, 3, 2>::new::<Meter>([1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
93
94        let m3 = m1.matmul(m2);
95        println!("{}", m3);
96        /*
97        Tensor [2x2]: L^2
98        ( 22  28 )
99        ( 49  64 )
100        */
101
102
103        // test openrators
104        if (vel1 == vel2) {
105            println!("Equal");
106        } else {
107            println!("Not equal");
108        }
109
110        let mass2 = Scalar::<f64,Mass>::from::<Kilogram>(10.0);
111
112        if (mass == mass2) {
113            println!("Equal");
114        } else {
115            if mass < mass2 {
116                println!("Less than");
117            } else {
118                println!("Greater than");
119            }
120        }
121
122
123        // test macros
124
125        let inv = Scalar::<f64,dim_inv!(Time)>::from::<unit_inv!(Second)>(1.0);
126
127        let mul = Scalar::<f64,dim_div!(Energy,Temperature)>::new::<unit_div!(Joule, Kelvin)>([1.0]);
128
129        assert_dimension!(mul, Entropy); // works
130        assert_dimension!(inv, Frequency); // works
131
132        println!("{}", inv);
133        println!("{}", mul);
134
135        /*
136        Tensor [1x1]: T^-1
137        ( 1 )
138
139        Tensor [1x1]: L^2 * M^1 * T^-2 * Θ^-1
140        ( 1 )
141        */
142
143        // test dot product
144        let a = Vec2::<f64,Length>::new::<Meter>([1.0, 2.0]);
145        let b = Vec2::<f64,Length>::new::<Meter>([3.0, 4.0]);
146        let c = dot!(a, b);
147        println!("{}", c);
148
149        
150
151        // invert
152        let d = c.inv();
153        println!("{}", d);
154
155    }
156
157    #[test]
158    fn test_simple() {
159
160        let a = cvec!((2,4), (3,5));
161        let b = cvec!((1,2), (3,4));
162
163        let c = ip!(a,b);
164        println!("{}", c);
165    }
166
167    #[test]
168    fn test_conjugate_transpose() {
169        let a = cvec!((2,4), (3,5));  // [2+4i, 3+5i]
170        let a_h = a.conjugate_transpose();
171
172        println!("{}", a);
173        println!("{}", a_h);
174
175
176
177        assert_eq!(a_h.get_at(0,0,0).raw(), c64::new(2.0, -4.0));
178        assert_eq!(a_h.get_at(0,0,1).raw(), c64::new(3.0, -5.0));
179    }
180
181
182    #[test]
183    fn test_inner_product() {
184        let a = cvec!((2,4), (3,5));
185        let b = cvec!((1,2), (3,4));
186
187        println!("a:\n{}", a);
188        println!("b:\n{}", b);
189        println!("a†:\n{}", a.conjugate_transpose());
190        println!("a† × b:\n{}", a.conjugate_transpose().matmul(b));
191
192
193        let c = ip!(a,b);
194        println!("c: {}",c);
195
196        let c_ = dless!((39.0, -3.0).complex());
197        println!("c_: {}",c_);
198
199        // The result should be -17 - 7i
200        assert_approx_eq!(c, c_);
201
202        // Test conjugate symmetry
203        assert_approx_eq!(ip!(a,b).conjugate(), ip!(b,a));
204
205        // Test linearity
206        let d = cvec!((1,1), (2,2));
207        let alpha = dless!((2.0, 1.0).complex());
208
209        // (a, αb + d) = α(a,b) + (a,d)
210        assert_approx_eq!(
211            ip!(a,(b.scale(alpha) + d)),
212            ip!(a,b).scale(alpha) + ip!(a,d)
213        );
214
215        // Test positive definiteness
216        assert!(ip!(a,a).raw().re() >= 0.0);
217    }
218
219    #[test]
220    fn pure_test() {
221        let a = cvec!((2,4), (3,5));
222        let b = cvec!((1,2), (3,4));
223
224        let c = ip!(a,b);
225        println!("{}", c);
226
227        let c_ = dless!((39.0, -3.0).complex());
228        println!("{}", c_);
229
230        assert_approx_eq!(c, c_);
231
232        let d = Natural::<1,1,4>::nat([1.0, 2.0, 3.0, 4.0].complex());
233        println!("{}", d);
234
235        let e = dless!((1.0, 2.0).complex());
236
237
238    }
239
240    #[test]
241    fn test_linalg() {
242        
243    }
244
245
246
247}
248
249
250
251
252
253
254
255
256
257
258