orx_v/matrices/
matrix_mut.rs

1use super::Matrix;
2use crate::{IntoIdx, D2};
3
4/// A mutable matrix view over a `D2` vector with rectangular cardinality,
5/// or over a flattened representation by a `D1` vector.
6///
7/// A mutable matrix view can be created by:
8/// * calling [`as_matrix_mut`] or [`as_matrix_col_major_mut`] methods on a `D2`
9///   vector implementing `NVecMut<D2, _>`, or equivalently, `V2Mut<_>`; or by:
10/// * calling [`as_matrix_mut`] or [`as_matrix_col_major_mut`] methods on a `D1`
11///   vector implementing `NVecMut<D1, _>`, or equivalently, `V1Mut<_>`.
12///
13/// Alternatively an owned mutable matrix can be crated by
14/// * calling [`into_matrix`] method on a `D2` mutable vector; or by:
15/// * calling [`v1_into_matrix`] method on a `D1` mutable vector.
16///
17/// [`into_matrix`]: crate::V2AsMatrix::into_matrix
18/// [`as_matrix_mut`]: crate::V2AsMatrix::as_matrix_mut
19/// [`as_matrix_col_major_mut`]: crate::V2AsMatrix::as_matrix_col_major_mut
20/// [`v1_into_matrix`]: crate::V1AsMatrix::v1_into_matrix
21/// [`as_matrix_mut`]: crate::V1AsMatrix::as_matrix_mut
22/// [`as_matrix_col_major_mut`]: crate::V1AsMatrix::as_matrix_col_major_mut
23pub trait MatrixMut<T>: Matrix<T> {
24    /// Returns a mutable reference to the element at the given `idx` of the matrix.
25    ///
26    /// # Panics
27    ///
28    /// Panics if the `idx` is not `in_bounds`.
29    fn at_mut<Idx: IntoIdx<D2>>(&mut self, idx: Idx) -> &mut T;
30
31    /// Sets the element at the given `idx` of the matrix to the `value`.
32    ///
33    /// # Panics
34    ///
35    /// Panics if the `idx` is not `in_bounds`.
36    fn set<Idx: IntoIdx<D2>>(&mut self, idx: Idx, value: T) {
37        *self.at_mut(idx) = value;
38    }
39
40    /// Applies the mutating function `f` over all elements of the matrix.
41    fn mut_all<F>(&mut self, f: F)
42    where
43        F: FnMut(&mut T);
44
45    /// Sets all elements of the matrix to the given `value`.
46    /// This method is often used at initialization stage of algorithms.
47    ///
48    /// # Examples
49    ///
50    /// ```
51    /// use orx_v::*;
52    ///
53    /// let mut v2 =[
54    ///     [1, 2, 3],
55    ///     [4, 5, 6],
56    /// ];
57    /// let mut mat = v2.as_matrix_mut();
58    /// mat.reset_all(42);
59    /// assert_eq!(
60    ///     mat.equality(&[[42, 42, 42], [42, 42, 42]].as_matrix()),
61    ///     Equality::<D2>::Equal,
62    /// );
63    /// ```
64    ///
65    /// Or more practically, consider the Dijkstra's shortest path algorithm as implemented in the
66    /// [Algorithms](https://github.com/TianyiShi2001/Algorithms/blob/main/src/graph/shortest_path/dijkstra.rs)
67    /// repository.
68    ///
69    /// In addition to a priority queue, the implementation uses a distances vector throughout the
70    /// search. One way to avoid re-allocation of such internal data, we often cache and reuse them.
71    /// In such a case, we need to set all elements of this vector to infinity on initialization,
72    /// where `reset_all` method is useful.
73    ///
74    /// ```ignore
75    /// use orx_v::*;
76    ///
77    /// impl WeightedAdjacencyList {
78    ///     fn dijkstra(&mut self, start: usize, end: usize) -> Option<(f64, Vec<usize>)> {
79    ///         // initialization
80    ///         self.distances.reset_all(f64::INFINITY);
81    ///         ...
82    ///
83    ///         // search
84    ///         while let Some((node, cur_dist)) = pq.pop() {
85    ///             ...
86    ///         }
87    ///         ...
88    ///     }
89    /// }
90    /// ```
91    fn reset_all(&mut self, value: T)
92    where
93        T: PartialEq + Copy;
94
95    // provided
96
97    /// Returns a mutable reference to the element at the `idx`-th
98    /// position of the matrix if the index is `in_bounds`;
99    /// returns None otherwise.
100    fn try_at_mut(&mut self, idx: impl IntoIdx<D2>) -> Option<&mut T> {
101        let [i, j] = idx.into_idx();
102        match i < self.num_rows() && j < self.num_cols() {
103            true => Some(self.at_mut(idx)),
104            false => None,
105        }
106    }
107}
108
109// &mut V auto impl
110
111impl<T, M: MatrixMut<T>> MatrixMut<T> for &mut M {
112    fn at_mut<Idx: IntoIdx<D2>>(&mut self, idx: Idx) -> &mut T {
113        <M as MatrixMut<T>>::at_mut(self, idx)
114    }
115
116    fn mut_all<F>(&mut self, f: F)
117    where
118        F: FnMut(&mut T),
119    {
120        <M as MatrixMut<T>>::mut_all(self, f);
121    }
122
123    fn reset_all(&mut self, value: T)
124    where
125        T: PartialEq + Copy,
126    {
127        <M as MatrixMut<T>>::reset_all(self, value);
128    }
129}