mop_structs/matrix/dr_matrix/
mod.rs1mod dr_matrix_row_constructor;
2mod dr_matrix_row_iter_impls;
3#[cfg(feature = "rayon")]
4mod dr_matrix_row_par_iter_impls;
5
6pub use self::{
7 dr_matrix_row_constructor::DrMatrixRowConstructor,
8 dr_matrix_row_iter_impls::{DrMatrixRowIter, DrMatrixRowIterMut},
9};
10use crate::{
11 dim::Dim,
12 prelude::{Array, DynDenseStoMut, DynDenseStoRef, Matrix, StDenseStoMut, StDenseStoRef},
13 vec::VecArray,
14};
15
16#[cfg_attr(
17 feature = "serde1",
18 derive(mop_common_deps::serde::Deserialize, mop_common_deps::serde::Serialize)
19)]
20#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, PartialOrd)]
21pub struct DrMatrix<DS> {
22 data: DS,
23 dim: Dim<[usize; 2]>,
24}
25
26pub type DrMatrixArray<DA> = DrMatrix<DA>;
27pub type DrMatrixMut<'a, T> = DrMatrix<&'a mut [T]>;
28pub type DrMatrixRef<'a, T> = DrMatrix<&'a [T]>;
29#[cfg(feature = "std")]
30pub type DrMatrixVec<T> = DrMatrix<Vec<T>>;
31pub type DrMatrixVecArray<DA> = DrMatrix<VecArray<DA>>;
32
33impl<DS> DrMatrix<DS> {
34 #[inline]
35 fn stride(&self, idx: usize) -> usize {
36 self.cols() * idx
37 }
38}
39
40#[cfg(feature = "std")]
41impl<T> DrMatrixVec<T> {
42 #[cfg(feature = "rand")]
43 pub fn new_rnd<F, R>(shape: [usize; 2], rng: &mut R, mut cb: F) -> Self
44 where
45 F: FnMut(&mut R, [usize; 2]) -> T,
46 R: mop_common_deps::rand::Rng,
47 {
48 let dim: Dim<[usize; 2]> = shape.into();
49 let mut data = Vec::with_capacity(dim.rows() * dim.cols());
50 for x in 0..dim.rows() {
51 for y in 0..dim.cols() {
52 data.push(cb(rng, [x, y]));
53 }
54 }
55 DrMatrix { data, dim }
56 }
57
58 pub fn with_vec_capacity(shape: [usize; 2]) -> Self {
59 DrMatrix {
60 data: Vec::with_capacity(shape[0] * shape[1]),
61 dim: [0, shape[1]].into(),
62 }
63 }
64}
65
66impl<DA> DrMatrixVecArray<DA>
67where
68 DA: Array,
69{
70 #[cfg(feature = "rand")]
71 pub fn new_rnd<F, R>(shape: [usize; 2], rng: &mut R, mut cb: F) -> Self
72 where
73 F: FnMut(&mut R, [usize; 2]) -> DA::Item,
74 R: mop_common_deps::rand::Rng,
75 {
76 let dim: Dim<[usize; 2]> = shape.into();
77 let data = VecArray::new_rnd(dim.rows() * dim.cols(), rng, |rng, idx| {
78 cb(rng, crate::utils::matrix_x_y(dim.cols(), idx))
79 });
80 DrMatrix { data, dim }
81 }
82
83 pub fn with_vec_array(cols: usize) -> Self {
84 DrMatrix {
85 data: VecArray::with_capacity(),
86 dim: [0, cols].into(),
87 }
88 }
89}
90
91impl<DS> DrMatrix<DS>
92where
93 DS: StDenseStoRef,
94{
95 pub fn new(shape: [usize; 2], data: DS) -> Self {
118 let dim: Dim<[usize; 2]> = shape.into();
119 assert!(dim.rows() * dim.cols() == data.as_slice().len());
120 Self::new_unchecked(shape, data)
121 }
122
123 pub fn new_unchecked(shape: [usize; 2], data: DS) -> Self {
125 DrMatrix {
126 data,
127 dim: shape.into(),
128 }
129 }
130
131 pub fn as_ref(&self) -> DrMatrixRef<'_, DS::Item> {
149 DrMatrix::new([self.dim.rows(), self.dim.cols()], self.data.as_slice())
150 }
151
152 pub fn data(&self) -> &[DS::Item] {
153 &self.data.as_slice()
154 }
155
156 pub fn row(&self, idx: usize) -> &[DS::Item] {
157 let stride = self.stride(idx);
158 &self.data()[stride..stride + self.cols()]
159 }
160
161 pub fn row_iter(&self) -> DrMatrixRowIter<'_, DS::Item> {
162 DrMatrixRowIter::new([self.rows(), self.cols()], self.data().as_ptr())
163 }
164
165 #[cfg(feature = "rayon")]
166 pub fn row_par_iter(
167 &self,
168 ) -> crate::utils::ParallelIteratorWrapper<DrMatrixRowIter<'_, DS::Item>> {
169 crate::utils::ParallelIteratorWrapper(self.row_iter())
170 }
171
172 pub fn value(&self, row_idx: usize, col_idx: usize) -> &DS::Item {
173 &self.data()[self.stride(row_idx) + col_idx]
174 }
175}
176
177impl<DS> DrMatrix<DS>
178where
179 DS: StDenseStoMut,
180{
181 pub fn data_mut(&mut self) -> &mut [DS::Item] {
182 self.data.as_mut_slice()
183 }
184
185 pub fn row_mut(&mut self, idx: usize) -> &mut [DS::Item] {
186 let stride = self.stride(idx);
187 &mut self.data.as_mut_slice()[stride..stride + self.dim.cols()]
188 }
189
190 pub fn row_iter_mut(&mut self) -> DrMatrixRowIterMut<'_, DS::Item> {
191 DrMatrixRowIterMut::new([self.rows(), self.cols()], self.data_mut().as_mut_ptr())
192 }
193
194 #[cfg(feature = "rayon")]
195 pub fn row_par_iter_mut(
196 &mut self,
197 ) -> crate::utils::ParallelIteratorWrapper<DrMatrixRowIterMut<'_, DS::Item>> {
198 crate::utils::ParallelIteratorWrapper(self.row_iter_mut())
199 }
200
201 pub fn swap(&mut self, a: [usize; 2], b: [usize; 2]) {
202 let a_data_idx = self.stride(a[0]) + a[1];
203 let b_data_idx = self.stride(b[0]) + b[1];
204 self.data_mut().swap(a_data_idx, b_data_idx)
205 }
206
207 pub fn two_rows_mut(&mut self, smaller_idx: usize, bigger_idx: usize) -> [&mut [DS::Item]; 2] {
208 let bigger = self.stride(bigger_idx);
209 let smaller = self.stride(smaller_idx);
210 let (first, second) = self.data.as_mut_slice().split_at_mut(bigger);
211 [
212 &mut first[smaller..smaller + self.dim.cols()],
213 &mut second[0..self.dim.cols()],
214 ]
215 }
216
217 pub fn value_mut(&mut self, row_idx: usize, col_idx: usize) -> &mut DS::Item {
218 let stride = self.stride(row_idx);
219 &mut self.data_mut()[stride + col_idx]
220 }
221}
222
223impl<DS> DrMatrix<DS>
224where
225 DS: DynDenseStoRef,
226{
227 #[inline]
228 pub fn rows_capacity(&self) -> usize {
229 self.data.capacity() / self.dim.cols()
230 }
231}
232
233impl<DS> DrMatrix<DS>
234where
235 DS: DynDenseStoMut,
236{
237 pub fn clear(&mut self) {
238 self.data.clear();
239 *self.dim.rows_mut() = 0;
240 }
241
242 pub fn extend<AD>(&mut self, other: &DrMatrix<AD>)
243 where
244 AD: DynDenseStoMut<Item = DS::Item>,
245 DS::Item: Copy,
246 {
247 assert!(self.cols() == other.cols());
248 self.data.extend(other.data());
249 *self.dim.rows_mut() += other.rows();
250 }
251
252 pub fn extend_from_clone<AD>(&mut self, other: &DrMatrix<AD>)
253 where
254 AD: DynDenseStoMut<Item = DS::Item>,
255 DS::Item: Clone,
256 {
257 assert!(self.cols() == other.cols());
258 self.data.extend_from_clone(other.data());
259 *self.dim.rows_mut() += other.rows();
260 }
261
262 pub fn row_constructor(&mut self) -> DrMatrixRowConstructor<'_, DS> {
263 DrMatrixRowConstructor::new(&mut self.data, &mut self.dim)
264 }
265
266 pub fn truncate(&mut self, until_row_idx: usize) {
267 self.data.truncate(self.dim.cols() * until_row_idx);
268 *self.dim.rows_mut() = until_row_idx;
269 }
270}
271
272impl<DS> Matrix for DrMatrix<DS> {
273 #[inline]
274 fn cols(&self) -> usize {
275 self.dim.cols()
276 }
277
278 #[inline]
279 fn rows(&self) -> usize {
280 self.dim.rows()
281 }
282}
283
284#[cfg(all(feature = "quickcheck", feature = "rand"))]
285use mop_common_deps::{
286 quickcheck::{Arbitrary, Gen},
287 rand::{
288 distributions::{Distribution, Standard},
289 Rng,
290 },
291};
292#[cfg(all(feature = "quickcheck", feature = "rand"))]
293impl<T> Arbitrary for DrMatrixVec<T>
294where
295 Standard: Distribution<T>,
296 T: Arbitrary,
297{
298 #[inline]
299 fn arbitrary<G>(g: &mut G) -> Self
300 where
301 G: Gen,
302 {
303 DrMatrixVec::new_rnd(
304 [g.gen_range(0, g.size()), g.gen_range(0, g.size())],
305 g,
306 |g, _| g.gen(),
307 )
308 }
309}
310
311#[cfg(test)]
312mod tests {
313 #[cfg_attr(rustfmt, rustfmt_skip)]
314 const DEFAULT_DATA: [i32; 20] = [
315 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
316 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
317 ];
318 const DEFAULT_SHAPE: [usize; 2] = [4, 5];
319
320 use crate::{matrix::dr_matrix::DrMatrix, prelude::*, vec::VecArray};
321
322 #[test]
323 pub fn dr_matrix_alloc_clear() {
324 let mut dcca = default_dr_matrix_alloc();
325 dcca.clear();
326 assert_eq!(dcca.cols(), DEFAULT_SHAPE[1]);
327 assert_eq!(dcca.data(), &[]);
328 assert_eq!(dcca.rows(), 0);
329 }
330
331 #[test]
332 pub fn dr_matrix_alloc_cols() {
333 assert_eq!(default_dr_matrix_alloc().cols(), DEFAULT_SHAPE[1]);
334 }
335
336 #[test]
337 pub fn dr_matrix_alloc_data() {
338 assert_eq!(default_dr_matrix_alloc().data(), &DEFAULT_DATA);
339 }
340
341 #[test]
342 pub fn dr_matrix_alloc_data_mut() {
343 assert_eq!(default_dr_matrix_alloc().data_mut(), &mut DEFAULT_DATA);
344 }
345
346 #[test]
347 pub fn dr_matrix_alloc_row() {
348 let ddma = default_dr_matrix_alloc();
349 for row_idx in 0..4 {
350 let starting_row_value = row_idx * 5 + 1;
351 assert_eq!(
352 ddma.row(row_idx as usize),
353 &[
354 starting_row_value,
355 starting_row_value + 1,
356 starting_row_value + 2,
357 starting_row_value + 3,
358 starting_row_value + 4
359 ]
360 );
361 }
362 }
363
364 #[test]
365 pub fn dr_matrix_alloc_rows() {
366 assert_eq!(default_dr_matrix_alloc().rows(), DEFAULT_SHAPE[0]);
367 }
368
369 #[test]
370 pub fn dr_matrix_alloc_truncate() {
371 let mut ddma = default_dr_matrix_alloc();
372 ddma.truncate(2);
373 assert_eq!(ddma.cols(), DEFAULT_SHAPE[1]);
374 assert_eq!(ddma.data(), &DEFAULT_DATA[0..10]);
375 assert_eq!(ddma.rows(), 2);
376 }
377
378 #[test]
379 pub fn dr_matrix_alloc_value() {
380 let ddma = default_dr_matrix_alloc();
381 for row_idx in 0..4 {
382 let starting_row_value = row_idx * 5 + 1;
383 for col_idx in 0..5 {
384 assert_eq!(
385 *ddma.value(row_idx as usize, col_idx as usize),
386 starting_row_value + col_idx
387 );
388 }
389 }
390 }
391
392 fn default_dr_matrix_alloc() -> DrMatrix<VecArray<[i32; 20]>> {
393 DrMatrix::new([4, 5], VecArray::with_array(DEFAULT_DATA))
394 }
395}