Expand description
Iterators over parts of a Matrix
- Over a row: Row(Reference)(Mut)Iterator
- Over a column: Column(Reference)(Mut)Iterator
- Over all data in row major order: RowMajor(Reference)(Mut)(Owned)Iterator
- Over all data in column major order: ColumnMajor(Reference)(Mut)(Owned)Iterator
- Over the main diagonal: Diagonal(Reference)(Mut)Iterator
§Examples
Extending a matrix with new columns
use easy_ml::matrices::Matrix;
// we start with some matrix where the first and second columns correspond
// to x and y points
let mut matrix = Matrix::from(vec![
vec![ 3.0, 4.0 ],
vec![ 8.0, 1.0 ],
vec![ 2.0, 9.0 ]]);
// insert a third column based on the formula x * y
matrix.insert_column_with(2, matrix.column_iter(0)
// join together the x and y columns
.zip(matrix.column_iter(1))
// compute the values for the new column
.map(|(x, y)| x * y)
// Collect into a vector so we stop immutably borrowing from `matrix`.
// This is only neccessary when we use the data from a Matrix to modify itself,
// because the rust compiler enforces that we do not mutably and immutably borrow
// something at the same time. If we used data from a different Matrix to update
// `matrix` then we could stop at map and pass the iterator directly.
.collect::<Vec<f64>>()
// now that the Vec created owns the data for the new column and we have stopped
// borrowing immutably from `matrix` we turn the vec back into an iterator and
// mutably borrow `matrix` to add the new column
.drain(..));
assert_eq!(matrix.get(0, 2), 3.0 * 4.0);
assert_eq!(matrix.get(1, 2), 8.0 * 1.0);
assert_eq!(matrix.get(2, 2), 2.0 * 9.0);
§Matrix layout and iterator performance
Internally the Matrix type uses a flattened array with row major storage of the data. Due to CPU cache lines this means row major access of elements is likely to be faster than column major indexing, once a matrix is large enough, so you should favor iterating through each row.
use easy_ml::matrices::Matrix;
let matrix = Matrix::from(vec![
vec![ 1, 2 ],
vec![ 3, 4 ]]);
// storage of elements is [1, 2, 3, 4]
// row major access
for row in 0..2 {
for column in 0..2 {
println!("{}", matrix.get(row, column));
}
} // -> 1 2 3 4
matrix.row_major_iter().for_each(|e| println!("{}", e)); // -> 1 2 3 4
matrix.row_major_iter().with_index().for_each(|e| println!("{:?}", e)); // -> ((0, 0), 1) ((0, 1), 2), ((1, 0), 3), ((1, 1), 4)
// column major access
for column in 0..2 {
for row in 0..2 {
println!("{}", matrix.get(row, column));
}
} // -> 1 3 2 4
matrix.column_major_iter().for_each(|e| println!("{}", e)); // -> 1 3 2 4
matrix.column_major_iter().with_index().for_each(|e| println!("{:?}", e)); // // -> ((0, 0), 1), ((1, 0), 3), ((0, 1), 2), ((1, 1), 4)
Iterators are also able to elide array indexing bounds checks which may improve performance over explicit calls to get or get_reference in a loop, however you can use unsafe getters to elide bounds checks in loops as well so you are not forced to use iterators even if the checks are a performance concern.
Structs§
- An iterator over a column in a matrix.
- A column major iterator over all values in a matrix.
- A column major iterator over all values in a matrix.
- A column major iterator over references to all values in a matrix.
- A column major iterator over mutable references to all values in a matrix.
- An iterator over references to a column in a matrix.
- An iterator over mutable references to a column in a matrix.
- An iterator over the main diagonal in a matrix.
- An iterator over references to the main diagonal in a matrix.
- An iterator over mutable references to the main diagonal in a matrix.
- An iterator over a row in a matrix.
- A row major iterator over all values in a matrix.
- A row major iterator over all values in a matrix.
- A row major iterator over references to all values in a matrix.
- A row major iterator over mutable references to all values in a matrix.
- An iterator over references to a row in a matrix.
- An iterator over mutable references to a row in a matrix.
- A wrapper around another iterator that iterates through each element in the iterator and includes the index used to access the element.