1#![macro_use]
32use core::fmt;
33use core::ops::{Add, Mul, Div, Sub, SubAssign, AddAssign, Neg};
34use core::ops::{Deref, DerefMut, Index, IndexMut};
35
36use crate::traits::LinearAlgebra;
37use crate::utils::nearly_zero;
38use num::{Float, One, Zero, Num, Signed};
39
40use crate::slices_methods::*;
41use crate::vector3::*;
42#[derive(Copy, Clone, Debug, PartialEq)]
48pub struct M33<T>([[T; 3]; 3]);
49
50impl<T> M33<T> {
51 pub const fn new(data_input: [[T; 3]; 3]) -> M33<T> {
52 M33(data_input)
53 }
54
55 pub const fn rows(&self) -> usize {
56 self.0.len()
57 }
58
59 pub const fn cols(&self) -> usize {
60 self.rows()
61 }
62}
63
64impl<T: Float + core::iter::Sum> LinearAlgebra<T> for M33<T> {
65 fn rows(&self) -> usize {
66 self.0.len()
67 }
68
69 fn cols(&self) -> usize {
70 self.rows()
71 }
72
73 #[inline(always)]
74 fn transpose(&self) -> M33<T> {
75 M33::new([
76 [self[(0, 0)], self[(1, 0)], self[(2, 0)]],
77 [self[(0, 1)], self[(1, 1)], self[(2, 1)]],
78 [self[(0, 2)], self[(1, 2)], self[(2, 2)]],
79 ])
80 }
81
82 #[inline(always)]
83 fn trace(&self) -> T {
84 self[(0, 0)] + self[(1, 1)] + self[(2, 2)]
85 }
86
87 fn norm2(&self) -> T {
88 T::sqrt(
89 self[(0, 0)] * self[(0, 0)]
90 + self[(1, 0)] * self[(1, 0)]
91 + self[(2, 0)] * self[(2, 0)]
92 + self[(0, 1)] * self[(0, 1)]
93 + self[(1, 1)] * self[(1, 1)]
94 + self[(2, 1)] * self[(2, 1)]
95 + self[(0, 2)] * self[(0, 2)]
96 + self[(1, 2)] * self[(1, 2)]
97 + self[(2, 2)] * self[(2, 2)],
98 )
99 }
100
101 #[inline(always)]
103 fn det(&self) -> T {
104 self[(0, 0)] * (self[(1, 1)] * self[(2, 2)] - self[(2, 1)] * self[(1, 2)])
105 - self[(0, 1)] * (self[(1, 0)] * self[(2, 2)] - self[(1, 2)] * self[(2, 0)])
106 + self[(0, 2)] * (self[(1, 0)] * self[(2, 1)] - self[(1, 1)] * self[(2, 0)])
107 }
108
109 #[inline(always)]
111 fn inverse(&self) -> Option<Self> {
112 let det = self.det();
113 if !nearly_zero(det) {
114 let invdet = det.recip();
115 let mut res = M33::zero();
116 res[(0, 0)] = (self[(1, 1)] * self[(2, 2)] - self[(2, 1)] * self[(1, 2)]) * invdet;
117 res[(0, 1)] = (self[(0, 2)] * self[(2, 1)] - self[(0, 1)] * self[(2, 2)]) * invdet;
118 res[(0, 2)] = (self[(0, 1)] * self[(1, 2)] - self[(0, 2)] * self[(1, 1)]) * invdet;
119 res[(1, 0)] = (self[(1, 2)] * self[(2, 0)] - self[(1, 0)] * self[(2, 2)]) * invdet;
120 res[(1, 1)] = (self[(0, 0)] * self[(2, 2)] - self[(0, 2)] * self[(2, 0)]) * invdet;
121 res[(1, 2)] = (self[(1, 0)] * self[(0, 2)] - self[(0, 0)] * self[(1, 2)]) * invdet;
122 res[(2, 0)] = (self[(1, 0)] * self[(2, 1)] - self[(2, 0)] * self[(1, 1)]) * invdet;
123 res[(2, 1)] = (self[(2, 0)] * self[(0, 1)] - self[(0, 0)] * self[(2, 1)]) * invdet;
124 res[(2, 2)] = (self[(0, 0)] * self[(1, 1)] - self[(1, 0)] * self[(0, 1)]) * invdet;
125 Some(res)
126 } else {
127 None
128 }
129 }
130
131 fn qr(&self) -> Option<(Self, Self)> {
134 if !nearly_zero(self.det()) {
135 let cols = self.get_cols();
136 let mut q: [V3<T>; 3] = *M33::zeros().get_cols();
137 for i in 0..q.len() {
138 let mut q_tilde = cols[i];
139 for elem in q.iter().take(i) {
140 q_tilde -= *elem * project_x_over_y(&*cols[i], &**elem);
141 }
142 normalize(&mut *q_tilde);
143 q[i] = q_tilde;
144 }
145 let basis = V3::new_from(q[0], q[1], q[2]);
146 let q = M33::new_from_vecs(basis);
147 let r = q.transpose() * (*self);
148 Some((q, r))
149 } else {
150 None
151 }
152 }
153}
154
155impl<T: Num + Copy> M33<T> {
156 pub fn identity() -> M33<T> {
158 <M33<T> as One>::one()
159 }
160
161 pub fn zeros() -> M33<T> {
163 <M33<T> as Zero>::zero()
164 }
165
166 pub fn as_vec(&self) -> [T; 9] {
168 let mut result = [T::zero(); 9];
169 for (index, element) in self.iter().flatten().enumerate() {
170 result[index] = *element;
171 }
172 result
173 }
174
175 pub fn new_from_vecs(cols: V3<V3<T>>) -> Self {
177 let mut result = Self::zeros();
178
179 for i in 0..result.cols() {
180 result[(i, 0)] = cols[0][i];
181 result[(i, 1)] = cols[1][i];
182 result[(i, 2)] = cols[2][i];
183 }
184 result
185 }
186
187 pub fn get_diagonal(&self) -> V3<T> {
189 let mut result = V3::zeros();
190 let mut index: usize = 0;
191 for i in 0..self.rows() {
192 for j in 0..self.cols() {
193 if i == j {
194 result[index] = self[(i, j)];
195 index += 1;
196 }
197 }
198 }
199 result
200 }
201
202 pub fn get_upper_triagular(&self) -> [T; 3] {
203 let zero = T::zero();
204 let mut result: [T; 3] = [zero, zero, zero];
205 let mut index = 0;
206 for i in 0..self.rows() {
207 for j in 0..self.cols() {
208 if i < j {
209 result[index] = self[(i, j)];
210 index += 1;
211 }
212 }
213 }
214 result
215 }
216
217 pub fn get_lower_triangular(&self) -> [T; 3] {
218 let zero = T::zero();
219 let mut result: [T; 3] = [zero, zero, zero];
220 let mut index = 0;
221 for i in 0..self.rows() {
222 for j in 0..self.cols() {
223 if i > j {
224 result[index] = self[(i, j)];
225 index += 1;
226 }
227 }
228 }
229 result
230 }
231
232
233 pub fn for_each(&self, f: impl Fn(T) -> T) -> Self {
235 let mut result = Self::zeros();
236 for i in 0..self.rows() {
237 for j in 0..self.cols() {
238 result[(i, j)] = f(self[(i, j)]);
239 }
240 }
241 result
242 }
243
244}
245
246impl<T: Num + Copy> M33<T> {
247
248 pub fn get_rows(self) -> V3<V3<T>> {
250 let mut r0 = V3::zeros();
251 let mut r1 = V3::zeros();
252 let mut r2 = V3::zeros();
253
254 for j in 0..self.rows() {
255 r0[j] = self[(0, j)];
256 r1[j] = self[(1, j)];
257 r2[j] = self[(2, j)];
258 }
259 V3::new([r0, r1, r2])
260 }
261
262 pub fn get_cols(self) -> V3<V3<T>> {
264 let mut c0 = V3::zeros();
265 let mut c1 = V3::zeros();
266 let mut c2 = V3::zeros();
267
268 for i in 0..self.rows() {
269 c0[i] = self[(i, 0)];
270 c1[i] = self[(i, 1)];
271 c2[i] = self[(i, 2)];
272 }
273 V3::new([c0, c1, c2])
274 }
275}
276
277impl<T: Num + Copy> Add for M33<T> {
278 type Output = Self;
279
280 #[inline(always)]
281 fn add(self, rhs: Self) -> Self {
282 M33::new([
283 [
284 self[(0, 0)] + rhs[(0, 0)],
285 self[(0, 1)] + rhs[(0, 1)],
286 self[(0, 2)] + rhs[(0, 2)],
287 ],
288 [
289 self[(1, 0)] + rhs[(1, 0)],
290 self[(1, 1)] + rhs[(1, 1)],
291 self[(1, 2)] + rhs[(1, 2)],
292 ],
293 [
294 self[(2, 0)] + rhs[(2, 0)],
295 self[(2, 1)] + rhs[(2, 1)],
296 self[(2, 2)] + rhs[(2, 2)],
297 ],
298 ])
299 }
300}
301
302impl<T: Num + Copy> AddAssign for M33<T> {
304 fn add_assign(&mut self, other: Self) {
305 *self = *self + other
306 }
307}
308
309impl<T: Num + Copy> Sub for M33<T> {
311 type Output = Self;
312
313 fn sub(self, rhs: Self) -> Self {
314 M33::new([
315 [
316 self[(0, 0)] - rhs[(0, 0)],
317 self[(0, 1)] - rhs[(0, 1)],
318 self[(0, 2)] - rhs[(0, 2)],
319 ],
320 [
321 self[(1, 0)] - rhs[(1, 0)],
322 self[(1, 1)] - rhs[(1, 1)],
323 self[(1, 2)] - rhs[(1, 2)],
324 ],
325 [
326 self[(2, 0)] - rhs[(2, 0)],
327 self[(2, 1)] - rhs[(2, 1)],
328 self[(2, 2)] - rhs[(2, 2)],
329 ],
330 ])
331 }
332}
333
334impl<T: Num + Copy> SubAssign for M33<T> {
336 fn sub_assign(&mut self, other: Self) {
337 *self = *self - other
338 }
339}
340
341impl<T: Num + Copy> Mul<V3<T>> for M33<T> {
343 type Output = V3<T>;
344
345 #[inline(always)]
346 fn mul(self, rhs: V3<T>) -> V3<T> {
347
348 let a_00 = self[(0, 0)];
349 let a_01 = self[(0, 1)];
350 let a_02 = self[(0, 2)];
351 let a_10 = self[(1, 0)];
352 let a_11 = self[(1, 1)];
353 let a_12 = self[(1, 2)];
354 let a_20 = self[(2, 0)];
355 let a_21 = self[(2, 1)];
356 let a_22 = self[(2, 2)];
357
358 let v0 = rhs[0];
359 let v1 = rhs[1];
360 let v2 = rhs[2];
361 V3::new([a_00 * v0 + a_01 * v1 + a_02 * v2,
362 a_10 * v0 + a_11 * v1 + a_12 * v2,
363 a_20 * v0 + a_21 * v1 + a_22 * v2])
364 }
365}
366
367impl<T: Num + Copy> Mul<T> for M33<T> {
369 type Output = M33<T>;
370
371 fn mul(self, rhs: T) -> Self::Output {
372 let a_00 = self[(0, 0)] * rhs;
373 let a_01 = self[(0, 1)] * rhs;
374 let a_02 = self[(0, 2)] * rhs;
375 let a_10 = self[(1, 0)] * rhs;
376 let a_11 = self[(1, 1)] * rhs;
377 let a_12 = self[(1, 2)] * rhs;
378 let a_20 = self[(2, 0)] * rhs;
379 let a_21 = self[(2, 1)] * rhs;
380 let a_22 = self[(2, 2)] * rhs;
381
382 M33::new([[a_00, a_01, a_02], [a_10, a_11, a_12], [a_20, a_21, a_22]])
383 }
384}
385
386impl<T: Num + Copy> Div<T> for M33<T> {
388 type Output = Self;
389
390 fn div(self, rhs: T) -> Self::Output {
391 let a_00 = self[(0, 0)] / rhs;
392 let a_01 = self[(0, 1)] / rhs;
393 let a_02 = self[(0, 2)] / rhs;
394 let a_10 = self[(1, 0)] / rhs;
395 let a_11 = self[(1, 1)] / rhs;
396 let a_12 = self[(1, 2)] / rhs;
397 let a_20 = self[(2, 0)] / rhs;
398 let a_21 = self[(2, 1)] / rhs;
399 let a_22 = self[(2, 2)] / rhs;
400
401 M33::new([[a_00, a_01, a_02], [a_10, a_11, a_12], [a_20, a_21, a_22]])
402 }
403}
404
405impl Mul<M33<f32>> for f32 {
407 type Output = M33<f32>;
408
409 fn mul(self, rhs: M33<f32>) -> Self::Output {
410 let a_00 = self * rhs[(0, 0)];
411 let a_01 = self * rhs[(0, 1)];
412 let a_02 = self * rhs[(0, 2)];
413 let a_10 = self * rhs[(1, 0)];
414 let a_11 = self * rhs[(1, 1)];
415 let a_12 = self * rhs[(1, 2)];
416 let a_20 = self * rhs[(2, 0)];
417 let a_21 = self * rhs[(2, 1)];
418 let a_22 = self * rhs[(2, 2)];
419
420 M33::new([[a_00, a_01, a_02], [a_10, a_11, a_12], [a_20, a_21, a_22]])
421 }
422}
423
424impl Mul<M33<f64>> for f64 {
426 type Output = M33<f64>;
427
428 fn mul(self, rhs: M33<f64>) -> Self::Output {
429 let a_00 = self * rhs[(0, 0)];
430 let a_01 = self * rhs[(0, 1)];
431 let a_02 = self * rhs[(0, 2)];
432 let a_10 = self * rhs[(1, 0)];
433 let a_11 = self * rhs[(1, 1)];
434 let a_12 = self * rhs[(1, 2)];
435 let a_20 = self * rhs[(2, 0)];
436 let a_21 = self * rhs[(2, 1)];
437 let a_22 = self * rhs[(2, 2)];
438
439 M33::new([[a_00, a_01, a_02], [a_10, a_11, a_12], [a_20, a_21, a_22]])
440 }
441}
442
443
444impl<T: Num + Copy> Mul for M33<T> {
446 type Output = Self;
447
448 #[inline]
449 fn mul(self, rhs: Self) -> Self {
450 let m00 =
451 self[(0, 0)] * rhs[(0, 0)] + self[(0, 1)] * rhs[(1, 0)] + self[(0, 2)] * rhs[(2, 0)];
452 let m01 =
453 self[(0, 0)] * rhs[(0, 1)] + self[(0, 1)] * rhs[(1, 1)] + self[(0, 2)] * rhs[(2, 1)];
454 let m02 =
455 self[(0, 0)] * rhs[(0, 2)] + self[(0, 1)] * rhs[(1, 2)] + self[(0, 2)] * rhs[(2, 2)];
456
457 let m10 =
458 self[(1, 0)] * rhs[(0, 0)] + self[(1, 1)] * rhs[(1, 0)] + self[(1, 2)] * rhs[(2, 0)];
459 let m11 =
460 self[(1, 0)] * rhs[(0, 1)] + self[(1, 1)] * rhs[(1, 1)] + self[(1, 2)] * rhs[(2, 1)];
461 let m12 =
462 self[(1, 0)] * rhs[(0, 2)] + self[(1, 1)] * rhs[(1, 2)] + self[(1, 2)] * rhs[(2, 2)];
463
464 let m20 =
465 self[(2, 0)] * rhs[(0, 0)] + self[(2, 1)] * rhs[(1, 0)] + self[(2, 2)] * rhs[(2, 0)];
466 let m21 =
467 self[(2, 0)] * rhs[(0, 1)] + self[(2, 1)] * rhs[(1, 1)] + self[(2, 2)] * rhs[(2, 1)];
468 let m22 =
469 self[(2, 0)] * rhs[(0, 2)] + self[(2, 1)] * rhs[(1, 2)] + self[(2, 2)] * rhs[(2, 2)];
470
471 M33::new([[m00, m01, m02], [m10, m11, m12], [m20, m21, m22]])
472 }
473}
474
475impl<T: Num + Copy + Signed> Neg for M33<T> {
477 type Output = Self;
478
479 fn neg(self) -> Self {
480 let a_00 = -self[(0, 0)];
481 let a_01 = -self[(0, 1)];
482 let a_02 = -self[(0, 2)];
483 let a_10 = -self[(1, 0)];
484 let a_11 = -self[(1, 1)];
485 let a_12 = -self[(1, 2)];
486 let a_20 = -self[(2, 0)];
487 let a_21 = -self[(2, 1)];
488 let a_22 = -self[(2, 2)];
489
490 M33::new([[a_00, a_01, a_02], [a_10, a_11, a_12], [a_20, a_21, a_22]])
491 }
492}
493
494impl<T: Num + Copy> Zero for M33<T> {
495 fn zero() -> M33<T> {
496 M33::new([[T::zero(); 3]; 3])
497 }
498
499 fn is_zero(&self) -> bool {
500 *self == M33::zero()
501 }
502}
503
504impl<T: Num + Copy> One for M33<T> {
505 fn one() -> M33<T> {
507 let one = T::one();
508 let zero = T::zero();
509 M33::new([[one, zero, zero], [zero, one, zero], [zero, zero, one]])
510 }
511}
512impl<T> Deref for M33<T> {
514 type Target = [[T; 3]; 3];
515 #[inline]
516 fn deref(&self) -> &Self::Target {
517 &self.0
518 }
519}
520
521impl<T> DerefMut for M33<T> {
522 #[inline]
523 fn deref_mut(&mut self) -> &mut Self::Target {
524 &mut self.0
525 }
526}
527
528impl<T> From<[[T; 3]; 3]> for M33<T> {
529 fn from(data: [[T; 3]; 3]) -> M33<T> {
530 M33(data)
531 }
532}
533
534impl<T> Index<(usize, usize)> for M33<T> {
535 type Output = T;
536 #[inline(always)]
537 fn index(&self, index: (usize, usize)) -> &T {
538 &self.0[index.0][index.1]
539 }
540}
541
542impl<T> IndexMut<(usize, usize)> for M33<T> {
543 #[inline(always)]
544 fn index_mut(&mut self, index: (usize, usize)) -> &mut T {
545 &mut self.0[index.0][index.1]
546 }
547}
548
549impl<T: Num + fmt::Display> fmt::Display for M33<T> {
553 fn fmt(&self, dest: &mut fmt::Formatter) -> fmt::Result {
554 println!();
555 writeln!(
556 dest,
557 "|{0:<7.2} {1:^7.2} {2:>7.2}|",
558 self[(0, 0)],
559 self[(0, 1)],
560 self[(0, 2)]
561 )?;
562 writeln!(
563 dest,
564 "|{0:<7.2} {1:^7.2} {2:>7.2}|",
565 self[(1, 0)],
566 self[(1, 1)],
567 self[(1, 2)]
568 )?;
569 writeln!(
570 dest,
571 "|{0:<7.2} {1:^7.2} {2:>7.2}|",
572 self[(2, 0)],
573 self[(2, 1)],
574 self[(2, 2)]
575 )
576 }
577}
578
579#[macro_export]
583macro_rules! m33_new {
584 ($($first_row:expr),*;
585 $($second_row:expr),*;
586 $($third_row:expr),*
587 ) => {
588 M33::new([[$($first_row),*], [$($second_row),*], [$($third_row),*]])
589 }
590}
591
592#[cfg(test)]
597mod test_matrix3x3 {
598 use crate::traits::LinearAlgebra;
599 use crate::matrix3x3::M33;
600 use crate::utils::nearly_equal;
601 use crate::utils::compare_vecs;
602 use crate::vector3::*;
603
604 const EPS: f32 = 1e-8;
605
606 #[test]
607 fn create_matrix() {
608 let matrix = M33::new([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]]);
609 assert_eq!(matrix[(0, 0)], 0.0);
610 assert_eq!(matrix[(0, 1)], 1.0);
611 assert_eq!(matrix[(0, 2)], 2.0);
612 assert_eq!(matrix[(1, 0)], 3.0);
613 assert_eq!(matrix[(1, 1)], 4.0);
614 assert_eq!(matrix[(1, 2)], 5.0);
615 assert_eq!(matrix[(2, 0)], 6.0);
616 assert_eq!(matrix[(2, 1)], 7.0);
617 assert_eq!(matrix[(2, 2)], 8.0);
618 }
619
620 #[test]
621 fn trace_test() {
622 let matrix = M33::new([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]]);
623 assert_eq!(matrix.trace(), 12.0);
624 }
625
626 #[test]
627 fn add_matrix() {
628 use super::test_matrix3x3::EPS;
629 let m1 = M33::new([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]]);
630
631 let m2 = M33::new([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]]);
632
633 let expected = M33::new([[0.0, 2.0, 4.0], [6.0, 8.0, 10.0], [12.0, 14.0, 16.0]]);
634 let result = m1 + m2;
635 assert!(compare_vecs(&result.as_vec(), &expected.as_vec(), EPS));
636 }
637
638 #[test]
639 fn sub_test() {
640 use super::test_matrix3x3::EPS;
641 let m1 = m33_new!(0.0, 1.0, 2.0;
642 3.0, 4.0, 5.0;
643 6.0, 7.0, 8.0);
644
645 let m2 = m33_new!(0.0, 1.0, 2.0;
646 3.0, 4.0, 5.0;
647 6.0, 7.0, 8.0);
648
649 let expected = m33_new!(0.0, 0.0, 0.0;
650 0.0, 0.0, 0.0;
651 0.0, 0.0, 0.0);
652
653 let result = m1 - m2;
654 assert!(compare_vecs(&result.as_vec(), &expected.as_vec(), EPS));
655 }
656
657 #[test]
658 fn test_identity_creation() {
659 use super::test_matrix3x3::EPS;
660 let identity: M33<f32> = M33::identity();
661
662 let expected = M33::new([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]);
663 assert!(compare_vecs(&identity.as_vec(), &expected.as_vec(), EPS));
664 }
665
666 #[test]
667 fn test_zeros_creation() {
668 use super::test_matrix3x3::EPS;
669 let zero: M33<f32> = M33::zeros();
670
671 let expected = M33::new([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]);
672 assert!(compare_vecs(&zero.as_vec(), &expected.as_vec(), EPS));
673 }
674
675 #[test]
676 fn test_trace() {
677 let m: M33<f32> = M33::identity();
678 assert_eq!(m.trace(), 3.0);
679 }
680
681 #[test]
682 fn test_norm2() {
683 use super::test_matrix3x3::EPS;
684 let m = M33::new([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]]);
685 assert!(nearly_equal(m.norm2(), 14.2828568570857, EPS));
686 }
687
688 #[test]
689 fn determinant_test() {
690 let m = M33::new([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 9.0]]);
691 let expected = -3.0;
692 let result = m.det();
693
694 assert!(nearly_equal(result, expected, EPS));
695 }
696
697 #[test]
698 fn inverse_test() {
699 use super::test_matrix3x3::EPS;
700 let m = M33::new([[1.0, 0.0, 3.0], [2.0, 1.0, 6.0], [1.0, 0.0, 9.0]]);
701 let expected = M33::new([
703 [1.5, 0.0, -0.5],
704 [-2.0, 1.0, 0.0],
705 [-0.16666666666666666, 0.0, 0.16666666666666666],
706 ]);
707
708 if let Some(result) = m.inverse() {
709 assert!(compare_vecs(&result.as_vec(), &expected.as_vec(), EPS));
710 }
711 }
712
713 #[test]
714 fn inverse_fail() {
715 let m = M33::new([[1.0, 0.0, 3.0], [1.0, 0.0, 3.0], [10.0, 0.0, 3.0]]);
716 let result = m.inverse();
717 let expected = None;
718 assert_eq!(result, expected);
719 }
720
721 #[test]
722 fn test_mul_m33_v3() {
723 let m = M33::new([[1.0, 1.0, 1.0],
724 [3.0, 2.0, 1.0],
725 [7.0, 3.0, 3.0],]);
726 let v = V3::new([2.0, 7.0, 6.0]);
727 let result = m * v;
728 let expected = V3::new([15.0, 26.0, 53.0]);
729 assert_eq!(
730 &result[..],
731 &expected[..],
732 "\nExpected\n{:?}\nfound\n{:?}",
733 &result[..],
734 &expected[..]
735 );
736 }
737
738 #[test]
739 fn get_columns_test() {
740 let m = m33_new!(0.0, 1.0, 2.0;
741 3.0, 4.0, 5.0;
742 6.0, 7.0, 8.0);
743
744 let result = m.get_cols();
745
746 let expected0 = V3::new([0.0, 3.0, 6.0]);
747 let expected1 = V3::new([1.0, 4.0, 7.0]);
748 let expected2 = V3::new([2.0, 5.0, 8.0]);
749
750 let expected = V3::new([expected0, expected1, expected2]);
751 assert_eq!(
752 &result[..],
753 &expected[..],
754 "\nExpected\n{:?}\nfound\n{:?}",
755 &result[..],
756 &expected[..]
757 );
758 }
759
760 #[test]
761 fn get_rows_test() {
762 let m = m33_new!(0.0, 1.0, 2.0;
763 3.0, 4.0, 5.0;
764 6.0, 7.0, 8.0);
765
766 let result = m.get_rows();
767
768 let expected0 = V3::new([0.0, 1.0, 2.0]);
769 let expected1 = V3::new([3.0, 4.0, 5.0]);
770 let expected2 = V3::new([6.0, 7.0, 8.0]);
771
772 let expected = V3::new([expected0, expected1, expected2]);
773
774 assert_eq!(
775 &result[..],
776 &expected[..],
777 "\nExpected\n{:?}\nfound\n{:?}",
778 &result[..],
779 &expected[..]
780 );
781 }
782
783 #[test]
784 fn new_from_vecs_test() {
785 let expected = m33_new!(0.0, 1.0, 2.0;
786 3.0, 4.0, 5.0;
787 6.0, 7.0, 8.0);
788
789 let cols = expected.get_cols();
790
791 let result = M33::new_from_vecs(cols);
792
793 assert!(compare_vecs(&result.as_vec(), &expected.as_vec(), EPS));
794 }
795
796 #[test]
797 fn qr_test() {
798 let expected = m33_new!(0.0, 1.0, 2.0;
799 3.0, 4.0, 5.0;
800 6.0, 7.0, 8.0);
801 if let Some((q, r)) = expected.qr() {
802 let result = q * r;
803 assert!(compare_vecs(&result.as_vec(), &expected.as_vec(), EPS));
804 assert!(nearly_equal(q.det().abs(), 1.0, EPS));
805 }
806 }
807
808 #[test]
809 fn get_diagonal() {
810 let m = m33_new!(0.0, 1.0, 2.0;
811 3.0, 4.0, 5.0;
812 6.0, 7.0, 8.0);
813 let result = m.get_diagonal();
814 let expected = V3::new([0.0, 4.0, 8.0]);
815 assert_eq!(
816 &result[..],
817 &expected[..],
818 "\nExpected\n{:?}\nfound\n{:?}",
819 &result[..],
820 &expected[..]
821 );
822 }
823
824 #[test]
825 fn get_upper_triangular_test() {
826 let m = m33_new!(0.0, 1.0, 2.0;
827 3.0, 4.0, 5.0;
828 6.0, 7.0, 8.0);
829 let result = m.get_upper_triagular();
830 let expected = [1.0, 2.0, 5.0];
831 assert_eq!(
832 &result[..],
833 &expected[..],
834 "\nExpected\n{:?}\nfound\n{:?}",
835 &result[..],
836 &expected[..]
837 );
838 }
839
840 #[test]
841 fn get_lower_triangular_test() {
842 let m = m33_new!(0.0, 1.0, 2.0;
843 3.0, 4.0, 5.0;
844 6.0, 7.0, 8.0);
845 let result = m.get_lower_triangular();
846 let expected = [3.0, 6.0, 7.0];
847 assert_eq!(
848 &result[..],
849 &expected[..],
850 "\nExpected\n{:?}\nfound\n{:?}",
851 &result[..],
852 &expected[..]
853 );
854 }
855
856 #[test]
857 fn for_each_test() {
858 let m = m33_new!(0.0, 1.0, 2.0;
859 3.0, 4.0, 5.0;
860 6.0, 7.0, 8.0);
861 let result = m.for_each(|element| element + 1.0);
862 let expected = m33_new!(1.0, 2.0, 3.0;
863 4.0, 5.0, 6.0;
864 7.0, 8.0, 9.0);
865 assert!(compare_vecs(&result.as_vec(), &expected.as_vec(), EPS));
866 }
867
868}