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 }
566}