1mod errors;
2
3extern crate num;
4
5pub use errors::{IndexError, InversionError, MinorError, SizingError};
6use num::{One, Zero};
7use std::{
8 fmt::Debug,
9 ops::{Add, AddAssign, Div, Index, IndexMut, Mul, Neg, Sub, SubAssign},
10};
11
12#[derive(Clone, PartialEq, Eq)]
13pub struct Matrix<T>
14where
15 T: Copy,
16{
17 data: Vec<T>,
18 rows: usize,
19 columns: usize,
20}
21
22impl<T> Matrix<T>
24where
25 T: Copy,
26{
27 pub fn empty() -> Self {
28 return Matrix {
29 data: vec![],
30 rows: 0,
31 columns: 0,
32 };
33 }
34
35 pub fn new(rows: usize, columns: usize) -> Result<Self, SizingError>
41 where
42 T: Zero,
43 {
44 if rows == 0 && columns != 0 {
45 return Err(SizingError::Row(0));
46 }
47
48 if columns == 0 && rows != 0 {
49 return Err(SizingError::Column(0));
50 }
51
52 Ok(Self {
53 data: vec![T::zero(); rows * columns],
54 rows,
55 columns,
56 })
57 }
58
59 pub fn new_identity(n: usize) -> Self
63 where
64 T: Zero + One,
65 {
66 Self {
67 data: (0..n.pow(2))
68 .map(|i| {
69 if i % (n + 1) == 0 {
70 T::one()
71 } else {
72 T::zero()
73 }
74 })
75 .collect(),
76 rows: n,
77 columns: n,
78 }
79 }
80
81 pub fn new_with_data(columns: usize, data: Vec<T>) -> Result<Self, SizingError> {
87 let len = data.len();
88
89 if len == 0 && columns == 0 {
90 return Ok(Matrix::empty());
91 }
92
93 if len == 0 {
94 return Err(SizingError::Row(0));
95 }
96
97 if columns == 0 {
98 return Err(SizingError::Column(0));
99 }
100
101 if len % columns != 0 {
102 return Err(SizingError::Row(len % columns));
103 }
104
105 Ok(Self {
106 data,
107 rows: len / columns,
108 columns,
109 })
110 }
111
112 pub fn new_from_data(data: &[Vec<T>]) -> Result<Self, usize> {
118 let rows = data.len();
119
120 if rows == 0 {
121 return Ok(Matrix::empty());
122 }
123
124 let columns = data[0].len();
125
126 if columns == 0 {
127 return Err(0);
128 }
129
130 let mut elements: Vec<T> = Vec::with_capacity(rows * columns);
131
132 for row in 0..rows {
133 if data[row].len() != columns {
134 return Err(row);
135 }
136
137 for e in &data[row] {
138 elements.push(*e);
139 }
140 }
141
142 Ok(Self {
143 data: elements,
144 rows,
145 columns,
146 })
147 }
148}
149
150impl<T> Matrix<T>
152where
153 T: Copy,
154{
155 pub fn data(&self) -> &[T] {
157 &self.data
158 }
159
160 pub fn rows(&self) -> usize {
162 self.rows
163 }
164
165 pub fn columns(&self) -> usize {
167 self.columns
168 }
169
170 pub fn size(&self) -> usize {
172 self.data.len()
173 }
174
175 pub fn is_square(&self) -> bool {
177 self.rows == self.columns && self.rows != 0
178 }
179
180 pub fn get_row(&self, index: usize) -> Option<Vec<&T>> {
186 if index >= self.rows {
187 return None;
188 }
189
190 Some((0..self.columns).map(|c| &self[(index, c)]).collect())
191 }
192
193 pub fn get_rows(&self, rows: impl Iterator<Item = usize>) -> Option<Vec<Vec<&T>>> {
199 rows.map(|r| self.get_row(r)).collect::<Option<Vec<_>>>()
200 }
201
202 pub fn get_column(&self, index: usize) -> Option<Vec<&T>> {
208 if index >= self.columns {
209 return None;
210 }
211
212 Some((0..self.rows).map(|r| &self[(r, index)]).collect())
213 }
214
215 pub fn get_columns(&self, columns: impl Iterator<Item = usize>) -> Option<Vec<Vec<&T>>> {
221 columns
222 .map(|c| self.get_column(c))
223 .collect::<Option<Vec<Vec<&T>>>>()
224 }
225}
226
227impl<T> Matrix<T>
229where
230 T: Copy,
231{
232 pub fn data_mut(&mut self) -> &mut [T] {
234 &mut self.data
235 }
236
237 pub fn get_mut_row(&mut self, index: usize) -> Option<Vec<&mut T>> {
243 if index >= self.rows {
244 return None;
245 }
246
247 Some(
248 self.data[(index * self.columns)..((index + 1) * self.columns)]
249 .iter_mut()
250 .collect(),
251 )
252 }
253
254 pub fn get_mut_column(&mut self, index: usize) -> Option<Vec<&mut T>> {
260 if index >= self.columns {
261 return None;
262 }
263
264 Some(
265 self.data
266 .iter_mut()
267 .skip(index)
268 .step_by(self.columns)
269 .collect(),
270 )
271 }
272}
273
274impl<T> Matrix<T>
276where
277 T: Copy + 'static,
278{
279 pub fn swap_elements(
285 &mut self,
286 el1: (usize, usize),
287 el2: (usize, usize),
288 ) -> Option<IndexError> {
289 if el1.0 >= self.rows && el1.1 >= self.columns {
290 return Some(IndexError::Both(el1.0, el1.1));
291 }
292
293 if el1.0 >= self.rows {
294 return Some(IndexError::Row(el1.0));
295 }
296
297 if el1.1 >= self.columns {
298 return Some(IndexError::Column(el1.1));
299 }
300
301 if el2.0 >= self.rows && el2.1 >= self.columns {
302 return Some(IndexError::Both(el2.0, el2.1));
303 }
304
305 if el2.0 >= self.rows {
306 return Some(IndexError::Row(el2.0));
307 }
308
309 if el2.1 >= self.columns {
310 return Some(IndexError::Column(el2.1));
311 }
312
313 let temp = self[el1];
314 self[el1] = self[el2];
315 self[el2] = temp;
316
317 None
318 }
319
320 pub fn swap_rows(&mut self, row1: usize, row2: usize) -> Option<usize> {
326 let first_clone = match self.get_row(row1) {
327 Some(t) => t,
328 None => return Some(row1),
329 }
330 .iter()
331 .map(|&e| *e)
332 .collect::<Vec<_>>();
333
334 let second_clone = match self.get_row(row2) {
335 Some(t) => t,
336 None => return Some(row2),
337 }
338 .iter()
339 .map(|&e| *e)
340 .collect::<Vec<_>>();
341
342 let cols = self.columns;
343
344 let mut first = self.get_mut_row(row1).unwrap();
345
346 for i in 0..cols {
347 *first[i] = second_clone[i];
348 }
349
350 let mut second = self.get_mut_row(row2).unwrap();
351
352 for i in 0..cols {
353 *second[i] = first_clone[i];
354 }
355
356 None
357 }
358
359 pub fn swap_columns(&mut self, col1: usize, col2: usize) -> Option<IndexError> {
365 let first_clone = match self.get_column(col1) {
366 Some(t) => t,
367 None => return Some(IndexError::Column(col1)),
368 }
369 .iter()
370 .map(|&e| *e)
371 .collect::<Vec<_>>();
372
373 let second_clone = match self.get_column(col2) {
374 Some(t) => t,
375 None => return Some(IndexError::Column(col2)),
376 }
377 .iter()
378 .map(|&e| *e)
379 .collect::<Vec<_>>();
380
381 let rows = self.rows;
382
383 let mut first = self.get_mut_column(col1).unwrap();
384
385 for i in 0..rows {
386 *first[i] = second_clone[i];
387 }
388
389 let mut second = self.get_mut_column(col2).unwrap();
390
391 for i in 0..rows {
392 *second[i] = first_clone[i];
393 }
394
395 None
396 }
397}
398
399impl<T> Matrix<T>
401where
402 T: Copy,
403{
404 pub fn scale(&mut self, factor: T)
406 where
407 T: Mul<Output = T>,
408 {
409 for e in self.data.iter_mut() {
410 *e = *e * factor
411 }
412 }
413
414 pub fn scale_row(&mut self, row: usize, factor: T) -> Option<usize>
420 where
421 T: Mul<Output = T>,
422 {
423 for t in match self.get_mut_row(row) {
424 Some(t) => t,
425 None => return Some(row),
426 } {
427 *t = *t * factor;
428 }
429
430 None
431 }
432
433 pub fn add_scaled_row(&mut self, source: usize, target: usize, factor: T) -> Option<usize>
439 where
440 T: Add<Output = T> + Mul<Output = T>,
441 {
442 let source_clone = match self.get_row(source) {
443 Some(t) => t,
444 None => return Some(source),
445 }
446 .iter()
447 .map(|&e| *e)
448 .collect::<Vec<_>>();
449
450 let cols = self.columns;
451
452 let mut target = match self.get_mut_row(target) {
453 Some(t) => t,
454 None => return Some(target),
455 };
456
457 for i in 0..cols {
458 *target[i] = *target[i] + (source_clone[i] * factor);
459 }
460
461 None
462 }
463
464 pub fn scale_column(&mut self, column: usize, factor: T) -> Option<usize>
470 where
471 T: Mul<Output = T>,
472 {
473 for t in match self.get_mut_column(column) {
474 Some(t) => t,
475 None => return Some(column),
476 } {
477 *t = *t * factor
478 }
479
480 None
481 }
482
483 pub fn add_scaled_column(&mut self, source: usize, target: usize, factor: T) -> Option<usize>
489 where
490 T: Add<Output = T> + Mul<Output = T>,
491 {
492 let source_clone = match self.get_column(source) {
493 Some(t) => t,
494 None => return Some(source),
495 }
496 .iter()
497 .map(|&e| *e)
498 .collect::<Vec<_>>();
499
500 let rows = self.rows;
501
502 let mut target = match self.get_mut_column(target) {
503 Some(t) => t,
504 None => return Some(target),
505 };
506
507 for i in 0..rows {
508 *target[i] = *target[i] + (source_clone[i] * factor);
509 }
510
511 None
512 }
513
514 pub fn resize(&mut self, bounds: (usize, usize)) -> Option<IndexError> {
520 if bounds.0 == 0 && bounds.1 != 0 {
521 return Some(IndexError::Row(0));
522 }
523
524 if bounds.1 == 0 && bounds.0 != 0 {
525 return Some(IndexError::Column(0));
526 }
527
528 if bounds.0 * bounds.1 != self.size() {
529 return Some(IndexError::Both(bounds.0, bounds.1));
530 }
531
532 self.rows = bounds.0;
533 self.columns = bounds.1;
534 None
535 }
536
537 pub fn remove_row(&mut self, row: usize) -> Option<usize> {
543 if row >= self.rows {
544 return Some(row);
545 }
546
547 self.data
548 .drain((row * self.columns)..((row + 1) * self.columns));
549 self.rows -= 1;
550
551 if self.rows == 0 {
552 self.columns = 0;
553 }
554
555 None
556 }
557
558 pub fn remove_column(&mut self, column: usize) -> Option<usize> {
564 if column >= self.columns {
565 return Some(column);
566 }
567
568 self.columns -= 1;
569 for r in 0..self.rows {
570 self.data.remove(r * self.columns + column);
571 }
572
573 if self.rows == 0 {
574 self.columns = 0;
575 }
576
577 None
578 }
579
580 pub fn insert_row(&mut self, row: usize, data: &[T]) -> Option<IndexError> {
586 let len = data.len();
587
588 if row > self.rows && len != self.columns && self.columns != 0 {
589 return Some(IndexError::Both(row, len));
590 }
591
592 if row > self.rows {
593 return Some(IndexError::Row(row));
594 }
595
596 if len != self.columns && self.columns != 0 {
597 return Some(IndexError::Column(len));
598 }
599
600 self.rows += 1;
601 for (col, e) in data.iter().enumerate() {
602 self.data.insert((row * self.columns) + col, *e);
603 }
604
605 if self.columns == 0 {
606 self.columns = data.len();
607 }
608
609 None
610 }
611
612 pub fn insert_column(&mut self, column: usize, data: &[T]) -> Option<IndexError> {
618 let len = data.len();
619
620 if column > self.columns && len != self.rows && self.rows != 0 {
621 return Some(IndexError::Both(len, column));
622 }
623
624 if column > self.columns {
625 return Some(IndexError::Column(column));
626 }
627
628 if len != self.rows && self.rows != 0 {
629 return Some(IndexError::Row(len));
630 }
631
632 self.columns += 1;
633 for (row, e) in data.iter().enumerate() {
634 self.data.insert(row * self.columns + column, *e);
635 }
636
637 if self.rows == 0 {
638 self.rows = data.len();
639 }
640
641 None
642 }
643
644 pub fn join_matrix_below(&mut self, other: &Matrix<T>) -> Option<usize> {
650 if other.columns != self.columns && self.columns != 0 {
651 return Some(other.columns);
652 }
653
654 self.rows += other.rows;
655 self.data.append(&mut other.data.clone());
656
657 if self.columns == 0 {
658 self.columns = other.columns;
659 }
660
661 None
662 }
663
664 pub fn join_matrix_above(&mut self, other: &Matrix<T>) -> Option<usize> {
670 if other.columns != self.columns && self.columns != 0 {
671 return Some(other.columns);
672 }
673
674 self.rows += other.rows;
675 let mut clone = other.data.clone();
676 clone.append(&mut self.data);
677 self.data = clone;
678
679 if self.columns == 0 {
680 self.columns = other.columns;
681 }
682
683 None
684 }
685
686 pub fn join_matrix_left(&mut self, other: &Matrix<T>) -> Option<usize> {
692 if other.rows != self.rows && self.rows != 0 {
693 return Some(other.rows);
694 }
695
696 self.columns += other.columns;
697 for (row, chunk) in other.data.chunks(other.columns).enumerate() {
698 for (col, el) in chunk.iter().enumerate() {
699 self.data.insert(row * self.columns + col, *el);
700 }
701 }
702
703 if self.rows == 0 {
704 self.rows = other.rows;
705 }
706
707 None
708 }
709
710 pub fn join_matrix_right(&mut self, other: &Matrix<T>) -> Option<usize> {
716 if other.rows != self.rows && self.rows != 0 {
717 return Some(other.rows);
718 }
719
720 for (row, chunk) in other.data.chunks(other.columns).enumerate() {
721 let r = row + 1;
722 for (col, el) in chunk.iter().enumerate() {
723 self.data
724 .insert(r * self.columns + row * other.columns + col, *el);
725 }
726 }
727 self.columns += other.columns;
728
729 if self.rows == 0 {
730 self.rows = other.rows;
731 }
732
733 None
734 }
735}
736
737impl<T> Matrix<T>
739where
740 T: Copy,
741{
742 pub fn transpose(&self) -> Self {
744 let mut elements: Vec<T> = vec![];
745
746 for c in self.get_columns(0..self.columns).unwrap() {
747 elements.append(&mut c.iter().map(|e| **e).collect());
748 }
749
750 Matrix {
751 data: elements,
752 rows: self.columns,
753 columns: self.rows,
754 }
755 }
756
757 pub fn minor(&self, element: (usize, usize)) -> Result<T, MinorError>
765 where
766 T: Mul<Output = T> + Sub<Output = T> + Zero,
767 {
768 if !self.is_square() {
769 return Err(MinorError::NotSquare);
770 }
771
772 if element.0 >= self.rows && element.1 >= self.columns {
773 return Err(IndexError::Both(element.0, element.1).into());
774 }
775
776 if element.0 >= self.rows {
777 return Err(IndexError::Row(element.0).into());
778 }
779
780 if element.1 >= self.columns {
781 return Err(IndexError::Column(element.1).into());
782 }
783
784 let mut copy = self.clone();
785
786 copy.remove_row(element.0);
787 copy.remove_column(element.1);
788
789 Ok(copy.determinant().unwrap())
790 }
791
792 pub fn minor_matrix(&self) -> Option<Self>
798 where
799 T: Mul<Output = T> + Sub<Output = T> + Zero,
800 {
801 if !self.is_square() {
802 return None;
803 }
804
805 Matrix::new_with_data(
806 self.columns,
807 (0..self.size())
808 .map(|n| {
809 self.minor(((n / self.columns), (n % self.columns)))
810 .unwrap()
811 })
812 .collect(),
813 )
814 .ok()
815 }
816
817 pub fn cofactor(&self) -> Option<Self>
821 where
822 T: Neg<Output = T> + Mul<Output = T> + Sub<Output = T> + Zero,
823 {
824 let mut out = self.minor_matrix()?;
825
826 for (n, e) in out.data.iter_mut().enumerate() {
827 if (n / self.columns + n % self.columns) % 2 == 1 {
828 *e = e.neg();
829 }
830 }
831
832 Some(out)
833 }
834
835 pub fn adjunct(&self) -> Option<Self>
841 where
842 T: Neg<Output = T> + Mul<Output = T> + Sub<Output = T> + Zero,
843 {
844 Some(self.cofactor()?.transpose())
845 }
846
847 pub fn determinant(&self) -> Option<T>
853 where
854 T: Mul<Output = T> + Zero + Sub<Output = T>,
855 {
856 if !self.is_square() {
857 return None;
858 }
859
860 if self.rows == 1 {
861 return Some(self.data[0]);
862 }
863
864 Some(
865 self.get_row(0)
866 .unwrap()
867 .iter()
868 .enumerate()
869 .fold(T::zero(), |res, (c, e)| {
870 let det = **e * self.minor((0, c)).unwrap();
871 if c % 2 == 0 {
872 res + det
873 } else {
874 res - det
875 }
876 }),
877 )
878 }
879
880 pub fn inverse(&self) -> Result<Self, InversionError>
890 where
891 T: Sub<Output = T>
892 + Mul<Output = T>
893 + Div<Output = T>
894 + Neg<Output = T>
895 + Zero
896 + One
897 + PartialEq,
898 {
899 let det = self.determinant().ok_or(InversionError::NotSquare)?;
900
901 if det == T::zero() {
902 return Err(InversionError::InvalidDeterminant);
903 }
904
905 let mut out = self.adjunct().unwrap();
906 out.scale(T::one() / det);
907
908 Ok(out)
909 }
910
911 pub fn fast_inverse(&self) -> Result<Self, InversionError>
921 where
922 T: Copy + Zero + One + Div<Output = T> + Neg<Output = T> + PartialEq,
923 {
924 if !self.is_square() {
925 return Err(InversionError::NotSquare);
926 }
927
928 let mut clone = self.clone();
929 let mut out = Matrix::new_identity(clone.rows);
930
931 for c in 0..clone.rows {
932 if !T::is_one(&clone[(c, c)]) {
933 if T::is_zero(&clone[(c, c)]) {
934 return Err(InversionError::InvalidDeterminant);
935 }
936 let factor = T::one() / clone[(c, c)];
937 clone.scale_row(c, factor);
938 out.scale_row(c, factor);
939 }
940
941 for r in 0..c {
942 if !T::is_zero(&clone[(r, c)]) {
943 let factor = clone[(r, c)].neg();
944 clone.add_scaled_row(c, r, factor);
945 out.add_scaled_row(c, r, factor);
946 }
947 }
948
949 for r in (c + 1)..clone.rows {
950 if !T::is_zero(&clone[(r, c)]) {
951 let factor = clone[(r, c)].neg();
952 clone.add_scaled_row(c, r, factor);
953 out.add_scaled_row(c, r, factor);
954 }
955 }
956 }
957
958 Ok(out)
959 }
960
961 pub fn as_resize(&self, bounds: (usize, usize)) -> Result<Matrix<T>, IndexError> {
967 if bounds.0 == 0 {
968 return Err(IndexError::Row(0));
969 }
970
971 if bounds.1 == 0 {
972 return Err(IndexError::Column(0));
973 }
974
975 if bounds.0 * bounds.1 != self.size() {
976 return Err(IndexError::Both(bounds.0, bounds.1));
977 }
978
979 Ok(Matrix {
980 data: self.data.clone(),
981 rows: bounds.0,
982 columns: bounds.1,
983 })
984 }
985}
986
987impl<T> Debug for Matrix<T>
988where
989 T: Copy + Debug,
990{
991 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
992 if self.rows <= 1 {
993 return write!(f, "{:?}", self.data);
994 }
995
996 writeln!(f, "{:?}", self.get_row(0).unwrap())?;
997 let middle = self.get_rows(1..(self.rows - 1)).unwrap();
998 for row in middle {
999 writeln!(f, "{:?}", row)?;
1000 }
1001 write!(f, "{:?}", self.get_row(self.rows - 1).unwrap())
1002 }
1003}
1004
1005impl<T> Index<(usize, usize)> for Matrix<T>
1006where
1007 T: Copy,
1008{
1009 type Output = T;
1010
1011 fn index(&self, index: (usize, usize)) -> &Self::Output {
1012 assert!(
1013 index.0 < self.rows && index.1 < self.columns,
1014 "Index out of bounds. index: {:?}, matrix bounds: {:?}",
1015 index,
1016 (self.rows, self.columns)
1017 );
1018
1019 &self.data[index.0 * self.columns + index.1]
1020 }
1021}
1022
1023impl<T> IndexMut<(usize, usize)> for Matrix<T>
1024where
1025 T: Copy,
1026{
1027 fn index_mut(&mut self, index: (usize, usize)) -> &mut Self::Output {
1028 assert!(
1029 index.0 < self.rows && index.1 < self.columns,
1030 "Index out of bounds. index: {:?}, matrix bounds: {:?}",
1031 index,
1032 (self.rows, self.columns)
1033 );
1034
1035 &mut self.data[index.0 * self.columns + index.1]
1036 }
1037}
1038
1039impl<T> AddAssign for Matrix<T>
1040where
1041 T: Add<Output = T> + Copy,
1042{
1043 fn add_assign(&mut self, rhs: Self) {
1047 assert_eq!(self.rows, rhs.rows, "Mismatched rows.");
1048 assert_eq!(self.columns, rhs.columns, "Mismatched columns");
1049
1050 for (s, o) in self.data.iter_mut().zip(rhs.data.iter()) {
1051 *s = *s + *o
1052 }
1053 }
1054}
1055
1056impl<T, U> Add for Matrix<T>
1057where
1058 T: Add<Output = U> + Copy,
1059 U: Copy,
1060{
1061 type Output = Result<Matrix<U>, SizingError>;
1062
1063 fn add(self, rhs: Self) -> Self::Output {
1064 if self.rows != rhs.rows && self.columns != rhs.columns {
1065 return Err(SizingError::Both(rhs.rows, rhs.columns));
1066 }
1067
1068 if self.rows != rhs.rows {
1069 return Err(SizingError::Row(rhs.rows));
1070 }
1071
1072 if self.columns != rhs.columns {
1073 return Err(SizingError::Column(rhs.columns));
1074 }
1075
1076 Ok(Matrix {
1077 data: self
1078 .data
1079 .iter()
1080 .zip(rhs.data.iter())
1081 .map(|(s, r)| *s + *r)
1082 .collect(),
1083 rows: self.rows,
1084 columns: self.columns,
1085 })
1086 }
1087}
1088
1089impl<T, U> Add for &Matrix<T>
1090where
1091 T: Add<Output = U> + Copy,
1092 U: Copy,
1093{
1094 type Output = Result<Matrix<U>, SizingError>;
1095
1096 fn add(self, rhs: Self) -> Self::Output {
1097 if self.rows != rhs.rows && self.columns != rhs.columns {
1098 return Err(SizingError::Both(rhs.rows, rhs.columns));
1099 }
1100
1101 if self.rows != rhs.rows {
1102 return Err(SizingError::Row(rhs.rows));
1103 }
1104
1105 if self.columns != rhs.columns {
1106 return Err(SizingError::Column(rhs.columns));
1107 }
1108
1109 Ok(Matrix {
1110 data: self
1111 .data
1112 .iter()
1113 .zip(rhs.data.iter())
1114 .map(|(s, r)| *s + *r)
1115 .collect(),
1116 rows: self.rows,
1117 columns: self.columns,
1118 })
1119 }
1120}
1121
1122impl<T> SubAssign for Matrix<T>
1123where
1124 T: Sub<Output = T> + Copy,
1125{
1126 fn sub_assign(&mut self, rhs: Self) {
1127 assert!(self.rows == rhs.rows, "Mismatched rows");
1128 assert!(self.columns == rhs.columns, "Mismatched columns");
1129
1130 for (s, o) in self.data.iter_mut().zip(rhs.data.iter()) {
1131 *s = *s - *o
1132 }
1133 }
1134}
1135
1136impl<T, U> Sub for Matrix<T>
1137where
1138 T: Sub<Output = U> + Copy,
1139 U: Copy,
1140{
1141 type Output = Result<Matrix<U>, SizingError>;
1142
1143 fn sub(self, rhs: Self) -> Self::Output {
1144 if self.rows != rhs.rows && self.columns != rhs.columns {
1145 return Err(SizingError::Both(rhs.rows, rhs.columns));
1146 }
1147
1148 if self.rows != rhs.rows {
1149 return Err(SizingError::Row(rhs.rows));
1150 }
1151
1152 if self.columns != rhs.columns {
1153 return Err(SizingError::Column(rhs.columns));
1154 }
1155
1156 Ok(Matrix {
1157 data: self
1158 .data
1159 .iter()
1160 .zip(rhs.data.iter())
1161 .map(|(s, r)| *s - *r)
1162 .collect(),
1163 rows: self.rows,
1164 columns: self.columns,
1165 })
1166 }
1167}
1168
1169impl<T, U> Sub for &Matrix<T>
1170where
1171 T: Sub<Output = U> + Copy,
1172 U: Copy,
1173{
1174 type Output = Result<Matrix<U>, SizingError>;
1175 fn sub(self, rhs: Self) -> Self::Output {
1176 if self.rows != rhs.rows && self.columns != rhs.columns {
1177 return Err(SizingError::Both(rhs.rows, rhs.columns));
1178 }
1179
1180 if self.rows != rhs.rows {
1181 return Err(SizingError::Row(rhs.rows));
1182 }
1183
1184 if self.columns != rhs.columns {
1185 return Err(SizingError::Column(rhs.columns));
1186 }
1187
1188 Ok(Matrix {
1189 data: self
1190 .data
1191 .iter()
1192 .zip(rhs.data.iter())
1193 .map(|(s, r)| *s - *r)
1194 .collect(),
1195 rows: self.rows,
1196 columns: self.columns,
1197 })
1198 }
1199}
1200
1201impl<T, U> Mul for Matrix<T>
1202where
1203 T: Copy + Mul<Output = U>,
1204 U: Copy + Zero,
1205{
1206 type Output = Result<Matrix<U>, usize>;
1207
1208 fn mul(self, rhs: Self) -> Self::Output {
1209 if self.columns != rhs.rows {
1210 return Err(rhs.rows);
1211 }
1212
1213 Matrix::new_from_data(
1214 &(0..self.rows)
1215 .map(|r| {
1216 (0..rhs.columns)
1217 .map(|c| {
1218 self.get_row(r)
1219 .unwrap()
1220 .iter()
1221 .zip(rhs.get_column(c).unwrap().iter())
1222 .fold(U::zero(), |res, (&el, &er)| res + (*el * *er))
1223 })
1224 .collect::<Vec<_>>()
1225 })
1226 .collect::<Vec<_>>(),
1227 )
1228 }
1229}
1230
1231impl<T, U> Mul for &Matrix<T>
1232where
1233 T: Copy + Mul<Output = U>,
1234 U: Copy + Zero,
1235{
1236 type Output = Result<Matrix<U>, usize>;
1237
1238 fn mul(self, rhs: Self) -> Self::Output {
1239 if self.columns != rhs.rows {
1240 return Err(rhs.rows);
1241 }
1242
1243 Matrix::new_from_data(
1244 &(0..self.rows)
1245 .map(|r| {
1246 (0..rhs.columns)
1247 .map(|c| {
1248 self.get_row(r)
1249 .unwrap()
1250 .iter()
1251 .zip(rhs.get_column(c).unwrap().iter())
1252 .fold(U::zero(), |res, (&el, &er)| res + (*el * *er))
1253 })
1254 .collect::<Vec<_>>()
1255 })
1256 .collect::<Vec<_>>(),
1257 )
1258 }
1259}
1260
1261impl<T, U> Neg for Matrix<T>
1262where
1263 T: Neg<Output = U> + Copy,
1264 U: Copy,
1265{
1266 type Output = Matrix<U>;
1267
1268 fn neg(self) -> Self::Output {
1269 Matrix {
1270 data: self.data.iter().map(|t| t.neg()).collect(),
1271 rows: self.rows,
1272 columns: self.columns,
1273 }
1274 }
1275}
1276
1277impl<T, U> Neg for &Matrix<T>
1278where
1279 T: Neg<Output = U> + Copy,
1280 U: Copy,
1281{
1282 type Output = Matrix<U>;
1283
1284 fn neg(self) -> Self::Output {
1285 Matrix {
1286 data: self.data.iter().map(|t| t.neg()).collect(),
1287 rows: self.rows,
1288 columns: self.columns,
1289 }
1290 }
1291}
1292
1293impl<T> Default for Matrix<T>
1294where
1295 T: Copy,
1296{
1297 fn default() -> Self {
1298 Self {
1299 data: vec![],
1300 rows: 0,
1301 columns: 0,
1302 }
1303 }
1304}
1305
1306#[cfg(test)]
1307mod tests {
1308 use super::*;
1309
1310 mod constructors {
1311 use super::*;
1312
1313 #[test]
1314 fn empty() {
1315 assert_eq!(
1316 Matrix::<i16>::empty(),
1317 Matrix {
1318 data: vec![],
1319 rows: 0,
1320 columns: 0
1321 }
1322 );
1323 }
1324
1325 mod new {
1326 use super::*;
1327
1328 #[test]
1329 fn handles_errors() {
1330 assert_eq!(Matrix::<u8>::new(0, 5), Err(SizingError::Row(0)));
1331 assert_eq!(Matrix::<i32>::new(2, 0), Err(SizingError::Column(0)));
1332 }
1333
1334 #[test]
1335 fn creates_matrix() {
1336 assert_eq!(
1337 Matrix::<i8>::new(2, 5),
1338 Ok(Matrix {
1339 data: vec![0; 10],
1340 rows: 2,
1341 columns: 5
1342 })
1343 );
1344 assert_eq!(
1345 Matrix::new(8, 3),
1346 Ok(Matrix {
1347 data: vec![0; 24],
1348 rows: 8,
1349 columns: 3
1350 })
1351 );
1352 assert_eq!(
1353 Matrix::new(4, 4),
1354 Ok(Matrix {
1355 data: vec![0; 16],
1356 rows: 4,
1357 columns: 4
1358 })
1359 );
1360 }
1361 }
1362
1363 #[test]
1364 fn new_identity() {
1365 assert_eq!(
1366 Matrix::new_identity(4),
1367 Matrix {
1368 data: vec![1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
1369 rows: 4,
1370 columns: 4
1371 }
1372 );
1373 }
1374
1375 mod new_with_data {
1376 use super::*;
1377
1378 #[test]
1379 fn handles_errors() {
1380 assert_eq!(
1381 Matrix::new_with_data(0, vec![1, 2, 3, 4]),
1382 Err(SizingError::Column(0))
1383 );
1384 assert_eq!(
1385 Matrix::<u8>::new_with_data(4, vec![]),
1386 Err(SizingError::Row(0))
1387 );
1388 assert_eq!(
1389 Matrix::new_with_data(3, vec![5; 7]),
1390 Err(SizingError::Row(1))
1391 );
1392 }
1393
1394 #[test]
1395 fn creates_matrix() {
1396 let m = Matrix::new_with_data(7, (0u32..35).collect());
1397
1398 assert_eq!(
1399 m,
1400 Ok(Matrix {
1401 data: (0u32..35).collect(),
1402 rows: 5,
1403 columns: 7
1404 })
1405 )
1406 }
1407 }
1408
1409 mod new_from_data {
1410 use super::*;
1411
1412 #[test]
1413 fn handles_errors() {
1414 assert_eq!(
1415 Matrix::new_from_data(&vec![vec![], vec![1, 5, 6], vec![2, 6, 9]]),
1416 Err(0)
1417 );
1418 assert_eq!(
1419 Matrix::new_from_data(&vec![
1420 vec![1, 5, 3, 2, 7],
1421 vec![1, 2, 45, 7, 3],
1422 vec![65, 8, 5, 23, 67],
1423 vec![123, 5, 47]
1424 ]),
1425 Err(3)
1426 )
1427 }
1428
1429 #[test]
1430 fn creates_matrix() {
1431 assert_eq!(
1432 Matrix::new_from_data(&vec![
1433 vec![1, 2, 3, 4],
1434 vec![2, 3, 4, 1],
1435 vec![3, 4, 1, 2],
1436 vec![4, 1, 2, 3]
1437 ]),
1438 Ok(Matrix {
1439 data: vec![1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3],
1440 rows: 4,
1441 columns: 4
1442 })
1443 );
1444 assert_eq!(
1445 Matrix::new_from_data(&vec![vec![4, 2, 1, 5, 3], vec![1, 2, 3, 4, 5],]),
1446 Ok(Matrix {
1447 data: vec![4, 2, 1, 5, 3, 1, 2, 3, 4, 5],
1448 rows: 2,
1449 columns: 5
1450 })
1451 );
1452 assert_eq!(
1453 Matrix::<&str>::new_from_data(&vec![]),
1454 Ok(Matrix {
1455 data: vec![],
1456 rows: 0,
1457 columns: 0
1458 })
1459 );
1460 }
1461 }
1462 }
1463
1464 mod getters {
1465 use super::*;
1466
1467 #[test]
1468 fn data() {
1469 let m = Matrix::<u16>::new(12, 5).unwrap();
1470
1471 assert_eq!(m.data(), vec![0; 60]);
1472 }
1473
1474 #[test]
1475 fn rows() {
1476 let m = Matrix::<u16>::new(9, 3).unwrap();
1477
1478 assert_eq!(m.rows(), 9);
1479 }
1480
1481 #[test]
1482 fn columns() {
1483 let m = Matrix::<u16>::new(2, 4).unwrap();
1484
1485 assert_eq!(m.columns(), 4);
1486 }
1487
1488 #[test]
1489 fn size() {
1490 let m1 = Matrix::<i32>::new(9, 16).unwrap();
1491 let m2 = Matrix::<u32>::new_identity(12);
1492
1493 assert_eq!(m1.size(), 144);
1494 assert_eq!(m2.size(), 144);
1495 }
1496
1497 #[test]
1498 fn is_square() {
1499 let m1 = Matrix::<u16>::new(6, 2).unwrap();
1500 let m2 = Matrix::<i8>::new(3, 3).unwrap();
1501 let m3 = Matrix::<u32>::new_identity(4);
1502
1503 assert!(!m1.is_square());
1504 assert!(m2.is_square());
1505 assert!(m3.is_square());
1506 }
1507
1508 mod get_row {
1509 use super::*;
1510
1511 #[test]
1512 fn handles_errors() {
1513 let m = Matrix::new_from_data(&vec![vec![0]]).unwrap();
1514
1515 assert_eq!(m.get_row(3), None);
1516 }
1517
1518 #[test]
1519 fn gets_row() {
1520 let m = Matrix::<i32>::new_identity(5);
1521
1522 assert_eq!(m.get_row(3).unwrap(), vec![&0i32, &0, &0, &1, &0]);
1523 }
1524 }
1525
1526 mod get_rows {
1527 use super::*;
1528
1529 #[test]
1530 fn handles_errors() {
1531 let m = Matrix::<u8>::new_identity(4);
1532
1533 assert_eq!(m.get_rows(0..8), None);
1534 }
1535
1536 #[test]
1537 fn gets_rows() {
1538 let m = Matrix::<u64>::new_identity(7);
1539
1540 assert_eq!(
1541 m.get_rows(1..4).unwrap(),
1542 vec![
1543 vec![&0, &1, &0, &0, &0, &0, &0],
1544 vec![&0, &0, &1, &0, &0, &0, &0],
1545 vec![&0, &0, &0, &1, &0, &0, &0]
1546 ]
1547 )
1548 }
1549 }
1550
1551 mod get_column {
1552 use super::*;
1553
1554 #[test]
1555 fn handles_errors() {
1556 let m = Matrix::new_from_data(&vec![
1557 vec![1, 2, 3, 4, 5],
1558 vec![6, 7, 8, 7, 6],
1559 vec![5, 4, 3, 2, 1],
1560 ])
1561 .unwrap();
1562
1563 assert_eq!(m.get_column(5), None);
1564 }
1565
1566 #[test]
1567 fn gets_column() {
1568 let m = Matrix::new_from_data(&vec![
1569 vec![1, 2, 3, 4, 5],
1570 vec![6, 7, 8, 7, 6],
1571 vec![5, 4, 3, 2, 1],
1572 ])
1573 .unwrap();
1574
1575 assert_eq!(m.get_column(3).unwrap(), vec![&4, &7, &2]);
1576 }
1577 }
1578
1579 mod get_columns {
1580 use super::*;
1581
1582 #[test]
1583 fn handles_errors() {
1584 let m = Matrix::new_from_data(&vec![
1585 vec![1, 2, 3, 4, 5],
1586 vec![6, 7, 8, 7, 6],
1587 vec![5, 4, 3, 2, 1],
1588 ])
1589 .unwrap();
1590
1591 assert_eq!(m.get_columns(0..9), None);
1592 }
1593
1594 #[test]
1595 fn gets_columns() {
1596 let m = Matrix::new_from_data(&vec![
1597 vec![1, 2, 3, 4, 5],
1598 vec![6, 7, 8, 7, 6],
1599 vec![5, 4, 3, 2, 1],
1600 ])
1601 .unwrap();
1602
1603 assert_eq!(
1604 m.get_columns(2..4).unwrap(),
1605 vec![vec![&3, &8, &3], vec![&4, &7, &2]]
1606 );
1607 }
1608 }
1609 }
1610
1611 mod mut_getters {
1612 use super::*;
1613
1614 #[test]
1615 fn data_mut() {
1616 let mut m = Matrix::new_identity(2);
1617 let data = m.data_mut();
1618
1619 assert_eq!(data, &mut vec![1, 0, 0, 1]);
1620
1621 data[1] = 5;
1622
1623 assert_eq!(m.data, vec![1, 5, 0, 1]);
1624 }
1625
1626 mod get_mut_row {
1627 use super::*;
1628
1629 #[test]
1630 fn handles_errors() {
1631 let mut m = Matrix::<i128>::new(7, 5).unwrap();
1632
1633 assert_eq!(m.get_mut_row(23), None);
1634 }
1635
1636 #[test]
1637 fn gets_mut_row() {
1638 let mut m = Matrix::<i8>::new_identity(3);
1639 let mut row = m.get_mut_row(2).unwrap();
1640
1641 assert_eq!(row, vec![&mut 0, &mut 0, &mut 1]);
1642
1643 *row[0] = 3;
1644
1645 assert_eq!(m.get_row(2).unwrap(), vec![&3, &0, &1]);
1646 }
1647 }
1648
1649 mod get_mut_column {
1650 use super::*;
1651
1652 #[test]
1653 fn handles_errors() {
1654 let mut m = Matrix::<u8>::new(5, 8).unwrap();
1655
1656 assert_eq!(m.get_mut_column(19), None);
1657 }
1658
1659 #[test]
1660 fn gets_column() {
1661 let mut m = Matrix::new_from_data(&vec![
1662 vec![1, 2, 3, 4, 5, 6, 7],
1663 vec![8, 9, 10, 11, 12, 13, 14],
1664 vec![14, 13, 12, 11, 10, 9, 8],
1665 vec![7, 6, 5, 4, 3, 2, 1],
1666 ])
1667 .unwrap();
1668 let mut col = m.get_mut_column(5).unwrap();
1669
1670 assert_eq!(col, vec![&mut 6, &mut 13, &mut 9, &mut 2]);
1671
1672 *col[3] = 17;
1673
1674 assert_eq!(m.get_column(5).unwrap(), vec![&6, &13, &9, &17]);
1675 }
1676 }
1677 }
1678
1679 mod swappers {
1680 use super::*;
1681
1682 mod swap_elements {
1683 use super::*;
1684
1685 #[test]
1686 fn handles_errors() {
1687 let mut m = Matrix::<u16>::new_identity(6);
1688
1689 assert_eq!(m.swap_elements((13, 2), (5, 1)), Some(IndexError::Row(13)));
1690 assert_eq!(m.swap_elements((0, 8), (3, 4)), Some(IndexError::Column(8)));
1691 assert_eq!(
1692 m.swap_elements((18, 27), (1, 2)),
1693 Some(IndexError::Both(18, 27))
1694 );
1695 assert_eq!(m.swap_elements((3, 0), (6, 5)), Some(IndexError::Row(6)));
1696 assert_eq!(m.swap_elements((4, 3), (3, 9)), Some(IndexError::Column(9)));
1697 assert_eq!(
1698 m.swap_elements((0, 2), (12, 7)),
1699 Some(IndexError::Both(12, 7))
1700 );
1701 }
1702
1703 #[test]
1704 fn swaps_elements() {
1705 let mut m = Matrix::<i8>::new_identity(3);
1706
1707 assert_eq!(m.swap_elements((0, 0), (0, 2)), None);
1708 assert_eq!(m.data, vec![0, 0, 1, 0, 1, 0, 0, 0, 1]);
1709 }
1710 }
1711
1712 mod swap_rows {
1713 use super::*;
1714
1715 #[test]
1716 fn handles_errors() {
1717 let mut m = Matrix::<i64>::new_identity(7);
1718
1719 assert_eq!(m.swap_rows(2, 9), Some(9));
1720 assert_eq!(m.swap_rows(7, 4), Some(7));
1721 }
1722
1723 #[test]
1724 fn swaps_rows() {
1725 let mut m = Matrix::new_from_data(&vec![
1726 vec![5, 4, 3, 2, 1],
1727 vec![1, 2, 3, 4, 5],
1728 vec![5, 4, 3, 2, 1],
1729 ])
1730 .unwrap();
1731
1732 assert_eq!(m.swap_rows(0, 1), None);
1733 assert_eq!(m.data, vec![1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]);
1734 }
1735 }
1736
1737 mod swap_columns {
1738 use super::*;
1739
1740 #[test]
1741 fn handles_errors() {
1742 let mut m = Matrix::<u16>::new(7, 3).unwrap();
1743
1744 assert_eq!(m.swap_columns(0, 4), Some(IndexError::Column(4)));
1745 assert_eq!(m.swap_columns(10, 2), Some(IndexError::Column(10)));
1746 }
1747
1748 #[test]
1749 fn swaps_columns() {
1750 let mut m = Matrix::<u8>::new_identity(4);
1751
1752 assert_eq!(m.swap_columns(0, 2), None);
1753 assert_eq!(m.data, vec![0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1]);
1754 }
1755 }
1756 }
1757
1758 mod operations {
1759 use super::*;
1760
1761 #[test]
1762 fn scale() {
1763 let mut m =
1764 Matrix::new_from_data(&vec![vec![1, 2, 3], vec![2, 3, 1], vec![3, 1, 2]]).unwrap();
1765 m.scale(2);
1766
1767 assert_eq!(m.data, vec![2, 4, 6, 4, 6, 2, 6, 2, 4]);
1768 }
1769
1770 mod scale_row {
1771 use super::*;
1772
1773 #[test]
1774 fn handles_errors() {
1775 let mut m = Matrix::new_from_data(&vec![vec![1]]).unwrap();
1776
1777 assert_eq!(m.scale_row(4, 3), Some(4));
1778 }
1779
1780 #[test]
1781 fn scales_row() {
1782 let mut m = Matrix::<u128>::new_identity(2);
1783
1784 assert_eq!(m.scale_row(0, 3), None);
1785 assert_eq!(m.data, vec![3, 0, 0, 1]);
1786 }
1787 }
1788
1789 mod add_scaled_row {
1790 use super::*;
1791
1792 #[test]
1793 fn handles_errors() {
1794 let mut m = Matrix::new_from_data(&vec![vec![1, 2], vec![2, 1]]).unwrap();
1795
1796 assert_eq!(m.add_scaled_row(2, 0, 3), Some(2));
1797 assert_eq!(m.add_scaled_row(1, 5, 8), Some(5));
1798 }
1799
1800 #[test]
1801 fn adds_scaled_row() {
1802 let mut m =
1803 Matrix::new_from_data(&vec![vec![1, 0, 1], vec![2, 3, 0], vec![0, 5, 9]])
1804 .unwrap();
1805
1806 assert_eq!(m.add_scaled_row(0, 2, 3), None);
1807 assert_eq!(m.data, vec![1, 0, 1, 2, 3, 0, 3, 5, 12]);
1808 }
1809 }
1810
1811 mod scale_column {
1812 use super::*;
1813
1814 #[test]
1815 fn handles_errors() {
1816 let mut m = Matrix::new_from_data(&vec![vec![1]]).unwrap();
1817
1818 assert_eq!(m.scale_column(4, 3), Some(4));
1819 }
1820
1821 #[test]
1822 fn scales_column() {
1823 let mut m = Matrix::<u128>::new_identity(2);
1824
1825 assert_eq!(m.scale_column(0, 3), None);
1826 assert_eq!(m.data, vec![3, 0, 0, 1]);
1827 }
1828 }
1829
1830 mod add_scaled_column {
1831 use super::*;
1832
1833 #[test]
1834 fn handles_errors() {
1835 let mut m = Matrix::new_from_data(&vec![vec![1, 2], vec![2, 1]]).unwrap();
1836
1837 assert_eq!(m.add_scaled_column(2, 0, 3), Some(2));
1838 assert_eq!(m.add_scaled_column(1, 5, 8), Some(5));
1839 }
1840
1841 #[test]
1842 fn adds_scaled_column() {
1843 let mut m =
1844 Matrix::new_from_data(&vec![vec![1, 0, 1], vec![2, 3, 0], vec![0, 5, 9]])
1845 .unwrap();
1846
1847 assert_eq!(m.add_scaled_column(0, 2, 3), None);
1848 assert_eq!(m.data, vec![1, 0, 4, 2, 3, 6, 0, 5, 9]);
1849 }
1850 }
1851
1852 mod resize {
1853 use super::*;
1854
1855 #[test]
1856 fn handles_errors() {
1857 let mut m = Matrix::new_from_data(&vec![vec![2, 5, 3], vec![9, 1, 6]]).unwrap();
1858
1859 assert_eq!(m.resize((0, 5)), Some(IndexError::Row(0)));
1860 assert_eq!(m.resize((2, 0)), Some(IndexError::Column(0)));
1861 assert_eq!(m.resize((3, 4)), Some(IndexError::Both(3, 4)));
1862 }
1863
1864 #[test]
1865 fn resizes() {
1866 let mut m = Matrix::new_from_data(&vec![vec![2, 5, 3], vec![9, 1, 6]]).unwrap();
1867
1868 assert_eq!(m.resize((3, 2)), None);
1869 assert_eq!(m.rows, 3);
1870 assert_eq!(m.columns, 2);
1871
1872 assert_eq!(m.resize((6, 1)), None);
1873 assert_eq!(m.rows, 6);
1874 assert_eq!(m.columns, 1);
1875
1876 assert_eq!(m.resize((1, 6)), None);
1877 assert_eq!(
1878 m,
1879 Matrix {
1880 data: vec![2, 5, 3, 9, 1, 6],
1881 rows: 1,
1882 columns: 6
1883 }
1884 );
1885 }
1886 }
1887
1888 mod remove_row {
1889 use super::*;
1890
1891 #[test]
1892 fn handles_errors() {
1893 let mut m = Matrix::<u64>::new(10, 7).unwrap();
1894
1895 assert_eq!(m.remove_row(19), Some(19));
1896 assert_eq!(m.remove_row(10), Some(10));
1897 }
1898
1899 #[test]
1900 fn removes_row() {
1901 let mut m = Matrix::new_from_data(&vec![
1902 vec![1, 2, 3],
1903 vec![4, 5, 6],
1904 vec![7, 8, 9],
1905 vec![10, 11, 10],
1906 vec![9, 8, 7],
1907 vec![6, 5, 4],
1908 vec![3, 2, 1],
1909 ])
1910 .unwrap();
1911
1912 assert_eq!(m.remove_row(2), None);
1913 assert_eq!(
1914 m,
1915 Matrix {
1916 data: vec![1, 2, 3, 4, 5, 6, 10, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
1917 rows: 6,
1918 columns: 3
1919 }
1920 );
1921 assert_eq!(m.remove_row(5), None);
1922 assert_eq!(
1923 m,
1924 Matrix {
1925 data: vec![1, 2, 3, 4, 5, 6, 10, 11, 10, 9, 8, 7, 6, 5, 4],
1926 rows: 5,
1927 columns: 3
1928 }
1929 );
1930 }
1931 }
1932
1933 mod remove_column {
1934 use super::*;
1935
1936 #[test]
1937 fn handles_errors() {
1938 let mut m = Matrix::new_with_data(
1939 5,
1940 vec![3, 5, 4, 6, 8, 6, 3, 2, 1, 6, 8, 5, 8, 4, 5, 6, 7, 3, 4, 0],
1941 )
1942 .unwrap();
1943
1944 assert_eq!(m.remove_column(0), None);
1945 assert_eq!(
1946 m,
1947 Matrix {
1948 data: vec![5, 4, 6, 8, 3, 2, 1, 6, 5, 8, 4, 5, 7, 3, 4, 0],
1949 rows: 4,
1950 columns: 4
1951 }
1952 );
1953 assert_eq!(m.remove_column(2), None);
1954 assert_eq!(
1955 m,
1956 Matrix {
1957 data: vec![5, 4, 8, 3, 2, 6, 5, 8, 5, 7, 3, 0],
1958 rows: 4,
1959 columns: 3
1960 }
1961 );
1962 }
1963 }
1964
1965 mod insert_row {
1966 use super::*;
1967
1968 #[test]
1969 fn handles_errors() {
1970 let mut m = Matrix::<u128>::new(4, 7).unwrap();
1971
1972 assert_eq!(
1973 m.insert_row(9, &vec![1, 2, 3, 4, 5, 6, 7]),
1974 Some(IndexError::Row(9))
1975 );
1976 assert_eq!(
1977 m.insert_row(3, &vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),
1978 Some(IndexError::Column(10))
1979 );
1980 assert_eq!(
1981 m.insert_row(20, &vec![3, 5, 12, 3, 56, 7, 8, 4, 2, 1, 6, 23, 1, 7]),
1982 Some(IndexError::Both(20, 14))
1983 );
1984 }
1985
1986 #[test]
1987 fn inserts_row() {
1988 let mut m = Matrix::<i8>::new_from_data(&vec![
1989 vec![1, 2, 3, 4, 5],
1990 vec![6, 7, 8, 7, 6],
1991 vec![5, 4, 3, 2, 1],
1992 ])
1993 .unwrap();
1994
1995 assert_eq!(m.insert_row(0, &vec![10, 9, 8, 7, 6]), None);
1996 assert_eq!(
1997 m,
1998 Matrix {
1999 data: vec![10, 9, 8, 7, 6, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1],
2000 rows: 4,
2001 columns: 5
2002 }
2003 );
2004 assert_eq!(m.insert_row(4, &vec![2, 4, 6, 8, 10]), None);
2005 assert_eq!(
2006 m,
2007 Matrix {
2008 data: vec![
2009 10, 9, 8, 7, 6, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 2, 4, 6,
2010 8, 10
2011 ],
2012 rows: 5,
2013 columns: 5
2014 }
2015 );
2016 }
2017 }
2018
2019 mod insert_column {
2020 use super::*;
2021
2022 #[test]
2023 fn handles_errors() {
2024 let mut m = Matrix::<u16>::new(19, 7).unwrap();
2025
2026 assert_eq!(m.insert_column(2, &vec![0, 3, 1]), Some(IndexError::Row(3)));
2027 assert_eq!(
2028 m.insert_column(32, &(0..19).collect::<Vec<_>>()),
2029 Some(IndexError::Column(32))
2030 );
2031 assert_eq!(
2032 m.insert_column(22, &vec![2, 4, 6, 8, 1, 3, 5, 7, 9]),
2033 Some(IndexError::Both(9, 22))
2034 );
2035 }
2036
2037 #[test]
2038 fn inserts_column() {
2039 let mut m = Matrix::new_from_data(&vec![
2040 vec![1, 4, 7, 10],
2041 vec![2, 5, 8, 11],
2042 vec![3, 6, 9, 12],
2043 ])
2044 .unwrap();
2045
2046 assert_eq!(m.insert_column(2, &vec![0, 0, 0]), None);
2047 assert_eq!(
2048 m,
2049 Matrix {
2050 data: vec![1, 4, 0, 7, 10, 2, 5, 0, 8, 11, 3, 6, 0, 9, 12],
2051 rows: 3,
2052 columns: 5
2053 }
2054 );
2055 assert_eq!(m.insert_column(2, &vec![0, 0, 0]), None);
2056 assert_eq!(
2057 m,
2058 Matrix {
2059 data: vec![1, 4, 0, 0, 7, 10, 2, 5, 0, 0, 8, 11, 3, 6, 0, 0, 9, 12],
2060 rows: 3,
2061 columns: 6
2062 }
2063 );
2064 }
2065 }
2066
2067 mod join_matrix_above {
2068 use super::*;
2069
2070 #[test]
2071 fn handles_errors() {
2072 let mut m1 = Matrix::<i8>::new(2, 9).unwrap();
2073 let m2 = Matrix::new(3, 5).unwrap();
2074
2075 assert_eq!(m1.join_matrix_above(&m2), Some(5));
2076 }
2077
2078 #[test]
2079 fn joins_above() {
2080 let mut m1 = Matrix::new_identity(2);
2081 let m2 = Matrix::new_with_data(2, vec![2, 5]).unwrap();
2082
2083 assert_eq!(m1.join_matrix_above(&m2), None);
2084 assert_eq!(
2085 m1,
2086 Matrix {
2087 data: vec![2, 5, 1, 0, 0, 1],
2088 columns: 2,
2089 rows: 3
2090 }
2091 );
2092 }
2093 }
2094
2095 mod join_matrix_below {
2096 use super::*;
2097
2098 #[test]
2099 fn handles_errors() {
2100 let mut m1 = Matrix::<i8>::new(2, 2).unwrap();
2101 let m2 = Matrix::new(3, 7).unwrap();
2102
2103 assert_eq!(m1.join_matrix_below(&m2), Some(7));
2104 }
2105
2106 #[test]
2107 fn joins_below() {
2108 let mut m1 = Matrix::new_identity(2);
2109 let m2 = Matrix::new_with_data(2, vec![2, 5]).unwrap();
2110
2111 assert_eq!(m1.join_matrix_below(&m2), None);
2112 assert_eq!(
2113 m1,
2114 Matrix {
2115 data: vec![1, 0, 0, 1, 2, 5],
2116 columns: 2,
2117 rows: 3
2118 }
2119 );
2120 }
2121 }
2122
2123 mod join_matrix_left {
2124 use super::*;
2125
2126 #[test]
2127 fn handles_errors() {
2128 let mut m1 = Matrix::<i8>::new(5, 1).unwrap();
2129 let m2 = Matrix::new(3, 2).unwrap();
2130
2131 assert_eq!(m1.join_matrix_left(&m2), Some(3));
2132 }
2133
2134 #[test]
2135 fn joins_left() {
2136 let mut m1 = Matrix::new_identity(2);
2137 let m2 = Matrix::new_with_data(1, vec![2, 5]).unwrap();
2138
2139 assert_eq!(m1.join_matrix_left(&m2), None);
2140 assert_eq!(
2141 m1,
2142 Matrix {
2143 data: vec![2, 1, 0, 5, 0, 1],
2144 columns: 3,
2145 rows: 2
2146 }
2147 );
2148 }
2149 }
2150
2151 mod join_matrix_right {
2152 use super::*;
2153
2154 #[test]
2155 fn handles_errors() {
2156 let mut m1 = Matrix::<i8>::new(8, 5).unwrap();
2157 let m2 = Matrix::new(11, 11).unwrap();
2158
2159 assert_eq!(m1.join_matrix_right(&m2), Some(11));
2160 }
2161
2162 #[test]
2163 fn joins_left() {
2164 let mut m1 = Matrix::new_identity(2);
2165 let m2 = Matrix::new_with_data(1, vec![2, 5]).unwrap();
2166
2167 assert_eq!(m1.join_matrix_right(&m2), None);
2168 assert_eq!(
2169 m1,
2170 Matrix {
2171 data: vec![1, 0, 2, 0, 1, 5],
2172 columns: 3,
2173 rows: 2
2174 }
2175 );
2176 }
2177 }
2178 }
2179
2180 mod derivers {
2181 use super::*;
2182
2183 #[test]
2184 fn transpose() {
2185 let m1 = Matrix::new_from_data(&vec![vec![1, 4, 2], vec![9, 7, 1], vec![4, 6, 2]])
2186 .unwrap()
2187 .transpose();
2188 let m2 =
2189 Matrix::new_from_data(&vec![vec![1, 9, 4], vec![4, 7, 6], vec![2, 1, 2]]).unwrap();
2190
2191 assert_eq!(m1, m2);
2192 }
2193
2194 mod minor {
2195 use super::*;
2196
2197 #[test]
2198 fn handles_errors() {
2199 let m1 = Matrix::<i32>::new(5, 6).unwrap();
2200 let m2 = Matrix::<i32>::new_identity(5);
2201
2202 assert_eq!(m1.minor((3, 2)), Err(MinorError::NotSquare));
2203 assert_eq!(m1.minor((5, 7)), Err(MinorError::NotSquare));
2204 assert_eq!(
2205 m2.minor((7, 0)),
2206 Err(MinorError::BoundsError(IndexError::Row(7)))
2207 );
2208 assert_eq!(
2209 m2.minor((1, 5)),
2210 Err(MinorError::BoundsError(IndexError::Column(5)))
2211 );
2212 assert_eq!(
2213 m2.minor((6, 9)),
2214 Err(MinorError::BoundsError(IndexError::Both(6, 9)))
2215 );
2216 }
2217
2218 #[test]
2219 fn gets_minor() {
2220 let m1 = Matrix::new_from_data(&vec![vec![3, 2], vec![1, 7]]).unwrap();
2221 let m2 = Matrix::<u128>::new_identity(3);
2222
2223 assert_eq!(m1.minor((1, 1)).unwrap(), 3);
2224 assert_eq!(m2.minor((0, 0)).unwrap(), 1);
2225 }
2226 }
2227
2228 mod minor_matrix {
2229 use super::*;
2230
2231 #[test]
2232 fn handles_errors() {
2233 let m = Matrix::new_from_data(&vec![vec![1, 2, 31]]).unwrap();
2234
2235 assert_eq!(m.minor_matrix(), None);
2236 }
2237
2238 #[test]
2239 fn gets_minor_matrix() {
2240 let m1 = Matrix::<u64>::new_from_data(&vec![vec![5, 3], vec![2, 9]]).unwrap();
2241 let m2 = Matrix::<i32>::new_identity(4);
2242
2243 assert_eq!(m1.minor_matrix().unwrap().data, vec![9, 2, 3, 5]);
2244 assert_eq!(m2.minor_matrix().unwrap(), m2);
2245 }
2246 }
2247
2248 mod cofacter {
2249 use super::*;
2250
2251 #[test]
2252 fn handles_errors() {
2253 let m1 = Matrix::<i16>::new(5, 2).unwrap();
2254 let m2 = Matrix::new_from_data(&vec![vec![1, 2, 3], vec![3, 2, 1]]).unwrap();
2255
2256 assert_eq!(m1.cofactor(), None);
2257 assert_eq!(m2.cofactor(), None);
2258 }
2259
2260 #[test]
2261 fn creates_cofacter() {
2262 let m1 = Matrix::new_from_data(&vec![
2263 vec![1, 2, 3, 4],
2264 vec![5, 6, 7, 8],
2265 vec![8, 7, 6, 5],
2266 vec![4, 3, 2, 1],
2267 ])
2268 .unwrap();
2269 let m2 = Matrix::<i8>::new_identity(5);
2270 let m3 = Matrix::new_from_data(&vec![
2271 vec![2, 5, 0, 8, 4],
2272 vec![10, 2, 7, 2, 0],
2273 vec![8, 5, 1, 0, 6],
2274 vec![8, 8, 3, 3, 3],
2275 vec![5, 2, 0, 5, 9],
2276 ])
2277 .unwrap();
2278
2279 assert_eq!(m1.cofactor().unwrap().data, vec![0; 16]);
2280 assert_eq!(m2.cofactor().unwrap().data, m2.data);
2281 assert_eq!(
2282 m3.cofactor().unwrap().data,
2283 vec![
2284 -1578, 564, 2346, -885, 1243, -610, 376, 498, -291, 417, -2234, 752, 3154,
2285 -621, 1419, 2168, -1128, -3028, 886, -1446, 1468, -376, -2136, 512, -1288
2286 ]
2287 );
2288 }
2289 }
2290
2291 mod adjunct {
2292 use super::*;
2293
2294 #[test]
2295 fn handles_errors() {
2296 let m1 = Matrix::<i16>::new(5, 2).unwrap();
2297 let m2 = Matrix::new_from_data(&vec![vec![1, 2, 3], vec![3, 2, 1]]).unwrap();
2298
2299 assert_eq!(m1.adjunct(), None);
2300 assert_eq!(m2.adjunct(), None);
2301 }
2302
2303 #[test]
2304 fn creates_adjunct() {
2305 let m1 = Matrix::new_from_data(&vec![vec![2, 7, 6], vec![3, 6, 9], vec![4, 8, 1]])
2306 .unwrap();
2307 let m2 = Matrix::<i32>::new_identity(4);
2308
2309 assert_eq!(
2310 m1.adjunct().unwrap().data,
2311 vec![-66, 41, 27, 33, -22, 0, 0, 12, -9]
2312 );
2313 assert_eq!(m2.adjunct().unwrap(), m2);
2314 }
2315 }
2316
2317 mod determinant {
2318 use super::*;
2319
2320 #[test]
2321 fn handles_errors() {
2322 let m = Matrix::<i32>::new(7, 5).unwrap();
2323
2324 assert_eq!(m.determinant(), None);
2325 }
2326
2327 #[test]
2328 fn derives_determinant() {
2329 let m1 = Matrix::<u32>::new(4, 4).unwrap();
2330 let m2 = Matrix::new_from_data(&vec![vec![1, 2], vec![5, 7]]).unwrap();
2331 let m3 = Matrix::<i16>::new_identity(9);
2332
2333 assert_eq!(m1.determinant(), Some(0));
2334 assert_eq!(m2.determinant(), Some(-3));
2335 assert_eq!(m3.determinant(), Some(1));
2336 }
2337 }
2338
2339 mod inverse {
2340 use super::*;
2341
2342 #[test]
2343 fn handles_errors() {
2344 let m1 = Matrix::new_from_data(&vec![vec![1, 4], vec![2, 8]]).unwrap();
2345 let m2 = Matrix::<i16>::new(4, 5).unwrap();
2346
2347 assert_eq!(m1.inverse(), Err(InversionError::InvalidDeterminant));
2348 assert_eq!(m2.inverse(), Err(InversionError::NotSquare));
2349 }
2350
2351 #[test]
2352 fn derives_inverse() {
2353 let m1 = Matrix::new_from_data(&vec![vec![1, 0, 2], vec![0, 4, 1], vec![0, 1, 0]])
2354 .unwrap();
2355 let m2 = Matrix::<i8>::new_identity(6);
2356 let m3 =
2357 Matrix::new_from_data(&vec![vec![1, -1, 1], vec![2, 3, 0], vec![0, -2, 1]])
2358 .unwrap();
2359
2360 assert_eq!(
2361 m1.inverse(),
2362 Ok(Matrix {
2363 data: vec![1, -2, 8, 0, 0, 1, 0, 1, -4],
2364 rows: 3,
2365 columns: 3
2366 })
2367 );
2368 assert_eq!(m2.inverse(), Ok(m2));
2369 assert_eq!(
2370 m3.inverse().unwrap().data,
2371 vec![3, -1, -3, -2, 1, 2, -4, 2, 5]
2372 );
2373 }
2374 }
2375
2376 mod fast_inverse {
2377 use super::*;
2378
2379 #[test]
2380 fn handles_errors() {
2381 let m1 = Matrix::new_from_data(&vec![vec![1, 4], vec![2, 8]]).unwrap();
2382 let m2 = Matrix::<i16>::new(4, 5).unwrap();
2383
2384 assert_eq!(m1.fast_inverse(), Err(InversionError::InvalidDeterminant));
2385 assert_eq!(m2.fast_inverse(), Err(InversionError::NotSquare));
2386 }
2387
2388 #[test]
2389 fn derives_inverse() {
2390 let m1 = Matrix::new_from_data(&vec![
2391 vec![1f32, 0f32, 2f32],
2392 vec![0f32, 4f32, 1f32],
2393 vec![0f32, 1f32, 0f32],
2394 ])
2395 .unwrap();
2396 let m2 = Matrix::<i8>::new_identity(6);
2397 let m3 = Matrix::new_from_data(&vec![
2398 vec![1f32, -1f32, 1f32],
2399 vec![2f32, 3f32, 0f32],
2400 vec![0f32, -2f32, 1f32],
2401 ])
2402 .unwrap();
2403
2404 assert_eq!(
2405 m1.fast_inverse(),
2406 Ok(Matrix {
2407 data: vec![1f32, -2f32, 8f32, 0f32, 0f32, 1f32, 0f32, 1f32, -4f32],
2408 rows: 3,
2409 columns: 3
2410 })
2411 );
2412 assert_eq!(m2.fast_inverse(), Ok(m2));
2413 assert_eq!(
2414 m3.fast_inverse()
2415 .unwrap()
2416 .data
2417 .iter()
2418 .map(|f| f.round())
2419 .collect::<Vec<_>>(),
2420 vec![3f32, -1f32, -3f32, -2f32, 1f32, 2f32, -4f32, 2f32, 5f32]
2421 );
2422 }
2423 }
2424
2425 mod as_resize {
2426 use super::*;
2427
2428 #[test]
2429 fn handles_errors() {
2430 let m = Matrix::new_from_data(&vec![vec![2, 5, 3], vec![9, 1, 6]]).unwrap();
2431
2432 assert_eq!(m.as_resize((0, 5)), Err(IndexError::Row(0)));
2433 assert_eq!(m.as_resize((2, 0)), Err(IndexError::Column(0)));
2434 assert_eq!(m.as_resize((3, 4)), Err(IndexError::Both(3, 4)));
2435 }
2436
2437 #[test]
2438 fn resizes() {
2439 let m1 = Matrix::new_from_data(&vec![vec![2, 5, 3], vec![9, 1, 6]]).unwrap();
2440 let m2 = m1.as_resize((3, 2)).unwrap();
2441 let m3 = m1.as_resize((6, 1)).unwrap();
2442 let m4 = m1.as_resize((1, 6)).unwrap();
2443
2444 assert_eq!(
2445 m2,
2446 Matrix {
2447 data: vec![2, 5, 3, 9, 1, 6],
2448 rows: 3,
2449 columns: 2
2450 }
2451 );
2452 assert_eq!(
2453 m3,
2454 Matrix {
2455 data: vec![2, 5, 3, 9, 1, 6],
2456 rows: 6,
2457 columns: 1
2458 }
2459 );
2460 assert_eq!(
2461 m4,
2462 Matrix {
2463 data: vec![2, 5, 3, 9, 1, 6],
2464 rows: 1,
2465 columns: 6
2466 }
2467 );
2468 }
2469 }
2470 }
2471
2472 mod traits {
2473 use super::*;
2474
2475 #[test]
2476 fn debug() {
2477 let m1 = Matrix::<u8>::new(1, 1).unwrap();
2478 let m2 = Matrix::<i16>::new(1, 7).unwrap();
2479 let m3 = Matrix::<u32>::new(5, 1).unwrap();
2480 let m4 = Matrix::<i8>::new(3, 8).unwrap();
2481
2482 assert_eq!("[0]", format!("{:?}", m1));
2483 assert_eq!("[0, 0, 0, 0, 0, 0, 0]", format!("{:?}", m2));
2484 assert_eq!("[0]\n[0]\n[0]\n[0]\n[0]", format!("{:?}", m3));
2485 assert_eq!(
2486 "[0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 0, 0]\n[0, 0, 0, 0, 0, 0, 0, 0]",
2487 format!("{:?}", m4)
2488 );
2489 }
2490
2491 #[test]
2492 fn index() {
2493 let m = Matrix::new_from_data(&vec![
2494 vec![2, 5, 7, 2, 1],
2495 vec![8, 0, 5, 3, 6],
2496 vec![6, 4, 3, 6, 7],
2497 vec![1, 7, 9, 3, 4],
2498 ])
2499 .unwrap();
2500
2501 assert_eq!(m[(3, 4)], 4);
2502 assert_eq!(m[(1, 2)], 5);
2503 assert_eq!(m[(3, 1)], 7);
2504 assert_eq!(m[(0, 3)], 2);
2505 }
2506
2507 #[test]
2508 fn index_mut() {
2509 let mut m = Matrix::<u8>::new(3, 2).unwrap();
2510
2511 m[(1, 0)] = 5;
2512 m[(2, 1)] = 3;
2513 m[(0, 0)] = 1;
2514 assert_eq!(m.data, vec![1, 0, 5, 0, 0, 3]);
2515 }
2516
2517 #[test]
2518 fn add_assign() {
2519 let mut m1 = Matrix::<i8>::new(4, 4).unwrap();
2520 let m2 = Matrix::<i8>::new_identity(4);
2521 let m3 = Matrix::new_from_data(&vec![
2522 vec![1, 2, 3, 4],
2523 vec![5, 6, 7, 8],
2524 vec![8, 7, 6, 5],
2525 vec![4, 3, 2, 1],
2526 ])
2527 .unwrap();
2528
2529 m1 += m2;
2530 assert_eq!(
2531 m1.data,
2532 vec![1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
2533 );
2534 m1 += m3;
2535 assert_eq!(
2536 m1.data,
2537 vec![2, 2, 3, 4, 5, 7, 7, 8, 8, 7, 7, 5, 4, 3, 2, 2]
2538 );
2539 }
2540
2541 mod add {
2542 use super::*;
2543
2544 #[test]
2545 fn handles_errors() {
2546 let m1 = Matrix::<u8>::new(4, 4).unwrap();
2547 let m2 = Matrix::<u8>::new(3, 4).unwrap();
2548 let m3 = Matrix::<u8>::new(4, 5).unwrap();
2549 let m4 = Matrix::<u8>::new(3, 5).unwrap();
2550
2551 assert_eq!(&m1 + &m2, Err(SizingError::Row(3)));
2552 assert_eq!(&m1 + &m3, Err(SizingError::Column(5)));
2553 assert_eq!(m1 + m4, Err(SizingError::Both(3, 5)));
2554 }
2555
2556 #[test]
2557 fn adds() {
2558 let m = Matrix::<i8>::new_identity(4);
2559
2560 assert_eq!(
2561 (&m + &Matrix::<i8>::new(4, 4).unwrap()).unwrap().data,
2562 vec![1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
2563 );
2564 assert_eq!(
2565 (m + Matrix::new_from_data(&vec![
2566 vec![1, 2, 3, 4],
2567 vec![5, 6, 7, 8],
2568 vec![8, 7, 6, 5],
2569 vec![4, 3, 2, 1],
2570 ])
2571 .unwrap())
2572 .unwrap()
2573 .data,
2574 vec![2, 2, 3, 4, 5, 7, 7, 8, 8, 7, 7, 5, 4, 3, 2, 2]
2575 );
2576 }
2577 }
2578
2579 #[test]
2580 fn sub_assign() {
2581 let m1 = Matrix::<i8>::new(4, 4).unwrap();
2582 let mut m2 = Matrix::<i8>::new_identity(4);
2583 let m3 = Matrix::new_from_data(&vec![
2584 vec![1, 2, 3, 4],
2585 vec![5, 6, 7, 8],
2586 vec![8, 7, 6, 5],
2587 vec![4, 3, 2, 1],
2588 ])
2589 .unwrap();
2590
2591 m2 -= m1;
2592 assert_eq!(
2593 m2.data,
2594 vec![1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
2595 );
2596 m2 -= m3;
2597 assert_eq!(
2598 m2.data,
2599 vec![0, -2, -3, -4, -5, -5, -7, -8, -8, -7, -5, -5, -4, -3, -2, 0]
2600 );
2601 }
2602
2603 mod sub {
2604 use super::*;
2605
2606 #[test]
2607 fn handles_errors() {
2608 let m1 = Matrix::<u8>::new(4, 4).unwrap();
2609 let m2 = Matrix::<u8>::new(3, 4).unwrap();
2610 let m3 = Matrix::<u8>::new(4, 5).unwrap();
2611 let m4 = Matrix::<u8>::new(3, 5).unwrap();
2612
2613 assert_eq!(&m1 - &m2, Err(SizingError::Row(3)));
2614 assert_eq!(&m1 - &m3, Err(SizingError::Column(5)));
2615 assert_eq!(m1 - m4, Err(SizingError::Both(3, 5)));
2616 }
2617
2618 #[test]
2619 fn subs() {
2620 let m = Matrix::<i8>::new_identity(4);
2621
2622 assert_eq!(
2623 (&m - &Matrix::<i8>::new(4, 4).unwrap()).unwrap().data,
2624 vec![1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
2625 );
2626 assert_eq!(
2627 (m - Matrix::new_from_data(&vec![
2628 vec![1, 2, 3, 4],
2629 vec![5, 6, 7, 8],
2630 vec![8, 7, 6, 5],
2631 vec![4, 3, 2, 1],
2632 ])
2633 .unwrap())
2634 .unwrap()
2635 .data,
2636 vec![0, -2, -3, -4, -5, -5, -7, -8, -8, -7, -5, -5, -4, -3, -2, 0]
2637 );
2638 }
2639 }
2640
2641 mod mul {
2642 use super::*;
2643
2644 #[test]
2645 fn handles_errors() {
2646 let m1 = Matrix::<u16>::new(2, 5).unwrap();
2647 let m2 = Matrix::<u16>::new(4, 2).unwrap();
2648
2649 assert_eq!(m1 * m2, Err(4));
2650 }
2651
2652 #[test]
2653 fn muls() {
2654 let m1 = Matrix::new_from_data(&vec![
2655 vec![1, 6, 3],
2656 vec![3, 7, 2],
2657 vec![5, 4, 8],
2658 vec![5, 6, 9],
2659 ])
2660 .unwrap();
2661 let m2 = Matrix::new_from_data(&vec![
2662 vec![2, 7, 5, 7],
2663 vec![9, 1, 8, 3],
2664 vec![2, 4, 6, 5],
2665 ])
2666 .unwrap();
2667 let m3 = Matrix::<i8>::new_identity(3);
2668
2669 assert_eq!(
2670 &m1 * &m2,
2671 Ok(Matrix {
2672 data: vec![
2673 62, 25, 71, 40, 73, 36, 83, 52, 62, 71, 105, 87, 82, 77, 127, 98
2674 ],
2675 rows: 4,
2676 columns: 4
2677 })
2678 );
2679 assert_eq!((&m1 * &m3).unwrap(), m1);
2680 }
2681 }
2682
2683 #[test]
2684 fn neg() {
2685 let m1 = Matrix::<i32>::new_identity(3);
2686
2687 assert_eq!(m1.neg().data, vec![-1, 0, 0, 0, -1, 0, 0, 0, -1]);
2688 }
2689
2690 #[test]
2691 fn default() {
2692 let m = Matrix::<u8>::default();
2693
2694 assert_eq!(
2695 m,
2696 Matrix {
2697 data: vec![],
2698 rows: 0,
2699 columns: 0
2700 }
2701 );
2702 }
2703 }
2704}