orx_v/matrices/matrix_mut.rs
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 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
use super::Matrix;
use crate::{IntoIdx, D2};
/// A mutable matrix view over a `D2` vector with rectangular cardinality,
/// or over a flattened representation by a `D1` vector.
///
/// A mutable matrix view can be created by:
/// * calling [`as_matrix_mut`] or [`as_matrix_col_major_mut`] methods on a `D2`
/// vector implementing `NVecMut<D2, _>`, or equivalently, `V2Mut<_>`; or by:
/// * calling [`as_matrix_mut`] or [`as_matrix_col_major_mut`] methods on a `D1`
/// vector implementing `NVecMut<D1, _>`, or equivalently, `V1Mut<_>`.
///
/// Alternatively an owned mutable matrix can be crated by
/// * calling [`into_matrix`] method on a `D2` mutable vector; or by:
/// * calling [`v1_into_matrix`] method on a `D1` mutable vector.
///
/// [`into_matrix`]: crate::V2AsMatrix::into_matrix
/// [`as_matrix_mut`]: crate::V2AsMatrix::as_matrix_mut
/// [`as_matrix_col_major_mut`]: crate::V2AsMatrix::as_matrix_col_major_mut
/// [`v1_into_matrix`]: crate::V1AsMatrix::v1_into_matrix
/// [`as_matrix_mut`]: crate::V1AsMatrix::as_matrix_mut
/// [`as_matrix_col_major_mut`]: crate::V1AsMatrix::as_matrix_col_major_mut
pub trait MatrixMut<T>: Matrix<T> {
/// Returns a mutable reference to the element at the given `idx` of the matrix.
///
/// # Panics
///
/// Panics if the `idx` is not `in_bounds`.
fn at_mut<Idx: IntoIdx<D2>>(&mut self, idx: Idx) -> &mut T;
/// Sets the element at the given `idx` of the matrix to the `value`.
///
/// # Panics
///
/// Panics if the `idx` is not `in_bounds`.
fn set<Idx: IntoIdx<D2>>(&mut self, idx: Idx, value: T) {
*self.at_mut(idx) = value;
}
/// Applies the mutating function `f` over all elements of the matrix.
fn mut_all<F>(&mut self, f: F)
where
F: FnMut(&mut T);
/// Sets all elements of the matrix to the given `value`.
/// This method is often used at initialization stage of algorithms.
///
/// # Examples
///
/// ```
/// use orx_v::*;
///
/// let mut v2 =[
/// [1, 2, 3],
/// [4, 5, 6],
/// ];
/// let mut mat = v2.as_matrix_mut();
/// mat.reset_all(42);
/// assert_eq!(
/// mat.equality(&[[42, 42, 42], [42, 42, 42]].as_matrix()),
/// Equality::<D2>::Equal,
/// );
/// ```
///
/// Or more practically, consider the Dijkstra's shortest path algorithm as implemented in the
/// [Algorithms](https://github.com/TianyiShi2001/Algorithms/blob/main/src/graph/shortest_path/dijkstra.rs)
/// repository.
///
/// In addition to a priority queue, the implementation uses a distances vector throughout the
/// search. One way to avoid re-allocation of such internal data, we often cache and reuse them.
/// In such a case, we need to set all elements of this vector to infinity on initialization,
/// where `reset_all` method is useful.
///
/// ```ignore
/// use orx_v::*;
///
/// impl WeightedAdjacencyList {
/// fn dijkstra(&mut self, start: usize, end: usize) -> Option<(f64, Vec<usize>)> {
/// // initialization
/// self.distances.reset_all(f64::INFINITY);
/// ...
///
/// // search
/// while let Some((node, cur_dist)) = pq.pop() {
/// ...
/// }
/// ...
/// }
/// }
/// ```
fn reset_all(&mut self, value: T)
where
T: PartialEq + Copy;
// provided
/// Returns a mutable reference to the element at the `idx`-th
/// position of the matrix if the index is `in_bounds`;
/// returns None otherwise.
fn try_at_mut(&mut self, idx: impl IntoIdx<D2>) -> Option<&mut T> {
let [i, j] = idx.into_idx();
match i < self.num_rows() && j < self.num_cols() {
true => Some(self.at_mut(idx)),
false => None,
}
}
}
// &mut V auto impl
impl<T, M: MatrixMut<T>> MatrixMut<T> for &mut M {
fn at_mut<Idx: IntoIdx<D2>>(&mut self, idx: Idx) -> &mut T {
<M as MatrixMut<T>>::at_mut(self, idx)
}
fn mut_all<F>(&mut self, f: F)
where
F: FnMut(&mut T),
{
<M as MatrixMut<T>>::mut_all(self, f);
}
fn reset_all(&mut self, value: T)
where
T: PartialEq + Copy,
{
<M as MatrixMut<T>>::reset_all(self, value);
}
}