matrixes/
lib.rs

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
22// constructors
23impl<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    /// Creates a new matrix with the specified rows and columns initialized to 0 or a sizing error.
36    ///
37    /// # Errors
38    ///
39    /// If one of rows or columns is zero, both must be zero.
40    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    /// Returns an Option to a new identity matrix with dimensions n x n.
60    ///
61    /// An identity matrix is a square matrix where the elements of the leading diagonal have a value of one and all other elements have a value of zero.
62    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    /// Creates a matrix with raw data of data, and columns of columns or a sizing error.
82    ///
83    /// # Errors
84    ///
85    /// data must have a length that is divisable by columns.
86    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    /// Creates a matrix from data, which must be a vec of rows of elements, or the index of the first row of an invalid length.
113    ///
114    /// # Errors
115    ///
116    /// If data has rows, rows must all be of the same, non-zero length.
117    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
150// getters
151impl<T> Matrix<T>
152where
153    T: Copy,
154{
155    /// Returns the data as a shared slice.
156    pub fn data(&self) -> &[T] {
157        &self.data
158    }
159
160    /// Returns the number of rows.
161    pub fn rows(&self) -> usize {
162        self.rows
163    }
164
165    /// Returns the number of columns.
166    pub fn columns(&self) -> usize {
167        self.columns
168    }
169
170    /// Returns the number of items in the matrix.
171    pub fn size(&self) -> usize {
172        self.data.len()
173    }
174
175    /// Returns whether the matrix is square in shape.
176    pub fn is_square(&self) -> bool {
177        self.rows == self.columns && self.rows != 0
178    }
179
180    /// Returns indexed row as an option to a vec of references.
181    ///
182    /// # Errors
183    ///
184    /// index must refer to a row that exists.
185    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    /// Returns an option to a vec of the rows indexed by the iterator.
194    ///
195    /// # Error
196    ///
197    /// All elements of rows must validly index the matrix.
198    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    /// Returns indexed column as an option to a vec of references.
203    ///
204    /// # Errors
205    ///
206    /// index must refer to a column that exists.
207    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    /// Returns an option to a vec of the columns indexed by the iterator.
216    ///
217    /// # Error
218    ///
219    /// All elements of columns must validly index the matrix.
220    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
227// mut getters
228impl<T> Matrix<T>
229where
230    T: Copy,
231{
232    /// Returns data as a mutable shared slice.
233    pub fn data_mut(&mut self) -> &mut [T] {
234        &mut self.data
235    }
236
237    /// Returns indexed row as an option to a vec of mutable references.
238    ///
239    /// # Errors
240    ///
241    /// index must refer to a row that exists.
242    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    /// Returns indexed column as an option to a vec of mutable references.
255    ///
256    /// # Errors
257    ///
258    /// index must refer to a column that exists.
259    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
274// swappers
275impl<T> Matrix<T>
276where
277    T: Copy + 'static,
278{
279    /// Swaps the indexed elements or returns an indexing error.
280    ///
281    /// # Errors
282    ///
283    /// el1 and el2 must refer to valid elements of the matrix
284    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    /// Swaps the indexed rows or returns the invalid row index.
321    ///
322    /// # Errors
323    ///
324    /// row1 and row2 must refer to rows that exist
325    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    /// Swaps the indexed columns or returns the invalid column index.
360    ///
361    /// # Errors
362    ///
363    /// col1 and col2 must refer to columns that exist.
364    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
399// operations
400impl<T> Matrix<T>
401where
402    T: Copy,
403{
404    /// Multiplies each element of the matrix by factor.
405    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    /// Multiplies each element of indexed row by factor or returns the invalid index.
415    ///
416    /// # Errors
417    ///
418    /// row must refer to a row that exists.
419    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    /// Adds source row scaled by factor to target row or returns the invalid index.
434    ///
435    /// # Errors
436    ///
437    /// source and target must refer to rows that exist.
438    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    /// Multiplies each element of indexed column by factor or returns the invalid index.
465    ///
466    /// # Errors
467    ///
468    /// column must refer to a column that exists.
469    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    /// Adds source column scaled by factor to target column or returns the invalid index.
484    ///
485    /// # Errors
486    ///
487    /// source and target must refer to columns that exist.
488    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    /// Edits the boundries of the matrix while maintaing capacity or returns an index error.
515    ///
516    /// # Errors
517    ///
518    /// bounds must have the same size as the matrix
519    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    /// Removes the data of the selected row and changes to bounds to match or returns the invalid index.
538    ///
539    /// Errors
540    ///
541    /// row must refer to a row that exists
542    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    /// Removes the data of the selected column and changes to bounds to match or returns the invalid index.
559    ///
560    /// Errors
561    ///
562    /// column must refer to a row that exists
563    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    /// Adds a row with an index of row and values of data or returns the an index error.
581    ///
582    /// Errors
583    ///
584    /// row must refer to a row adjacent to a row that exists, data must have the same number of elements as there are columns.
585    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    /// Adds a row with an index of row and values of data or returns an index error.
613    ///
614    /// Errors
615    ///
616    /// column must refer to a column adjacent to a row that exists, data must have the same number of elements as there are rows.
617    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    /// Adds content of other into new rows below the existing data or returns the invalid size.
645    ///
646    /// Errors
647    ///
648    /// other must have the same number of columns as the matrix.
649    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    /// Adds content of other into new rows above the existing data or returns the invalid size.
665    ///
666    /// Errors
667    ///
668    /// other must have the same number of columns as the matrix.
669    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    /// Adds content of other into new columns to the left of the existing data or returns the invalid size.
687    ///
688    /// Errors
689    ///
690    /// other must have the same number of rows as the matrix.
691    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    /// Adds content of other into new columns to the right of the existing data or returns the invalid size.
711    ///
712    /// Errors
713    ///
714    /// other must have the same number of rows as the matrix.
715    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
737// derivers
738impl<T> Matrix<T>
739where
740    T: Copy,
741{
742    /// Creates a transpose matrix, whose rows are equivalent to the base matrix's columns.
743    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    /// Returns the minor of the indexed element or a minor error.
758    ///
759    /// The minor is the determinant of the sub-matrix generated by removing the row and column of the indexed row.
760    ///
761    /// # Errors
762    ///
763    /// matrix must be square and indexed element must exist.
764    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    /// Returns an option to a new matrix constructed of the minors of each element of the matrix.
793    ///
794    /// # Errors
795    ///
796    /// Matrix must be square.
797    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    /// Returns an option to the matrix of minors with every other element negated.
818    ///
819    /// Matrix must be square.
820    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    /// Returns an option to the transpose of the cofactor of the matrix.
836    ///
837    /// # Errors
838    ///
839    /// Matrix must be square.
840    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    /// Returns an option to the determinant of the matrix.
848    ///
849    /// # Errors
850    ///
851    /// Matrix must be square.
852    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    /// Returns the adjunct scaled by the inverse of the determinant or an inversion error.
881    ///
882    /// # Errors
883    ///
884    /// Matrix must be square, determinant must not be zero.
885    ///
886    /// # Warning
887    ///
888    /// May give an incorrect result on types with strong rounding on division such as integers.
889    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    /// Returns the adjunct scaled by the inverse of the derminant or an inversion error.
912    ///
913    /// # Errors
914    ///
915    /// Matrix must be square, determinant must not be zero.
916    ///
917    /// # Warning
918    ///
919    /// May give an incorrect result or unwarrented error on types with strong rounding on division such as integers.
920    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    /// Returns with edited boundries while maintaining capacity or returns an index error.
962    ///
963    /// Errors
964    ///
965    /// Matrix of size bounds must fit the same amount of data as this.
966    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    /// # Panics
1044    ///
1045    /// rhs must have the same rows and columns as the matrix.
1046    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}