pub struct Matrix<T> { /* private fields */ }
Expand description
A general purpose matrix of some type. This type may implement
no traits, in which case the matrix will be rather useless. If the
type implements Clone
most storage and accessor methods are defined and if the type
implements Numeric
then the matrix can be used in
a mathematical way.
When doing numeric operations with Matrices you should be careful to not
consume a matrix by accidentally using it by value. All the operations are
also defined on references to matrices so you should favor &x * &y
style
notation for matrices you intend to continue using. There are also convenience
operations defined for a matrix and a scalar.
§Matrix size invariants
Matrices must always be at least 1x1. You cannot construct a matrix with no rows or
no columns, and any function that resizes matrices will error if you try to use it
in a way that would construct a 0x1, 1x0, or 0x0 matrix. The maximum size of a matrix
is dependent on the platform’s std::isize::MAX
value. Matrices with dimensions NxM
such that N * M < std::isize::MAX
should not cause any errors in this library, but
attempting to expand their size further may cause panics and or errors. At the time of
writing it is no longer possible to construct or use matrices where the product of their
number of rows and columns exceed std::isize::MAX
, but some constructor methods may be used
to attempt this. Concerned readers should note that on a 64 bit computer this maximum
value is 9,223,372,036,854,775,807 so running out of memory is likely to occur first.
§Matrix layout and iterator performance
See iterators submodule for Matrix layout and iterator performance
§Matrix operations
Implementations§
source§impl<T> Matrix<T>
impl<T> Matrix<T>
Methods for matrices of any type, including non numerical types such as bool.
sourcepub fn from_scalar(value: T) -> Matrix<T>
pub fn from_scalar(value: T) -> Matrix<T>
Creates a 1x1 matrix from some scalar
sourcepub fn row(values: Vec<T>) -> Matrix<T>
pub fn row(values: Vec<T>) -> Matrix<T>
Creates a row vector (1xN) from a list
§Panics
Panics if no values are provided. Note: this method erroneously did not validate its inputs in Easy ML versions up to and including 1.7.0
sourcepub fn column(values: Vec<T>) -> Matrix<T>
pub fn column(values: Vec<T>) -> Matrix<T>
Creates a column vector (Nx1) from a list
§Panics
Panics if no values are provided. Note: this method erroneously did not validate its inputs in Easy ML versions up to and including 1.7.0
sourcepub fn from(values: Vec<Vec<T>>) -> Matrix<T>
pub fn from(values: Vec<Vec<T>>) -> Matrix<T>
Creates a matrix from a nested array of values, each inner vector being a row, and hence the outer vector containing all rows in sequence, the same way as when writing matrices in mathematics.
Example of a 2 x 3 matrix in both notations:
[
1, 2, 4
8, 9, 3
]
use easy_ml::matrices::Matrix;
Matrix::from(vec![
vec![ 1, 2, 4 ],
vec![ 8, 9, 3 ]
]);
§Panics
Panics if the input is jagged or rows or column length is 0.
sourcepub fn from_flat_row_major(size: (Row, Column), values: Vec<T>) -> Matrix<T>
pub fn from_flat_row_major(size: (Row, Column), values: Vec<T>) -> Matrix<T>
Creates a matrix with the specified size from a row major vec of data. The length of the vec must match the size of the matrix or the constructor will panic.
Example of a 2 x 3 matrix in both notations:
[
1, 2, 4
8, 9, 3
]
use easy_ml::matrices::Matrix;
Matrix::from_flat_row_major((2, 3), vec![
1, 2, 4,
8, 9, 3
]);
This method is more efficient than Matrix::from
but requires specifying the size explicitly and manually keeping track of where rows
start and stop.
§Panics
Panics if the length of the vec does not match the size of the matrix, or no values are provided. Note: this method erroneously did not validate its inputs were not empty in Easy ML versions up to and including 1.7.0
sourcepub fn from_fn<F>(size: (Row, Column), producer: F) -> Matrix<T>
pub fn from_fn<F>(size: (Row, Column), producer: F) -> Matrix<T>
Creates a matrix with the specified size initalised from a function.
use easy_ml::matrices::Matrix;
let matrix = Matrix::from_fn((4, 4), |(r, c)| r * c);
assert_eq!(
matrix,
Matrix::from(vec![
vec![ 0, 0, 0, 0 ],
vec![ 0, 1, 2, 3 ],
vec![ 0, 2, 4, 6 ],
vec![ 0, 3, 6, 9 ],
])
);
§Panics
Panics if the size has 0 rows or columns.
pub fn unit(value: T) -> Matrix<T>
from_scalar
insteadsourcepub fn size(&self) -> (Row, Column)
pub fn size(&self) -> (Row, Column)
Returns the dimensionality of this matrix in Row, Column format
sourcepub fn get_reference(&self, row: Row, column: Column) -> &T
pub fn get_reference(&self, row: Row, column: Column) -> &T
Gets a reference to the value at this row and column. Rows and Columns are 0 indexed.
§Panics
Panics if the index is out of range.
sourcepub fn get_reference_mut(&mut self, row: Row, column: Column) -> &mut T
pub fn get_reference_mut(&mut self, row: Row, column: Column) -> &mut T
Gets a mutable reference to the value at this row and column. Rows and Columns are 0 indexed.
§Panics
Panics if the index is out of range.
sourcepub fn set(&mut self, row: Row, column: Column, value: T)
pub fn set(&mut self, row: Row, column: Column, value: T)
Sets a new value to this row and column. Rows and Columns are 0 indexed.
§Panics
Panics if the index is out of range.
sourcepub fn remove_row(&mut self, row: Row)
pub fn remove_row(&mut self, row: Row)
Removes a row from this Matrix, shifting all other rows to the left. Rows are 0 indexed.
§Panics
This will panic if the row does not exist or the matrix only has one row.
sourcepub fn remove_column(&mut self, column: Column)
pub fn remove_column(&mut self, column: Column)
Removes a column from this Matrix, shifting all other columns to the left. Columns are 0 indexed.
§Panics
This will panic if the column does not exist or the matrix only has one column.
sourcepub fn column_reference_iter(
&self,
column: Column
) -> ColumnReferenceIterator<'_, T> ⓘ
pub fn column_reference_iter( &self, column: Column ) -> ColumnReferenceIterator<'_, T> ⓘ
Returns an iterator over references to a column vector in this matrix. Columns are 0 indexed.
§Panics
Panics if the column does not exist in this matrix.
sourcepub fn row_reference_iter(&self, row: Row) -> RowReferenceIterator<'_, T> ⓘ
pub fn row_reference_iter(&self, row: Row) -> RowReferenceIterator<'_, T> ⓘ
Returns an iterator over references to a row vector in this matrix. Rows are 0 indexed.
§Panics
Panics if the row does not exist in this matrix.
sourcepub fn column_reference_mut_iter(
&mut self,
column: Column
) -> ColumnReferenceMutIterator<'_, T> ⓘ
pub fn column_reference_mut_iter( &mut self, column: Column ) -> ColumnReferenceMutIterator<'_, T> ⓘ
Returns an iterator over mutable references to a column vector in this matrix. Columns are 0 indexed.
§Panics
Panics if the column does not exist in this matrix.
sourcepub fn row_reference_mut_iter(
&mut self,
row: Row
) -> RowReferenceMutIterator<'_, T> ⓘ
pub fn row_reference_mut_iter( &mut self, row: Row ) -> RowReferenceMutIterator<'_, T> ⓘ
Returns an iterator over mutable references to a row vector in this matrix. Rows are 0 indexed.
§Panics
Panics if the row does not exist in this matrix.
sourcepub fn column_major_reference_iter(&self) -> ColumnMajorReferenceIterator<'_, T> ⓘ
pub fn column_major_reference_iter(&self) -> ColumnMajorReferenceIterator<'_, T> ⓘ
Returns a column major iterator over references to all values in this matrix, proceeding through each column in order.
sourcepub fn row_major_reference_iter(&self) -> RowMajorReferenceIterator<'_, T> ⓘ
pub fn row_major_reference_iter(&self) -> RowMajorReferenceIterator<'_, T> ⓘ
Returns a row major iterator over references to all values in this matrix, proceeding through each row in order.
sourcepub fn column_major_reference_mut_iter(
&mut self
) -> ColumnMajorReferenceMutIterator<'_, T> ⓘ
pub fn column_major_reference_mut_iter( &mut self ) -> ColumnMajorReferenceMutIterator<'_, T> ⓘ
Returns a column major iterator over mutable references to all values in this matrix, proceeding through each column in order.
sourcepub fn row_major_reference_mut_iter(
&mut self
) -> RowMajorReferenceMutIterator<'_, T> ⓘ
pub fn row_major_reference_mut_iter( &mut self ) -> RowMajorReferenceMutIterator<'_, T> ⓘ
Returns a row major iterator over mutable references to all values in this matrix, proceeding through each row in order.
sourcepub fn column_major_owned_iter(self) -> ColumnMajorOwnedIterator<T> ⓘwhere
T: Default,
pub fn column_major_owned_iter(self) -> ColumnMajorOwnedIterator<T> ⓘwhere
T: Default,
Creates a column major iterator over all values in this matrix, proceeding through each column in order.
sourcepub fn row_major_owned_iter(self) -> RowMajorOwnedIterator<T> ⓘwhere
T: Default,
pub fn row_major_owned_iter(self) -> RowMajorOwnedIterator<T> ⓘwhere
T: Default,
Creates a row major iterator over all values in this matrix, proceeding through each row in order.
sourcepub fn diagonal_reference_iter(&self) -> DiagonalReferenceIterator<'_, T> ⓘ
pub fn diagonal_reference_iter(&self) -> DiagonalReferenceIterator<'_, T> ⓘ
Returns an iterator over references to the main diagonal in this matrix.
sourcepub fn diagonal_reference_mut_iter(
&mut self
) -> DiagonalReferenceMutIterator<'_, T> ⓘ
pub fn diagonal_reference_mut_iter( &mut self ) -> DiagonalReferenceMutIterator<'_, T> ⓘ
Returns an iterator over mutable references to the main diagonal in this matrix.
sourcepub fn retain_mut(&mut self, slice: Slice2D)
pub fn retain_mut(&mut self, slice: Slice2D)
Shrinks this matrix down from its current MxN size down to some new size OxP where O and P are determined by the kind of slice given and 1 <= O <= M and 1 <= P <= N.
Only rows and columns specified by the slice will be retained, so for
instance if the Slice is constructed by
Slice2D::new().rows(Slice::Range(0..2)).columns(Slice::Range(0..3))
then the
modified matrix will be no bigger than 2x3 and contain up to the first two
rows and first three columns that it previously had.
See Slice for constructing slices.
§Panics
This function will panic if the slice would delete all rows or all columns from this matrix, ie the resulting matrix must be at least 1x1.
sourcepub fn try_into_scalar(self) -> Result<T, ScalarConversionError>
pub fn try_into_scalar(self) -> Result<T, ScalarConversionError>
Consumes a 1x1 matrix and converts it into a scalar without copying the data.
§Example
use easy_ml::matrices::Matrix;
let x = Matrix::column(vec![ 1.0, 2.0, 3.0 ]);
let sum_of_squares: f64 = (x.transpose() * x).try_into_scalar()?;
sourcepub fn partition(
&mut self,
row_partitions: &[Row],
column_partitions: &[Column]
) -> Vec<MatrixView<T, MatrixPart<'_, T>>>
pub fn partition( &mut self, row_partitions: &[Row], column_partitions: &[Column] ) -> Vec<MatrixView<T, MatrixPart<'_, T>>>
Partition a matrix into an arbitary number of non overlapping parts.
This function is much like a hammer you should be careful to not overuse. If you don’t need to mutate the parts of the matrix data individually it will be much easier and less error prone to create immutable views into the matrix using MatrixRange instead.
Parts are returned in row major order, forming a grid of slices into the Matrix data that can be mutated independently.
§Panics
Panics if any row or column index is greater than the number of rows or columns in the matrix. Each list of row partitions and column partitions must also be in ascending order.
§Further Info
The partitions form the boundries between each slice of matrix data. Hence, for each dimension, each partition may range between 0 and the length of the dimension inclusive.
For one dimension of length 5, you can supply 0 up to 6 partitions,
[0,1,2,3,4,5]
would split that dimension into 7, 0 to 0, 0 to 1, 1 to 2,
2 to 3, 3 to 4, 4 to 5 and 5 to 5. 0 to 0 and 5 to 5 would of course be empty and the
5 parts in between would each be of length 1 along that dimension.
[2,4]
would instead split that dimension into three parts of 0 to 2, 2 to 4, and 4 to 5.
[]
would not split that dimension at all, and give a single part of 0 to 5.
partition
does this along both dimensions, and returns the parts in row major order, so
you will receive a list of R+1 * C+1 length where R is the length of the row partitions
provided and C is the length of the column partitions provided. If you just want to split
a matrix into a 2x2 grid see partition_quadrants
which
provides a dedicated API with more ergonomics for extracting the parts.
sourcepub fn partition_quadrants<'a>(
&'a mut self,
row: Row,
column: Column
) -> MatrixQuadrants<'a, T>
pub fn partition_quadrants<'a>( &'a mut self, row: Row, column: Column ) -> MatrixQuadrants<'a, T>
Partition a matrix into 4 non overlapping quadrants. Top left starts at 0,0 until exclusive of row and column, bottom right starts at row and column to the end of the matrix.
§Panics
Panics if the row or column are greater than the number of rows or columns in the matrix.
§Examples
use easy_ml::matrices::Matrix;
let mut matrix = Matrix::from(vec![
vec![ 0, 1, 2 ],
vec![ 3, 4, 5 ],
vec![ 6, 7, 8 ]
]);
// Split the matrix at the second row and first column giving 2x1, 2x2, 1x1 and 2x1
// quadrants.
// 0 | 1 2
// 3 | 4 5
// -------
// 6 | 7 8
let mut parts = matrix.partition_quadrants(2, 1);
assert_eq!(parts.top_left, Matrix::column(vec![ 0, 3 ]));
assert_eq!(parts.top_right, Matrix::from(vec![vec![ 1, 2 ], vec![ 4, 5 ]]));
assert_eq!(parts.bottom_left, Matrix::column(vec![ 6 ]));
assert_eq!(parts.bottom_right, Matrix::row(vec![ 7, 8 ]));
// Modify the matrix data independently without worrying about the borrow checker
parts.top_right.map_mut(|x| x + 10);
parts.bottom_left.map_mut(|x| x - 10);
// Drop MatrixQuadrants so we can use the matrix directly again
std::mem::drop(parts);
assert_eq!(matrix, Matrix::from(vec![
vec![ 0, 11, 12 ],
vec![ 3, 14, 15 ],
vec![ -4, 7, 8 ]
]));
sourcepub fn into_tensor(
self,
rows: Dimension,
columns: Dimension
) -> Result<Tensor<T, 2>, InvalidShapeError<2>>
pub fn into_tensor( self, rows: Dimension, columns: Dimension ) -> Result<Tensor<T, 2>, InvalidShapeError<2>>
Converts this Matrix into a 2 dimensional Tensor with the provided dimension names.
This is a wrapper around the TryFrom<(Matrix<T>, [Dimension; 2])>
implementation.
The Tensor will have the data in the same order, a shape with lengths of self.rows()
then
self.columns()
and the provided dimension names respectively.
Result::Err is returned if the rows
and columns
dimension names are the same.
source§impl<T: Clone> Matrix<T>
impl<T: Clone> Matrix<T>
Methods for matrices with types that can be copied, but still not neccessarily numerical.
sourcepub fn transpose(&self) -> Matrix<T>
pub fn transpose(&self) -> Matrix<T>
Computes and returns the transpose of this matrix
use easy_ml::matrices::Matrix;
let x = Matrix::from(vec![
vec![ 1, 2 ],
vec![ 3, 4 ]]);
let y = Matrix::from(vec![
vec![ 1, 3 ],
vec![ 2, 4 ]]);
assert_eq!(x.transpose(), y);
sourcepub fn transpose_mut(&mut self)
pub fn transpose_mut(&mut self)
Transposes the matrix in place (if it is square).
use easy_ml::matrices::Matrix;
let mut x = Matrix::from(vec![
vec![ 1, 2 ],
vec![ 3, 4 ]]);
x.transpose_mut();
let y = Matrix::from(vec![
vec![ 1, 3 ],
vec![ 2, 4 ]]);
assert_eq!(x, y);
Note: None square matrices were erroneously not supported in previous versions (<=1.8.0) and could be incorrectly mutated. This method will now correctly transpose non square matrices by not attempting to transpose them in place.
sourcepub fn column_iter(&self, column: Column) -> ColumnIterator<'_, T> ⓘ
pub fn column_iter(&self, column: Column) -> ColumnIterator<'_, T> ⓘ
Returns an iterator over a column vector in this matrix. Columns are 0 indexed.
If you have a matrix such as:
[
1, 2, 3
4, 5, 6
7, 8, 9
]
then a column of 0, 1, and 2 will yield [1, 4, 7], [2, 5, 8] and [3, 6, 9]
respectively. If you do not need to copy the elements use
column_reference_iter
instead.
§Panics
Panics if the column does not exist in this matrix.
sourcepub fn row_iter(&self, row: Row) -> RowIterator<'_, T> ⓘ
pub fn row_iter(&self, row: Row) -> RowIterator<'_, T> ⓘ
Returns an iterator over a row vector in this matrix. Rows are 0 indexed.
If you have a matrix such as:
[
1, 2, 3
4, 5, 6
7, 8, 9
]
then a row of 0, 1, and 2 will yield [1, 2, 3], [4, 5, 6] and [7, 8, 9]
respectively. If you do not need to copy the elements use
row_reference_iter
instead.
§Panics
Panics if the row does not exist in this matrix.
sourcepub fn column_major_iter(&self) -> ColumnMajorIterator<'_, T> ⓘ
pub fn column_major_iter(&self) -> ColumnMajorIterator<'_, T> ⓘ
Returns a column major iterator over all values in this matrix, proceeding through each column in order.
If you have a matrix such as:
[
1, 2
3, 4
]
then the iterator will yield [1, 3, 2, 4]. If you do not need to copy the
elements use column_major_reference_iter
instead.
sourcepub fn row_major_iter(&self) -> RowMajorIterator<'_, T> ⓘ
pub fn row_major_iter(&self) -> RowMajorIterator<'_, T> ⓘ
Returns a row major iterator over all values in this matrix, proceeding through each row in order.
If you have a matrix such as:
[
1, 2
3, 4
]
then the iterator will yield [1, 2, 3, 4]. If you do not need to copy the
elements use row_major_reference_iter
instead.
sourcepub fn diagonal_iter(&self) -> DiagonalIterator<'_, T> ⓘ
pub fn diagonal_iter(&self) -> DiagonalIterator<'_, T> ⓘ
Returns a iterator over the main diagonal of this matrix.
If you have a matrix such as:
[
1, 2
3, 4
]
then the iterator will yield [1, 4]. If you do not need to copy the
elements use diagonal_reference_iter
instead.
§Examples
Computing a trace
use easy_ml::matrices::Matrix;
let matrix = Matrix::from(vec![
vec![ 1, 2, 3 ],
vec![ 4, 5, 6 ],
vec![ 7, 8, 9 ],
]);
let trace: i32 = matrix.diagonal_iter().sum();
assert_eq!(trace, 1 + 5 + 9);
sourcepub fn empty(value: T, size: (Row, Column)) -> Matrix<T>
pub fn empty(value: T, size: (Row, Column)) -> Matrix<T>
Creates a matrix of the provided size with all elements initialised to the provided value
§Panics
Panics if no values are provided. Note: this method erroneously did not validate its inputs in Easy ML versions up to and including 1.7.0
sourcepub fn get(&self, row: Row, column: Column) -> T
pub fn get(&self, row: Row, column: Column) -> T
Gets a copy of the value at this row and column. Rows and Columns are 0 indexed.
§Panics
Panics if the index is out of range.
sourcepub fn scalar(&self) -> T
pub fn scalar(&self) -> T
Similar to matrix.get(0, 0) in that this returns the element in the first row and first column, except that this method will panic if the matrix is not 1x1.
This is provided as a convenience function when you want to convert a unit matrix to a scalar, such as after taking a dot product of two vectors.
§Example
use easy_ml::matrices::Matrix;
let x = Matrix::column(vec![ 1.0, 2.0, 3.0 ]);
let sum_of_squares: f64 = (x.transpose() * x).scalar();
§Panics
Panics if the matrix is not 1x1
sourcepub fn map_mut(&mut self, mapping_function: impl Fn(T) -> T)
pub fn map_mut(&mut self, mapping_function: impl Fn(T) -> T)
Applies a function to all values in the matrix, modifying the matrix in place.
sourcepub fn map_mut_with_index(
&mut self,
mapping_function: impl Fn(T, Row, Column) -> T
)
pub fn map_mut_with_index( &mut self, mapping_function: impl Fn(T, Row, Column) -> T )
Applies a function to all values and each value’s index in the matrix, modifying the matrix in place.
sourcepub fn map<U>(&self, mapping_function: impl Fn(T) -> U) -> Matrix<U>where
U: Clone,
pub fn map<U>(&self, mapping_function: impl Fn(T) -> U) -> Matrix<U>where
U: Clone,
Creates and returns a new matrix with all values from the original with the function applied to each. This can be used to change the type of the matrix such as creating a mask:
use easy_ml::matrices::Matrix;
let x = Matrix::from(vec![
vec![ 0.0, 1.2 ],
vec![ 5.8, 6.9 ]]);
let y = x.map(|element| element > 2.0);
let result = Matrix::from(vec![
vec![ false, false ],
vec![ true, true ]]);
assert_eq!(&y, &result);
sourcepub fn map_with_index<U>(
&self,
mapping_function: impl Fn(T, Row, Column) -> U
) -> Matrix<U>where
U: Clone,
pub fn map_with_index<U>(
&self,
mapping_function: impl Fn(T, Row, Column) -> U
) -> Matrix<U>where
U: Clone,
Creates and returns a new matrix with all values from the original and the index of each value mapped by a function. This can be used to perform elementwise operations that are not defined on the Matrix type itself.
§Exmples
Matrix elementwise division:
use easy_ml::matrices::Matrix;
let x = Matrix::from(vec![
vec![ 9.0, 2.0 ],
vec![ 4.0, 3.0 ]]);
let y = Matrix::from(vec![
vec![ 3.0, 2.0 ],
vec![ 1.0, 3.0 ]]);
let z = x.map_with_index(|x, row, column| x / y.get(row, column));
let result = Matrix::from(vec![
vec![ 3.0, 1.0 ],
vec![ 4.0, 1.0 ]]);
assert_eq!(&z, &result);
sourcepub fn insert_row(&mut self, row: Row, value: T)
pub fn insert_row(&mut self, row: Row, value: T)
Inserts a new row into the Matrix at the provided index, shifting other rows to the right and filling all entries with the provided value. Rows are 0 indexed.
§Panics
This will panic if the row is greater than the number of rows in the matrix.
sourcepub fn insert_row_with<I>(&mut self, row: Row, values: I)where
I: Iterator<Item = T>,
pub fn insert_row_with<I>(&mut self, row: Row, values: I)where
I: Iterator<Item = T>,
Inserts a new row into the Matrix at the provided index, shifting other rows to the right and filling all entries with the values from the iterator in sequence. Rows are 0 indexed.
§Panics
This will panic if the row is greater than the number of rows in the matrix,
or if the iterator has fewer elements than self.columns()
.
Example of duplicating a row:
use easy_ml::matrices::Matrix;
let x: Matrix<u8> = Matrix::row(vec![ 1, 2, 3 ]);
let mut y = x.clone();
// duplicate the first row as the second row
y.insert_row_with(1, x.row_iter(0));
assert_eq!((2, 3), y.size());
let mut values = y.column_major_iter();
assert_eq!(Some(1), values.next());
assert_eq!(Some(1), values.next());
assert_eq!(Some(2), values.next());
assert_eq!(Some(2), values.next());
assert_eq!(Some(3), values.next());
assert_eq!(Some(3), values.next());
assert_eq!(None, values.next());
sourcepub fn insert_column(&mut self, column: Column, value: T)
pub fn insert_column(&mut self, column: Column, value: T)
Inserts a new column into the Matrix at the provided index, shifting other columns to the right and filling all entries with the provided value. Columns are 0 indexed.
§Panics
This will panic if the column is greater than the number of columns in the matrix.
sourcepub fn insert_column_with<I>(&mut self, column: Column, values: I)where
I: Iterator<Item = T>,
pub fn insert_column_with<I>(&mut self, column: Column, values: I)where
I: Iterator<Item = T>,
Inserts a new column into the Matrix at the provided index, shifting other columns to the right and filling all entries with the values from the iterator in sequence. Columns are 0 indexed.
§Panics
This will panic if the column is greater than the number of columns in the matrix,
or if the iterator has fewer elements than self.rows()
.
Example of duplicating a column:
use easy_ml::matrices::Matrix;
let x: Matrix<u8> = Matrix::column(vec![ 1, 2, 3 ]);
let mut y = x.clone();
// duplicate the first column as the second column
y.insert_column_with(1, x.column_iter(0));
assert_eq!((3, 2), y.size());
let mut values = y.column_major_iter();
assert_eq!(Some(1), values.next());
assert_eq!(Some(2), values.next());
assert_eq!(Some(3), values.next());
assert_eq!(Some(1), values.next());
assert_eq!(Some(2), values.next());
assert_eq!(Some(3), values.next());
assert_eq!(None, values.next());
sourcepub fn retain(&self, slice: Slice2D) -> Matrix<T>
pub fn retain(&self, slice: Slice2D) -> Matrix<T>
Makes a copy of this matrix shrunk down in size according to the slice. See retain_mut.
source§impl<T: Numeric> Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Methods for matrices with numerical types, such as f32 or f64.
Note that unsigned integers are not Numeric because they do not implement Neg. You must first wrap unsigned integers via Wrapping or Saturating.
While these methods will all be defined on signed integer types as well, such as i16 or i32, in many cases integers cannot be used sensibly in these computations. If you have a matrix of type i8 for example, you should consider mapping it into a floating type before doing heavy linear algebra maths on it.
Determinants can be computed without loss of precision using sufficiently large signed integers because the only operations performed on the elements are addition, subtraction and mulitplication. However the inverse of a matrix such as
[
4, 7
2, 8
]
is
[
0.6, -0.7,
-0.2, 0.4
]
which requires a type that supports decimals to accurately represent.
Mapping matrix type example:
use easy_ml::matrices::Matrix;
use std::num::Wrapping;
let matrix: Matrix<u8> = Matrix::from(vec![
vec![ 2, 3 ],
vec![ 6, 0 ]
]);
// determinant is not defined on this matrix because u8 is not Numeric
// println!("{:?}", matrix.determinant()); // won't compile
// however Wrapping<u8> is numeric
let matrix = matrix.map(|element| Wrapping(element));
println!("{:?}", matrix.determinant()); // -> 238 (overflow)
println!("{:?}", matrix.map(|element| element.0 as i16).determinant()); // -> -18
println!("{:?}", matrix.map(|element| element.0 as f32).determinant()); // -> -18.0
sourcepub fn determinant(&self) -> Option<T>
pub fn determinant(&self) -> Option<T>
Returns the determinant of this square matrix, or None if the matrix
does not have a determinant. See linear_algebra
sourcepub fn inverse(&self) -> Option<Matrix<T>>
pub fn inverse(&self) -> Option<Matrix<T>>
Computes the inverse of a matrix provided that it exists. To have an inverse a
matrix must be square (same number of rows and columns) and it must also have a
non zero determinant. See linear_algebra
sourcepub fn covariance_column_features(&self) -> Matrix<T>
pub fn covariance_column_features(&self) -> Matrix<T>
Computes the covariance matrix for this NxM feature matrix, in which
each N’th row has M features to find the covariance and variance of. See
linear_algebra
sourcepub fn covariance_row_features(&self) -> Matrix<T>
pub fn covariance_row_features(&self) -> Matrix<T>
Computes the covariance matrix for this NxM feature matrix, in which
each M’th column has N features to find the covariance and variance of. See
linear_algebra
source§impl<T: Numeric + Real> Matrix<T>
impl<T: Numeric + Real> Matrix<T>
Methods for matrices with numerical real valued types, such as f32 or f64.
This excludes signed and unsigned integers as they do not support decimal precision and hence can’t be used for operations like square roots.
Third party fixed precision and infinite precision decimal types should be able to implement all of the methods for Real and then utilise these functions.
sourcepub fn euclidean_length(&self) -> T
pub fn euclidean_length(&self) -> T
Computes the L2 norm of this row or column vector, also referred to as the length or magnitude, and written as ||x||, or sometimes |x|.
||a|| = sqrt(a12 + a22 + a32…) = sqrt(aT * a)
This is a shorthand for (x.transpose() * x).scalar().sqrt()
for
column vectors and (x * x.transpose()).scalar().sqrt()
for row vectors, ie
the square root of the dot product of a vector with itself.
The euclidean length can be used to compute a unit vector, that is, a vector with length of 1. This should not be confused with a unit matrix, which is another name for an identity matrix.
use easy_ml::matrices::Matrix;
let a = Matrix::column(vec![ 1.0, 2.0, 3.0 ]);
let length = a.euclidean_length(); // (1^2 + 2^2 + 3^2)^0.5
let unit = a / length;
assert_eq!(unit.euclidean_length(), 1.0);
§Panics
If the matrix is not a vector, ie if it has more than one row and more than one column.
source§impl<T: Numeric> Matrix<T>
impl<T: Numeric> Matrix<T>
sourcepub fn diagonal(value: T, size: (Row, Column)) -> Matrix<T>
pub fn diagonal(value: T, size: (Row, Column)) -> Matrix<T>
Creates a diagonal matrix of the provided size with the diagonal elements set to the provided value and all other elements in the matrix set to 0. A diagonal matrix is always square.
The size is still taken as a tuple to facilitate creating a diagonal matrix from the dimensionality of an existing one. If the provided value is 1 then this will create an identity matrix.
A 3 x 3 identity matrix:
[
1, 0, 0
0, 1, 0
0, 0, 1
]
§Panics
If the provided size is not square.
sourcepub fn from_diagonal(values: Vec<T>) -> Matrix<T>
pub fn from_diagonal(values: Vec<T>) -> Matrix<T>
Creates a diagonal matrix with the elements along the diagonal set to the provided values and all other elements in the matrix set to 0. A diagonal matrix is always square.
Examples
use easy_ml::matrices::Matrix;
let matrix = Matrix::from_diagonal(vec![ 1, 1, 1 ]);
assert_eq!(matrix.size(), (3, 3));
let copy = Matrix::from_diagonal(matrix.diagonal_iter().collect());
assert_eq!(matrix, copy);
assert_eq!(matrix, Matrix::from(vec![
vec![ 1, 0, 0 ],
vec![ 0, 1, 0 ],
vec![ 0, 0, 1 ],
]))
Trait Implementations§
source§impl<T, S> Add<&Matrix<T>> for &MatrixView<T, S>
impl<T, S> Add<&Matrix<T>> for &MatrixView<T, S>
Elementwise addition for a referenced matrix view and a referenced matrix
source§impl<T> Add<&Matrix<T>> for Matrix<T>
impl<T> Add<&Matrix<T>> for Matrix<T>
Elementwise addition for two matrices with one referenced
source§impl<T, S> Add<&Matrix<T>> for MatrixView<T, S>
impl<T, S> Add<&Matrix<T>> for MatrixView<T, S>
Elementwise addition for a matrix view and a referenced matrix
source§impl<T, S> Add<&MatrixView<T, S>> for &Matrix<T>
impl<T, S> Add<&MatrixView<T, S>> for &Matrix<T>
Elementwise addition for a referenced matrix and a referenced matrix view
source§impl<T, S> Add<&MatrixView<T, S>> for Matrix<T>
impl<T, S> Add<&MatrixView<T, S>> for Matrix<T>
Elementwise addition for a matrix and a referenced matrix view
source§impl<T: Numeric> Add<&T> for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Add<&T> for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Operation for a matrix and scalar by reference. The scalar is applied to all elements, this is a shorthand for map().
source§impl<T: Numeric> Add<&T> for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Add<&T> for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Operation for a matrix by value and scalar by reference. The scalar is applied to all elements, this is a shorthand for map().
source§impl<T> Add<Matrix<T>> for &Matrix<T>
impl<T> Add<Matrix<T>> for &Matrix<T>
Elementwise addition for two matrices with one referenced
source§impl<T, S> Add<Matrix<T>> for &MatrixView<T, S>
impl<T, S> Add<Matrix<T>> for &MatrixView<T, S>
Elementwise addition for a referenced matrix view and a matrix
source§impl<T, S> Add<Matrix<T>> for MatrixView<T, S>
impl<T, S> Add<Matrix<T>> for MatrixView<T, S>
Elementwise addition for a matrix view and a matrix
source§impl<T, S> Add<MatrixView<T, S>> for &Matrix<T>
impl<T, S> Add<MatrixView<T, S>> for &Matrix<T>
Elementwise addition for a referenced matrix and a matrix view
source§impl<T, S> Add<MatrixView<T, S>> for Matrix<T>
impl<T, S> Add<MatrixView<T, S>> for Matrix<T>
Elementwise addition for a matrix and a matrix view
source§impl<T: Numeric> Add<T> for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Add<T> for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Operation for a matrix by reference and scalar by value. The scalar is applied to all elements, this is a shorthand for map().
source§impl<T: Numeric> Add<T> for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Add<T> for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Operation for a matrix and scalar by value. The scalar is applied to all elements, this is a shorthand for map().
source§impl<T: Display> Display for Matrix<T>
impl<T: Display> Display for Matrix<T>
Any matrix of a Displayable type implements Display
You can control the precision of the formatting using format arguments, i.e.
format!("{:.3}", matrix)
source§impl<T: Numeric> Div<&T> for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Div<&T> for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Operation for a matrix and scalar by reference. The scalar is applied to all elements, this is a shorthand for map().
source§impl<T: Numeric> Div<&T> for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Div<&T> for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Operation for a matrix by value and scalar by reference. The scalar is applied to all elements, this is a shorthand for map().
source§impl<T: Numeric> Div<T> for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Div<T> for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Operation for a matrix by reference and scalar by value. The scalar is applied to all elements, this is a shorthand for map().
source§impl<T: Numeric> Div<T> for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Div<T> for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Operation for a matrix and scalar by value. The scalar is applied to all elements, this is a shorthand for map().
source§impl<T> From<Tensor<T, 2>> for Matrix<T>
impl<T> From<Tensor<T, 2>> for Matrix<T>
Any 2 dimensional tensor can be converted to a matrix with rows equal to the length of the first dimension in the tensor, and columns equal to the length of the second.
source§impl<'source, T> MatrixMut<T> for &'source mut Matrix<T>
impl<'source, T> MatrixMut<T> for &'source mut Matrix<T>
An exclusive reference to a Matrix implements MatrixMut.
source§fn try_get_reference_mut(&mut self, row: Row, column: Column) -> Option<&mut T>
fn try_get_reference_mut(&mut self, row: Row, column: Column) -> Option<&mut T>
source§unsafe fn get_reference_unchecked_mut(
&mut self,
row: Row,
column: Column
) -> &mut T
unsafe fn get_reference_unchecked_mut( &mut self, row: Row, column: Column ) -> &mut T
source§impl<T> MatrixMut<T> for Matrix<T>
impl<T> MatrixMut<T> for Matrix<T>
An owned Matrix implements MatrixMut.
source§fn try_get_reference_mut(&mut self, row: Row, column: Column) -> Option<&mut T>
fn try_get_reference_mut(&mut self, row: Row, column: Column) -> Option<&mut T>
source§unsafe fn get_reference_unchecked_mut(
&mut self,
row: Row,
column: Column
) -> &mut T
unsafe fn get_reference_unchecked_mut( &mut self, row: Row, column: Column ) -> &mut T
source§impl<'source, T> MatrixRef<T> for &'source Matrix<T>
impl<'source, T> MatrixRef<T> for &'source Matrix<T>
A shared reference to a Matrix implements MatrixRef.
source§fn try_get_reference(&self, row: Row, column: Column) -> Option<&T>
fn try_get_reference(&self, row: Row, column: Column) -> Option<&T>
source§fn view_rows(&self) -> Row
fn view_rows(&self) -> Row
source§fn view_columns(&self) -> Column
fn view_columns(&self) -> Column
source§unsafe fn get_reference_unchecked(&self, row: Row, column: Column) -> &T
unsafe fn get_reference_unchecked(&self, row: Row, column: Column) -> &T
source§fn data_layout(&self) -> DataLayout
fn data_layout(&self) -> DataLayout
source§impl<'source, T> MatrixRef<T> for &'source mut Matrix<T>
impl<'source, T> MatrixRef<T> for &'source mut Matrix<T>
An exclusive reference to a Matrix implements MatrixRef.
source§fn try_get_reference(&self, row: Row, column: Column) -> Option<&T>
fn try_get_reference(&self, row: Row, column: Column) -> Option<&T>
source§fn view_rows(&self) -> Row
fn view_rows(&self) -> Row
source§fn view_columns(&self) -> Column
fn view_columns(&self) -> Column
source§unsafe fn get_reference_unchecked(&self, row: Row, column: Column) -> &T
unsafe fn get_reference_unchecked(&self, row: Row, column: Column) -> &T
source§fn data_layout(&self) -> DataLayout
fn data_layout(&self) -> DataLayout
source§impl<T> MatrixRef<T> for Matrix<T>
impl<T> MatrixRef<T> for Matrix<T>
An owned Matrix implements MatrixRef.
source§fn try_get_reference(&self, row: Row, column: Column) -> Option<&T>
fn try_get_reference(&self, row: Row, column: Column) -> Option<&T>
source§fn view_rows(&self) -> Row
fn view_rows(&self) -> Row
source§fn view_columns(&self) -> Column
fn view_columns(&self) -> Column
source§unsafe fn get_reference_unchecked(&self, row: Row, column: Column) -> &T
unsafe fn get_reference_unchecked(&self, row: Row, column: Column) -> &T
source§fn data_layout(&self) -> DataLayout
fn data_layout(&self) -> DataLayout
source§impl<T, S> Mul<&Matrix<T>> for &MatrixView<T, S>
impl<T, S> Mul<&Matrix<T>> for &MatrixView<T, S>
Matrix multiplication for a referenced matrix view and a referenced matrix
source§impl<T> Mul<&Matrix<T>> for Matrix<T>
impl<T> Mul<&Matrix<T>> for Matrix<T>
Matrix multiplication for two matrices with one referenced
source§impl<T, S> Mul<&Matrix<T>> for MatrixView<T, S>
impl<T, S> Mul<&Matrix<T>> for MatrixView<T, S>
Matrix multiplication for a matrix view and a referenced matrix
source§impl<T, S> Mul<&MatrixView<T, S>> for &Matrix<T>
impl<T, S> Mul<&MatrixView<T, S>> for &Matrix<T>
Matrix multiplication for a referenced matrix and a referenced matrix view
source§impl<T, S> Mul<&MatrixView<T, S>> for Matrix<T>
impl<T, S> Mul<&MatrixView<T, S>> for Matrix<T>
Matrix multiplication for a matrix and a referenced matrix view
source§impl<T: Numeric> Mul<&T> for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Mul<&T> for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Operation for a matrix and scalar by reference. The scalar is applied to all elements, this is a shorthand for map().
source§impl<T: Numeric> Mul<&T> for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Mul<&T> for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Operation for a matrix by value and scalar by reference. The scalar is applied to all elements, this is a shorthand for map().
source§impl<T> Mul<Matrix<T>> for &Matrix<T>
impl<T> Mul<Matrix<T>> for &Matrix<T>
Matrix multiplication for two matrices with one referenced
source§impl<T, S> Mul<Matrix<T>> for &MatrixView<T, S>
impl<T, S> Mul<Matrix<T>> for &MatrixView<T, S>
Matrix multiplication for a referenced matrix view and a matrix
source§impl<T, S> Mul<Matrix<T>> for MatrixView<T, S>
impl<T, S> Mul<Matrix<T>> for MatrixView<T, S>
Matrix multiplication for a matrix view and a matrix
source§impl<T, S> Mul<MatrixView<T, S>> for &Matrix<T>
impl<T, S> Mul<MatrixView<T, S>> for &Matrix<T>
Matrix multiplication for a referenced matrix and a matrix view
source§impl<T, S> Mul<MatrixView<T, S>> for Matrix<T>
impl<T, S> Mul<MatrixView<T, S>> for Matrix<T>
Matrix multiplication for a matrix and a matrix view
source§impl<T: Numeric> Mul<T> for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Mul<T> for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Operation for a matrix by reference and scalar by value. The scalar is applied to all elements, this is a shorthand for map().
source§impl<T: Numeric> Mul<T> for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Mul<T> for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Operation for a matrix and scalar by value. The scalar is applied to all elements, this is a shorthand for map().
source§impl<T: Numeric> Neg for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Neg for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Elementwise negation for a referenced matrix.
source§impl<T: Numeric> Neg for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Neg for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Elementwise negation for a matrix.
source§impl<T, S> PartialEq<Matrix<T>> for MatrixView<T, S>
impl<T, S> PartialEq<Matrix<T>> for MatrixView<T, S>
A MatrixView and a Matrix can be compared for equality. PartialEq is implemented as they are equal if and only if all their elements are equal and they have the same size.
source§impl<T, S> PartialEq<MatrixView<T, S>> for Matrix<T>
impl<T, S> PartialEq<MatrixView<T, S>> for Matrix<T>
A Matrix and a MatrixView can be compared for equality. PartialEq is implemented as they are equal if and only if all their elements are equal and they have the same size.
source§fn eq(&self, other: &MatrixView<T, S>) -> bool
fn eq(&self, other: &MatrixView<T, S>) -> bool
self
and other
values to be equal, and is used
by ==
.source§impl<T: PartialEq> PartialEq for Matrix<T>
impl<T: PartialEq> PartialEq for Matrix<T>
PartialEq is implemented as two matrices are equal if and only if all their elements are equal and they have the same size.
source§impl<T, S> Sub<&Matrix<T>> for &MatrixView<T, S>
impl<T, S> Sub<&Matrix<T>> for &MatrixView<T, S>
Elementwise subtraction for a referenced matrix view and a referenced matrix
source§impl<T> Sub<&Matrix<T>> for Matrix<T>
impl<T> Sub<&Matrix<T>> for Matrix<T>
Elementwise subtraction for two matrices with one referenced
source§impl<T, S> Sub<&Matrix<T>> for MatrixView<T, S>
impl<T, S> Sub<&Matrix<T>> for MatrixView<T, S>
Elementwise subtraction for a matrix view and a referenced matrix
source§impl<T, S> Sub<&MatrixView<T, S>> for &Matrix<T>
impl<T, S> Sub<&MatrixView<T, S>> for &Matrix<T>
Elementwise subtraction for a referenced matrix and a referenced matrix view
source§impl<T, S> Sub<&MatrixView<T, S>> for Matrix<T>
impl<T, S> Sub<&MatrixView<T, S>> for Matrix<T>
Elementwise subtraction for a matrix and a referenced matrix view
source§impl<T: Numeric> Sub<&T> for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Sub<&T> for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Operation for a matrix and scalar by reference. The scalar is applied to all elements, this is a shorthand for map().
source§impl<T: Numeric> Sub<&T> for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Sub<&T> for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Operation for a matrix by value and scalar by reference. The scalar is applied to all elements, this is a shorthand for map().
source§impl<T> Sub<Matrix<T>> for &Matrix<T>
impl<T> Sub<Matrix<T>> for &Matrix<T>
Elementwise subtraction for two matrices with one referenced
source§impl<T, S> Sub<Matrix<T>> for &MatrixView<T, S>
impl<T, S> Sub<Matrix<T>> for &MatrixView<T, S>
Elementwise subtraction for a referenced matrix view and a matrix
source§impl<T, S> Sub<Matrix<T>> for MatrixView<T, S>
impl<T, S> Sub<Matrix<T>> for MatrixView<T, S>
Elementwise subtraction for a matrix view and a matrix
source§impl<T, S> Sub<MatrixView<T, S>> for &Matrix<T>
impl<T, S> Sub<MatrixView<T, S>> for &Matrix<T>
Elementwise subtraction for a referenced matrix and a matrix view
source§impl<T, S> Sub<MatrixView<T, S>> for Matrix<T>
impl<T, S> Sub<MatrixView<T, S>> for Matrix<T>
Elementwise subtraction for a matrix and a matrix view
source§impl<T: Numeric> Sub<T> for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Sub<T> for &Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Operation for a matrix by reference and scalar by value. The scalar is applied to all elements, this is a shorthand for map().
source§impl<T: Numeric> Sub<T> for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
impl<T: Numeric> Sub<T> for Matrix<T>where
for<'a> &'a T: NumericRef<T>,
Operation for a matrix and scalar by value. The scalar is applied to all elements, this is a shorthand for map().
impl<'source, T> NoInteriorMutability for &'source Matrix<T>
A shared reference to a Matrix implements NoInteriorMutability.
impl<'source, T> NoInteriorMutability for &'source mut Matrix<T>
An exclusive reference to a Matrix implements NoInteriorMutability.
impl<T> NoInteriorMutability for Matrix<T>
An owned Matrix implements NoInteriorMutability.