grassmann/core/
matrix2.rs

1use std::{f64::consts::PI, fmt, fmt::{
2    Display, 
3    Formatter
4}, ops::{
5    Add, 
6    AddAssign, 
7    Index, 
8    IndexMut,
9    Sub,
10    SubAssign,
11    Mul,
12    Div,
13    Neg
14}};
15use crate::{Float, functions::utils::eq_eps_f64, matrix, vec3, vec2, vector, vector3::Vector3};
16use super::{matrix::Matrix, matrix4::Matrix4, vector::Vector, vector2::Vector2, vector4::Vector4};
17
18
19
20#[macro_export]
21macro_rules! matrix2 {
22    (
23        $x1:expr, $y1:expr,
24        $x2:expr, $y2:expr
25    ) => {
26        {
27            Matrix2::new([
28                $x1, $y1,
29                $x2, $y2
30            ])
31        }
32    };
33}
34
35
36
37#[macro_export]
38macro_rules! compose_basis2 {
39    (
40        $x:expr, 
41        $y:expr
42    ) => {
43        {
44            Matrix2::new([
45                $x[0], $y[0],
46                $x[1], $y[1]
47            ])
48        }
49    };
50}
51
52
53
54#[derive(Clone, Debug)]
55pub struct Matrix2 {
56    pub data: [Float; 4]
57}
58
59
60
61impl Display for Matrix2 {
62    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
63        write!(f, 
64            "\n [{}, {}] \n [{}, {}] \n",
65            self[0], self[1],
66            self[2], self[3]
67        )
68    }
69}
70
71
72
73impl Index<usize> for Matrix2 {
74    type Output = Float;
75
76    fn index(&self, idx:usize) -> &Float {
77        &self.data[idx]
78    }
79}
80
81
82
83impl IndexMut<usize> for Matrix2 {
84    fn index_mut(&mut self, idx:usize) -> &mut Float {
85        &mut self.data[idx]
86    }
87}
88
89
90
91impl Matrix2 {
92
93    pub fn new(data: [Float; 4]) -> Matrix2 {
94        Matrix2 {
95            data
96        }
97    }
98
99
100
101    pub fn id() -> Matrix2 {
102        Matrix2::new([
103            1., 0.,
104            0., 1.
105        ])
106    }
107
108
109
110    pub fn transpose(&self) -> Matrix2 {
111        Matrix2::new([
112            self[0], self[2],
113            self[1], self[3]
114        ])
115    }
116
117
118
119    pub fn det(&self) -> Float {
120
121        let a = self[0];
122        let b = self[1];
123        let c = self[2];
124        let d = self[3];
125        
126        a * d - b * c
127    }
128
129
130
131    pub fn trace(&self) -> Float {
132
133        self[0] + self[3]
134
135    }
136
137
138
139    pub fn eig(&self) -> Option<(f64, f64)> {
140
141        let t = self.trace();
142
143        let d = self.det();
144
145        let r = t.powf(2.) - 4. * d;
146
147        if r < 0. {
148           return None;
149        }
150
151        let y1 = (t + r.sqrt()) / 2.;
152
153        let y2 = (t - r.sqrt()) / 2.;
154
155        Some((y1, y2))
156    }
157
158
159
160    pub fn inv(&self) -> Option<Matrix2> {
161
162        let d = self.det();
163
164        if d == 0. {
165            return None;
166        }
167
168        let a = self[0];
169        let b = self[1];
170        let c = self[2];
171        let d = self[3];
172
173        let mut m = matrix2![
174            d, -b,
175           -c,  a
176        ];
177
178        m = m * (1. / d);
179
180        Some(m)
181    }
182
183
184
185    pub fn rotation(rad: f64) -> Matrix2 {
186
187        let z = matrix2![
188            rad.cos(), -rad.sin(),
189            rad.sin(),  rad.cos()
190        ];
191
192        z
193    }
194
195
196
197    pub fn scale(s: f64) -> Matrix2 {
198        matrix2![
199            s,  0.,
200            0., s
201        ]
202    }
203
204
205
206    pub fn sheer(xy:f64, yx:f64) -> Matrix2 {
207        matrix2![
208            1., yx,
209            xy, 1.
210        ]
211    }
212
213
214    
215    pub fn from_basis(
216        x: Vector2,
217        y: Vector2
218    ) -> Matrix2 {
219        let r = compose_basis2![
220            &x,
221            &y
222        ];
223
224        r
225    }
226    
227
228
229    pub fn into_basis(&self) -> [Vector2; 2] {
230
231        let x = vec2![self[0], self[2]];
232        let y = vec2![self[1], self[3]];
233
234        [x,y]
235    }
236    
237
238
239    pub fn apply(&mut self, f: fn(f64) -> f64) {
240        self[0] = f(self[0]);
241        self[1] = f(self[1]);
242        self[2] = f(self[2]); 
243        self[3] = f(self[3]);
244    }
245}
246
247
248
249fn add(a:&Matrix2, b:&Matrix2) -> Matrix2 {
250    Matrix2::new([
251        a[0] + b[0], a[1] + b[1],
252        a[2] + b[2], a[3] + b[3]
253    ])
254}
255
256
257
258fn sub(a:&Matrix2, b:&Matrix2) -> Matrix2 {
259    Matrix2::new([
260        a[0] - b[0], a[1] - b[1],
261        a[2] - b[2], a[3] - b[3]
262    ])
263}
264
265
266
267fn mul(a:&Matrix2, b:&Matrix2) -> Matrix2 {
268    Matrix2::new([
269        a[0] * b[0] + a[1] * b[2], a[0] * b[1] + a[1] * b[2],
270        a[2] * b[0] + a[3] * b[2], a[2] * b[1] + a[3] * b[2]
271    ])
272}
273
274
275
276fn mul_v(a:&Matrix2, v:&Vector2) -> Vector2 {
277    Vector2::new(
278        a[0] * v.x + a[1] * v.y,
279        a[3] * v.x + a[4] * v.y
280    )
281}
282
283
284
285impl Add for &Matrix2 {
286    type Output = Matrix2;
287
288    fn add(self, b:&Matrix2) -> Matrix2 {
289        add(self, b)
290    }
291}
292
293
294
295impl Add for Matrix2 {
296    type Output = Matrix2;
297
298    fn add(self, b:Matrix2) -> Matrix2 {
299        add(&self, &b)
300    }
301}
302
303
304
305impl Sub for &Matrix2 {
306    type Output = Matrix2;
307
308    fn sub(self, b:&Matrix2) -> Matrix2 {
309        sub(self, b)
310    }
311}
312
313
314
315impl Sub for Matrix2 {
316    type Output = Matrix2;
317
318    fn sub(self, b:Matrix2) -> Matrix2 {
319        sub(&self, &b)
320    }
321}
322
323
324
325impl Mul for &Matrix2 {
326    type Output = Matrix2;
327
328    fn mul(self, b: &Matrix2) -> Matrix2 {
329        mul(self, b)
330    }
331}
332
333
334
335impl Mul for Matrix2 {
336    type Output = Matrix2;
337
338    fn mul(self, b: Matrix2) -> Matrix2 {
339        mul(&self, &b)
340    }
341}
342
343
344
345impl Mul <Vector2> for &Matrix2 {
346    type Output = Vector2;
347
348    fn mul(self, v:Vector2) -> Vector2 {
349        mul_v(&self, &v)
350    }
351}
352
353
354
355impl Mul <Vector2> for Matrix2 {
356    type Output = Vector2;
357
358    fn mul(self, v:Vector2) -> Vector2 {
359        mul_v(&self, &v)
360    }
361}
362
363
364
365impl Mul <&Vector2> for Matrix2 {
366    type Output = Vector2;
367
368    fn mul(self, v:&Vector2) -> Vector2 {
369        mul_v(&self, v)
370    }
371}
372
373
374
375impl Mul <&Vector2> for &Matrix2 {
376    type Output = Vector2;
377
378    fn mul(self, v:&Vector2) -> Vector2 {
379        mul_v(self, v)
380    }
381}
382
383
384
385impl Mul <Float> for Matrix2 {
386    type Output = Matrix2;
387
388    fn mul(mut self, s:f64) -> Matrix2 {
389        self[0] *= s;
390        self[1] *= s;
391        self[2] *= s;
392        self[3] *= s;
393        self
394    }
395}
396
397
398
399impl Div <Float> for Matrix2 {
400    type Output = Matrix2;
401
402    fn div(mut self, s:f64) -> Matrix2 {
403        self[0] /= s;
404        self[1] /= s;
405        self[2] /= s;
406        self[3] /= s;
407        self
408    }
409}
410
411
412
413impl AddAssign for Matrix2 {
414    fn add_assign(&mut self, b:Matrix2) {
415        self[0] += b[0];
416        self[1] += b[1];
417        self[2] += b[2];
418        self[3] += b[3];
419    }
420}
421
422
423
424impl SubAssign for Matrix2 {
425    fn sub_assign(&mut self, b:Matrix2) {
426        self[0] -= b[0];
427        self[1] -= b[1];
428        self[2] -= b[2];
429        self[3] -= b[3];
430        self[4] -= b[4];
431        self[5] -= b[5];
432        self[6] -= b[6];
433        self[7] -= b[7];
434        self[8] -= b[8];
435    }
436}
437
438
439
440impl PartialEq for Matrix2 {
441    fn eq(&self, b: &Matrix2) -> bool {
442        self[0] == b[0] &&
443        self[1] == b[1] &&
444        self[2] == b[2] &&
445        self[3] == b[3]
446    }
447}
448
449
450
451impl Eq for Matrix2 {}
452
453
454
455impl Neg for Matrix2 {
456
457    type Output = Matrix2;
458
459    fn neg(mut self) -> Self {
460        self[0] *= -1.;
461        self[1] *= -1.;
462        self[2] *= -1.;
463        self[3] *= -1.;
464        self
465    }
466}
467
468
469
470impl From<Matrix<f64>> for Matrix2 {
471    fn from(m: Matrix<f64>) -> Matrix2 {
472        matrix2![
473            m[[0,0]], m[[0,1]],
474            m[[1,0]], m[[1,1]]
475        ]
476    }
477}
478
479
480
481impl From<&Matrix<f64>> for Matrix2 {
482    fn from(m: &Matrix<f64>) -> Matrix2 {
483        matrix2![
484            m[[0,0]], m[[0,1]],
485            m[[1,0]], m[[1,1]]
486        ]
487    }
488}
489
490
491
492impl From<Matrix4> for Matrix2 {
493    fn from(m: Matrix4) -> Matrix2 {
494        matrix2![
495            m[0], m[1],
496            m[4], m[5]
497        ]
498    }
499}
500
501
502
503impl From<&Matrix4> for Matrix2 {
504    fn from(m: &Matrix4) -> Matrix2 {
505        matrix2![
506            m[0], m[1],
507            m[4], m[5]
508        ]
509    }
510}
511
512
513
514mod tests {
515    
516    use super::{ Matrix, Vector, Matrix2 };
517    
518    #[test]
519    fn eig_test() {
520
521        let max = 6.3;
522        let m = Matrix::rand(2, 2, max);
523        let id = Matrix::id(2);
524        let b = Vector::new(vec![0.,0.]);
525        let m2: Matrix2 = m.clone().into();
526
527        println!("\n m2 is {} det is {} \n", m2, m2.det());
528        
529        let e = m2.eig();
530
531        if e.is_none() {
532           return;
533        }
534
535        let e = e.unwrap();
536
537        println!("\n A is {}, {} \n", m, m.rank());
538        println!("\n e is {} {} \n", e.0, e.1);
539        
540        let A1 = &m - &(&id * e.0);
541        let A2 = &m - &(&id * e.1);
542
543        println!("\n A1 is {}, {} \n", A1, A1.rank());
544        println!("\n A2 is {}, {} \n", A2, A2.rank());
545
546        let lu_A1 = A1.lu();
547        let x1 = A1.solve(&b, &lu_A1).unwrap();
548
549        let lu_A2 = A2.lu();
550        let x2 = A2.solve(&b, &lu_A2).unwrap();
551
552        println!("\n x1 {} \n", x1);
553        println!("\n x2 {} \n", x2);
554
555        let y1: Vector<f64> = &A1 * &x1;
556        let y2: Vector<f64> = &A1 * &x1;
557
558        println!("\n y1 {} \n", y1);
559        println!("\n y2 {} \n", y2);
560
561        //rank
562        //there is a vector in null space
563
564        //assert!(false);
565    }
566}