pub struct Matrix<T: MatrixElementRequiredTraits<T>> {
pub n: usize,
pub m: usize,
pub entries: Vec<T>,
}
Fields§
§n: usize
§m: usize
§entries: Vec<T>
Implementations§
Source§impl<T: MatrixElementRequiredTraits<T>> Matrix<T>
impl<T: MatrixElementRequiredTraits<T>> Matrix<T>
Sourcepub fn new(m: usize, n: usize, entries: Vec<T>) -> Self
pub fn new(m: usize, n: usize, entries: Vec<T>) -> Self
Standard initializer for a Matrix
Takes dimensions m
(number of rows) and n
(number of columns)
together with a vector representing the elements. The number of elements
should be equal to m
x n
use matrix::matrix_algebra::Matrix;
let test_matrix = Matrix::new(2, 3, [1.0, 2.0, -1.0, 0.0, 3.0, 7.0].to_vec());
println!("{test_matrix}");
Will output
⌜1 2 -1 ⌝
⌞0 3 7 ⌟
Sourcepub fn new_constant_value(
m: usize,
n: usize,
value: T,
) -> Result<Self, &'static str>
pub fn new_constant_value( m: usize, n: usize, value: T, ) -> Result<Self, &'static str>
Convenience initializer to initialize a matrix of dimension m x n with all entries equal to the provided value
use matrix::matrix_algebra::Matrix;
let test_matrix = Matrix::new_constant_value(2, 3, 5.0).expect("Unable to initialize matrix");
println!("{test_matrix}");
/// Will output
/// ⌜5 5 5 ⌝
/// ⌞5 5 5 ⌟
Sourcepub fn get_entry_ij(&self, i: usize, j: usize) -> &T
pub fn get_entry_ij(&self, i: usize, j: usize) -> &T
Getter for entry at position i,j (zero indexed) Returns a reference to the entry
use matrix::matrix_algebra::Matrix;
let test_matrix = Matrix::new(2, 3, [1.0, 2.0, -1.0, 0.0, 3.0, 7.0].to_vec());
let entry = test_matrix.get_entry_ij(1, 1);
println!("{entry}");
Will output
3
Sourcepub fn set_entry_ij(&mut self, i: usize, j: usize, new_value: &T)
pub fn set_entry_ij(&mut self, i: usize, j: usize, new_value: &T)
Setter for entry at position i, j (zero indexed)
use matrix::matrix_algebra::Matrix;
let mut test_matrix = Matrix::new(2, 3, [1.0, 2.0, -1.0, 0.0, 3.0, 7.0].to_vec());
let entry = test_matrix.get_entry_ij(1, 1);
println!("{entry}");
test_matrix.set_entry_ij(1, 1, &4.0);
let entry = test_matrix.get_entry_ij(1, 1);
println!("{entry}");
Will output:
3
4
Sourcepub fn rows(&self) -> Vec<Vec<T>>
pub fn rows(&self) -> Vec<Vec<T>>
Retrieves the rows of a matrix
use matrix::matrix_algebra::Matrix;
let mut test_matrix = Matrix::new(2, 3, [1.0, 2.0, -1.0, 0.0, 3.0, 7.0].to_vec());
let rows = test_matrix.rows();
Sourcepub fn row_interchange(
&self,
first_row_index: usize,
second_row_index: usize,
) -> Self
pub fn row_interchange( &self, first_row_index: usize, second_row_index: usize, ) -> Self
The first elementary operation on a matrix Returns a new matrix with the rows at the specified indices interchanged.
use matrix::matrix_algebra::Matrix;
let test_matrix = Matrix::new(2, 3, [1.0, 2.0, 3.0, 4.0, 5.0, 6.0].to_vec());
let result = test_matrix.row_interchange(0, 1);
assert_eq!(
result,
Matrix::new(2, 3, [4.0, 5.0, 6.0, 1.0, 2.0, 3.0].to_vec()),
);
Sourcepub fn multiply_row_by_scalar(&self, row_index: usize, scalar: T) -> Self
pub fn multiply_row_by_scalar(&self, row_index: usize, scalar: T) -> Self
The second elementary operation on a matrix Returns a new matrix with all elements in the row at the specified index multiplied by the specified scalar.
use matrix::matrix_algebra::Matrix;
let test_matrix = Matrix::new(3, 3, [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0].to_vec());
let result = test_matrix.multiply_row_by_scalar(2, 2.0);
assert_eq!(
result,
Matrix::new(
3,
3,
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 14.0, 16.0, 18.0].to_vec()
),
);
Sourcepub fn add_row_to_scalar_multiple_of_row(
&self,
target_index: usize,
source_index: usize,
scalar: T,
) -> Self
pub fn add_row_to_scalar_multiple_of_row( &self, target_index: usize, source_index: usize, scalar: T, ) -> Self
The third elementary operation on a matrix Adds a scalar multiple of a row to an existing row in a matrix
use matrix::matrix_algebra::Matrix;
let test_matrix = Matrix::new(3, 3, [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0].to_vec());
let result = test_matrix.add_row_to_scalar_multiple_of_row(0, 2, 5.0);
assert_eq!(
result,
Matrix::new(
3,
3,
[36.0, 42.0, 48.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0].to_vec()
),
);
Sourcepub fn row_echolon_form(&self) -> Self
pub fn row_echolon_form(&self) -> Self
Reduces a matrix to Row Echolon Form
use matrix::matrix_algebra::Matrix;
let test_matrix = Matrix::new(
3,
4,
[
0.0, 0.0, 3.0, -1.0, 0.0, -1.0, 4.0, 7.0, 0.0, -1.0, 7.0, 6.0,
]
.to_vec(),
);
let result = test_matrix.row_echolon_form();
assert_eq!(
result,
Matrix::new(
3,
4,
[
0.0,
1.0,
0.0,
-25.0 / 3.0,
0.0,
0.0,
1.0,
-1.0 / 3.0,
0.0,
0.0,
0.0,
0.0
]
.to_vec()
),
);
Sourcepub fn column_echolon_form(&self) -> Self
pub fn column_echolon_form(&self) -> Self
Reduces a matrix to column echolon form
use matrix::matrix_algebra::Matrix;
let test_matrix = Matrix::new(2, 3, [1.0, 2.0, 3.0, 2.0, 3.0, 4.0].to_vec());
let result = test_matrix.column_echolon_form();
assert_eq!(
result,
Matrix::new(2, 3, [1.0, 0.0, 0.0, 0.0, 1.0, 0.0,].to_vec())
);
let test_matrix = Matrix::new(3, 3, [1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0].to_vec());
let result = test_matrix.column_echolon_form();
assert_eq!(
result,
Matrix::new(3, 3, [1.0, 0.0, 0.0, 2.0, 0.0, 0.0, 3.0, 0.0, 0.0].to_vec())
);
Sourcepub fn columns(&self) -> Vec<Vec<T>>
pub fn columns(&self) -> Vec<Vec<T>>
Convenience function that extracts the columns of a matrix
use matrix::matrix_algebra::Matrix;
let test_matrix = Matrix::new(
3,
4,
[
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0,
]
.to_vec(),
);
let columns = test_matrix.columns();
assert_eq!(columns.len(), 4);
assert_eq!(columns[0], vec![1.0, 5.0, 9.0]);
assert_eq!(columns[1], vec![2.0, 6.0, 10.0]);
assert_eq!(columns[2], vec![3.0, 7.0, 11.0]);
assert_eq!(columns[3], vec![4.0, 8.0, 12.0]);
Sourcepub fn transpose(&self) -> Self
pub fn transpose(&self) -> Self
Creates a transpose of a matrix
use matrix::matrix_algebra::Matrix;
let test_matrix = Matrix::new(2, 3, [1.0, 2.0, -1.0, 0.0, 3.0, 7.0].to_vec());
let transpose_matrix = test_matrix.transpose();
assert_eq!(transpose_matrix.m, test_matrix.n);
assert_eq!(transpose_matrix.n, test_matrix.m);
assert_eq!(transpose_matrix.entries, [1.0, 0.0, 2.0, 3.0, -1.0, 7.0]);
Sourcepub fn determinant(&self) -> Result<T, &'static str>
pub fn determinant(&self) -> Result<T, &'static str>
Calculates the determinant of a matrix The following example shows that there can be some rounding issues with the calculations.
use matrix::matrix_algebra::Matrix;
use matrix::complex_number::ComplexNumber;
let test_matrix = Matrix::new(
3,
3,
[
ComplexNumber::new(1.0, 0.0),
ComplexNumber::new(1.0, 0.0),
ComplexNumber::new(0.0, 1.0),
ComplexNumber::new(1.0, 1.0),
ComplexNumber::new(1.0, 1.0),
ComplexNumber::new(1.0, 0.0),
ComplexNumber::new(2.0, 3.0),
ComplexNumber::new(0.0, -1.0),
ComplexNumber::new(3.0, 0.0),
]
.to_vec(),
);
let determinant = test_matrix.determinant();
fn delta_real(determinant: ComplexNumber<f64>, expectation: f64) -> bool {
determinant.real - expectation < (1.0 / 1000000000000000000000000000000.0)
}
fn delta_complex(determinant: ComplexNumber<f64>, expectation: f64) -> bool {
determinant.complex - expectation < (1.0 / 1000000000000000000000000000000.0)
}
assert!(delta_real(
determinant.expect("Unable to calculate determinant"),
8.0
));
assert!(delta_complex(
determinant.expect("Unable to calculate determinant"),
6.0
));
Sourcepub fn minor(
&self,
column_indices: &[usize],
row_indices: &[usize],
) -> Result<T, &'static str>
pub fn minor( &self, column_indices: &[usize], row_indices: &[usize], ) -> Result<T, &'static str>
Calculates the minor of a matrix (the determinant of a given submatrix) based on the provided column indices and row indices to be selected from the matrix
use matrix::matrix_algebra::Matrix;
let test_matrix = Matrix::new(3, 3, [1.0, 2.0, 1.0, 6.0, -1.0, 0.0, -1.0, -2.0, -1.0].to_vec());
assert_eq!(test_matrix.minor(&[1, 2], &[1,2]).expect("Unable to create minor"), 1.0);
assert_eq!(test_matrix.minor(&[0, 2], &[1,2]).expect("Unable to create minor"), -6.0);
assert_eq!(test_matrix.minor(&[0, 1], &[0,1]).expect("Unable to create minor"), -13.0);
Sourcepub fn is_nonsingular(&self) -> Result<bool, &'static str>
pub fn is_nonsingular(&self) -> Result<bool, &'static str>
Convenience function to identify a non-singular matrix
Sourcepub fn matrix_of_cofactors(&self) -> Result<Self, &'static str>
pub fn matrix_of_cofactors(&self) -> Result<Self, &'static str>
Creates a matrix of cofactors from a matrix
Sourcepub fn adjoint(&self) -> Result<Self, &'static str>
pub fn adjoint(&self) -> Result<Self, &'static str>
Caluculates the adjoint of a matrix
use matrix::matrix_algebra::Matrix;
let test_matrix = Matrix::new(3, 3, [3.0, 4.0, 3.0, 5.0, 7.0, 2.0, 0.0, 0.0, 1.0].to_vec());
assert_eq!(
test_matrix
.adjoint()
.expect("test_adjoint: unable to calculate matrix adjoint"),
Matrix::new(
3,
3,
[
7.0,
-4.0,
-13.0,
-5.0,
3.0,
9.0,
0.0,
0.0,
1.0000000000000018
]
.to_vec()
)
);
Sourcepub fn inverse(&self) -> Result<Self, &'static str>
pub fn inverse(&self) -> Result<Self, &'static str>
Calculates the inverse of a matrix
use matrix::matrix_algebra::Matrix;
let test_matrix = Matrix::new(
3,
3,
[2.0, 3.0, 0.0, 0.0, 3.0, -3.0, -2.0, 3.0, 3.0].to_vec(),
);
let inverse = test_matrix
.inverse()
.expect("Unable to compute matrix inverse in test_inverse");
assert_eq!(inverse.m, 3);
assert_eq!(inverse.n, 3);
let expected = [
1.0 / 3.0,
-1.0 / 6.0,
-1.0 / 6.0,
1.0 / 9.0,
1.0 / 9.0,
1.0 / 9.0,
1.0 / 9.0,
-2.0 / 9.0,
1.0 / 9.0,
]
.to_vec();
for i in 0..expected.len() {
assert!(expected[i] - inverse.entries[i] < 1.0 / 1000000000000000.0);
}
Sourcepub fn partition(
&self,
column_partitioning: &[usize],
row_partitioning: &[usize],
) -> Vec<Self>
pub fn partition( &self, column_partitioning: &[usize], row_partitioning: &[usize], ) -> Vec<Self>
Partitions a matrix based on the provided column and row indices
use matrix::matrix_algebra::Matrix;
let test_matrix = Matrix::new(
5,
5,
[
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0,
]
.to_vec(),
);
let submatrices = test_matrix.partition(&[3, 2], &[2, 3]);
assert_eq!(
submatrices,
[
Matrix::new(2, 3, [1.0, 2.0, 3.0, 6.0, 7.0, 8.0].to_vec()),
Matrix::new(2, 2, [4.0, 5.0, 9.0, 10.0].to_vec()),
Matrix::new(
3,
3,
[11.0, 12.0, 13.0, 16.0, 17.0, 18.0, 21.0, 22.0, 23.0].to_vec()
),
Matrix::new(3, 2, [14.0, 15.0, 19.0, 20.0, 24.0, 25.0].to_vec())
]
);
Sourcepub fn submatrix(&self, column_indices: &[usize], row_indices: &[usize]) -> Self
pub fn submatrix(&self, column_indices: &[usize], row_indices: &[usize]) -> Self
Generates a submatrix based on the provided column and row indices
use matrix::matrix_algebra::Matrix;
let test_matrix = Matrix::new(
5,
5,
[
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0,
]
.to_vec(),
);
let submatrix = test_matrix.submatrix(&[1, 3], &[0, 2, 4]);
assert_eq!(submatrix.n, 2);
assert_eq!(submatrix.m, 3);
assert_eq!(submatrix.entries, [2.0, 4.0, 12.0, 14.0, 22.0, 24.0]);
Trait Implementations§
Source§impl<T: MatrixElementRequiredTraits<T>> Add for Matrix<T>
Implementation of the Add
trait for Matrix<T>
Uses matrix_add
impl<T: MatrixElementRequiredTraits<T>> Add for Matrix<T>
Implementation of the Add
trait for Matrix<T>
Uses matrix_add
Source§impl<T: MatrixElementRequiredTraits<T>> Display for Matrix<T>
Implementation of the Display trait for Matrix
which can be used for debugging purposes
impl<T: MatrixElementRequiredTraits<T>> Display for Matrix<T>
Implementation of the Display trait for Matrix
Source§impl<T: MatrixElementRequiredTraits<T>> Mul for Matrix<T>
Implementation of the Mul
trait for Matrix<T>
Uses matrix_multiply
impl<T: MatrixElementRequiredTraits<T>> Mul for Matrix<T>
Implementation of the Mul
trait for Matrix<T>
Uses matrix_multiply
use matrix::matrix_algebra::Matrix;
let test_matrix_a = Matrix::new(
3,
4,
[
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0,
]
.to_vec(),
);
let test_matrix_b = Matrix::new(
4,
3,
[
12.0, 11.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0,
]
.to_vec(),
);
let matrix_product = test_matrix_a * test_matrix_b;
assert_eq!(matrix_product.entries.len(), 9);
assert_eq!(
matrix_product.entries,
[
1.0 * 12.0 + 2.0 * 9.0 + 3.0 * 6.0 + 4.0 * 3.0,
1.0 * 11.0 + 2.0 * 8.0 + 3.0 * 5.0 + 4.0 * 2.0,
1.0 * 10.0 + 2.0 * 7.0 + 3.0 * 4.0 + 4.0 * 1.0,
5.0 * 12.0 + 6.0 * 9.0 + 7.0 * 6.0 + 8.0 * 3.0,
5.0 * 11.0 + 6.0 * 8.0 + 7.0 * 5.0 + 8.0 * 2.0,
5.0 * 10.0 + 6.0 * 7.0 + 7.0 * 4.0 + 8.0 * 1.0,
9.0 * 12.0 + 10.0 * 9.0 + 11.0 * 6.0 + 12.0 * 3.0,
9.0 * 11.0 + 10.0 * 8.0 + 11.0 * 5.0 + 12.0 * 2.0,
9.0 * 10.0 + 10.0 * 7.0 + 11.0 * 4.0 + 12.0 * 1.0
]
);