1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use crate::exact::MaybeExact;
use anyhow::Result;
pub trait EbiMatrix<T>:
Clone + MaybeExact + IdentityMinus + GaussJordan + TryFrom<Vec<Vec<T>>> + Eq
where
T: Clone,
{
/// Creates a new matrix with each value initialised to zeroes.
fn new(number_of_rows: usize, number_of_columns: usize) -> Self;
/// Add a number of rows and columns to the matrix, initialised to zeroes.
/// Does not decrease the size.
fn increase_size_to(&mut self, number_of_rows: usize, number_of_columns: usize) {
if self.number_of_columns() < number_of_columns {
self.push_columns(number_of_columns - self.number_of_columns());
}
if self.number_of_rows() < number_of_rows {
self.push_rows(number_of_rows - self.number_of_rows());
}
}
/// Returns the number of rows
fn number_of_rows(&self) -> usize;
/// Returns the number of columns
fn number_of_columns(&self) -> usize;
/// Gets a particular value of the matrix, if it exists.
fn get(&self, row: usize, column: usize) -> Option<T>;
/// Returns whether a value of the matrix is one.
/// If row and column do not exist, behaviour is undefined, and may panic.
fn is_one(&self, row: usize, column: usize) -> bool;
/// Returns whether a value of the matrix is larger than zero.
/// If row and column do not exist, behaviour is undefined, and may panic.
fn is_positive(&self, row: usize, column: usize) -> bool;
/// Returns whether a value of the matrix is larger than zero.
/// If row and column do not exist, behaviour is undefined, and may panic.
fn is_negative(&self, row: usize, column: usize) -> bool;
/// Sets a particular value of the matrix, if the row and column exist.
/// If row and column do not exist, behaviour is undefined, and may panic.
/// Prefer set_one and set_zero if possible.
fn set(&mut self, row: usize, column: usize, value: T);
/// Increases a particular value of the matrix, if the row and column exist.
/// If row and column do not exist, behaviour is undefined, and may panic.
fn increase(&mut self, row: usize, column: usize, value: &T);
/// Decreases a particular value of the matrix, if the row and column exist.
/// If row and column do not exist, behaviour is undefined, and may panic.
fn decrease(&mut self, row: usize, column: usize, value: &T);
/// Sets an entire row to zeroes.
/// If row does not exist, behaviour is undefined, and may panic.
fn set_row_zero(&mut self, row: usize);
/// Sets a particular value of the matrix to zero, if the row and column exist.
/// If row and column do not exist, behaviour is undefined, and may panic.
fn set_zero(&mut self, row: usize, column: usize);
/// Sets a particular value of the matrix to one, if the row and column exist.
/// If row and column do not exist, behaviour is undefined, and may panic.
fn set_one(&mut self, row: usize, column: usize);
/// Adds a number of columns to the right side of the matrix.
/// The added columns will be filled with zeroes.
fn push_columns(&mut self, number_of_columns_to_add: usize);
/// Adds a number of rows to the bottom of the matrix.
/// The added rows will be filled with zeroes.
fn push_rows(&mut self, number_of_rows_to_add: usize);
/// Removes columsn from the left of the matrix.
fn pop_front_columns(&mut self, number_of_columns_to_remove: usize);
/// Returns a vector of the matrix
fn to_vec(self) -> Vec<Vec<T>>;
}
pub trait IdentityMinus {
/// For a given matrix M, computes I-M.
/// The matrix does not need to be squared.
fn identity_minus(&mut self);
}
pub trait Inversion {
fn invert(self) -> Result<Self>
where
Self: Sized;
}
pub trait GaussJordan {
/// Applies Gaussian elimination to obtain a matrix in row echelon form.
fn gauss_jordan(&mut self);
/// Applies Gaussian elimination to obtain a matrix in reduced row echelon form.
fn gauss_jordan_reduced(self) -> Result<Self>
where
Self: Sized;
}