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}