mop_structs/vec/
css.rs

1use crate::{
2  dim::Dim,
3  prelude::{Array, DynDenseStoMut, DynDenseStoRef, StDenseStoMut, StDenseStoRef},
4  vec::VecArray,
5};
6
7/// Compressed Sparse Storage.
8///
9/// This struct represents a single sparse row, thtoUses the same logic and storage of a CSR Matrix without rows/pointers.
10#[cfg_attr(
11  feature = "serde1",
12  derive(mop_common_deps::serde::Deserialize, mop_common_deps::serde::Serialize)
13)]
14#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, PartialOrd)]
15pub struct Css<DS, IS> {
16  data: DS,
17  dim: Dim<usize>,
18  indcs: IS,
19}
20
21pub type CssArray<DA, IA> = Css<DA, IA>;
22#[cfg(feature = "std")]
23pub type CssVec<T> = Css<Vec<T>, Vec<usize>>;
24pub type CssVecArray<DA, IA> = Css<VecArray<DA>, VecArray<IA>>;
25pub type CssSlice<'a, T> = Css<&'a [T], &'a [usize]>;
26pub type CssSliceMut<'a, T> = Css<&'a mut [T], &'a [usize]>;
27
28impl<DS, IS> Css<DS, IS> {
29  pub fn new(len: usize, data: DS, indcs: IS) -> Self {
30    Css {
31      data,
32      dim: len.into(),
33      indcs,
34    }
35  }
36
37  /// The length of the vector.
38  ///
39  /// # Examples
40  ///
41  /// ```rust
42  /// use mop_structs::doc_tests::css_array;
43  /// assert_eq!(css_array().len(), 10);
44  /// ```
45  #[inline]
46  pub fn len(&self) -> usize {
47    self.dim.len()
48  }
49}
50
51#[cfg(feature = "std")]
52impl<T> CssVec<T> {
53  #[cfg(feature = "rand")]
54  pub fn new_rnd<F, R>(len: usize, nnz: usize, rng: &mut R, mut cb: F) -> Self
55  where
56    F: FnMut(&mut R, usize) -> T,
57    R: mop_common_deps::rand::Rng,
58  {
59    assert!(nnz <= len);
60    let mut counter = 0;
61    let mut indcs = Vec::with_capacity(nnz);
62    while counter < nnz {
63      let rnd = rng.gen_range(0, len);
64      if indcs.contains(&rnd) == false {
65        indcs.push(rnd);
66        counter += 1;
67      }
68    }
69    indcs.sort_unstable();
70    let data = (0..nnz).map(|idx| cb(rng, indcs[idx])).collect();
71    CssVec {
72      dim: len.into(),
73      data,
74      indcs,
75    }
76  }
77
78  pub fn with_vec(len: usize, data: Vec<T>, indcs: Vec<usize>) -> Self {
79    CssVec {
80      data,
81      dim: len.into(),
82      indcs,
83    }
84  }
85}
86
87impl<DA, IA> CssVecArray<DA, IA>
88where
89  DA: Array,
90  IA: Array<Item = usize>,
91{
92  #[cfg(feature = "rand")]
93  pub fn new_rnd<F, R>(len: usize, nnz: usize, rng: &mut R, mut cb: F) -> Self
94  where
95    F: FnMut(&mut R, usize) -> DA::Item,
96    R: mop_common_deps::rand::Rng,
97  {
98    assert!(nnz <= len);
99    let mut counter = 0;
100    let mut indcs = VecArray::<IA>::with_capacity();
101    while counter < nnz {
102      let rnd = rng.gen_range(0, len);
103      if indcs.as_slice().contains(&rnd) == false {
104        indcs.push(rnd);
105        counter += 1;
106      }
107    }
108    indcs.as_mut_slice().sort_unstable();
109    let data = VecArray::<DA>::new_rnd(nnz, rng, |rng, idx| cb(rng, indcs.as_slice()[idx]));
110    CssVecArray {
111      dim: len.into(),
112      data,
113      indcs,
114    }
115  }
116
117  pub fn with_vec_array(len: usize, data: VecArray<DA>, indcs: VecArray<IA>) -> Self {
118    CssVecArray {
119      data,
120      dim: len.into(),
121      indcs,
122    }
123  }
124}
125
126impl<DS, IS> Css<DS, IS>
127where
128  DS: StDenseStoRef,
129  IS: StDenseStoRef<Item = usize>,
130{
131  pub fn as_ref(&self) -> CssSlice<'_, DS::Item> {
132    Css::new(self.dim.len(), self.data.as_slice(), self.indcs.as_slice())
133  }
134
135  pub fn data(&self) -> &[DS::Item] {
136    self.data.as_slice()
137  }
138
139  pub fn get(&self, idx: usize) -> Option<&DS::Item> {
140    if let Ok(x) = self.indcs().binary_search(&idx) {
141      Some(&self.data()[x])
142    } else {
143      None
144    }
145  }
146
147  pub fn indcs(&self) -> &[usize] {
148    self.indcs.as_slice()
149  }
150
151  pub fn iter(&self) -> impl Iterator<Item = (usize, &DS::Item)> {
152    self
153      .indcs
154      .as_slice()
155      .iter()
156      .cloned()
157      .zip(self.data.as_slice())
158  }
159
160  pub fn nnz(&self) -> usize {
161    self.data().len()
162  }
163}
164
165impl<DS, IS> Css<DS, IS>
166where
167  DS: StDenseStoMut,
168  IS: StDenseStoRef<Item = usize>,
169{
170  pub fn as_mut_slice(&mut self) -> CssSliceMut<'_, DS::Item> {
171    Css::new(
172      self.dim.len(),
173      self.data.as_mut_slice(),
174      self.indcs.as_slice(),
175    )
176  }
177
178  pub fn data_mut(&mut self) -> &mut [DS::Item] {
179    self.data.as_mut_slice()
180  }
181
182  pub fn get_mut(&mut self, idx: usize) -> Option<&mut DS::Item> {
183    if let Ok(x) = self.indcs().binary_search(&idx) {
184      Some(&mut self.data_mut()[x])
185    } else {
186      None
187    }
188  }
189
190  pub fn iter_mut(&mut self) -> impl Iterator<Item = (usize, &mut DS::Item)> {
191    self
192      .indcs
193      .as_slice()
194      .iter()
195      .cloned()
196      .zip(self.data.as_mut_slice())
197  }
198
199  pub fn split_at_mut(
200    &mut self,
201    idx: usize,
202  ) -> (CssSliceMut<'_, DS::Item>, CssSliceMut<'_, DS::Item>) {
203    assert!(idx <= self.len());
204    let len = self.len();
205    let split_idx = self.indcs().binary_search(&idx).unwrap();
206    let indcs = self.indcs.as_slice();
207    let (first_data, second_data) = self.data.as_mut_slice().split_at_mut(split_idx);
208    let first = Css::new(idx, first_data, &indcs[0..split_idx]);
209    let second = Css::new(len - idx, second_data, &indcs[split_idx..]);
210    (first, second)
211  }
212
213  pub fn swap(&mut self, a: usize, b: usize) {
214    let a_data_idx = self.indcs().binary_search(&a).unwrap();
215    let b_data_idx = self.indcs().binary_search(&b).unwrap();
216    self.data_mut().swap(a_data_idx, b_data_idx);
217  }
218}
219
220impl<DS, IS> Css<DS, IS>
221where
222  DS: DynDenseStoRef,
223{
224  pub fn nnz_capacity(&self) -> usize {
225    self.data.capacity()
226  }
227}
228
229impl<DS, IS> Css<DS, IS>
230where
231  DS: DynDenseStoMut,
232  IS: DynDenseStoMut<Item = usize>,
233{
234  pub fn clear(&mut self) {
235    self.data.clear();
236    self.indcs.clear();
237    *self.dim.len_mut() = 0;
238  }
239
240  pub fn extend(&mut self, other: &Self)
241  where
242    DS::Item: Copy,
243  {
244    self.data.extend(other.data());
245    self.indcs.extend(other.indcs());
246    *self.dim.len_mut() += other.len();
247  }
248
249  pub fn set(&mut self, idx: usize, data: DS::Item) {
250    self.indcs.push(idx);
251    self.data.push(data);
252    *self.dim.len_mut() += 1;
253  }
254
255  pub fn truncate(&mut self, until_idx: usize) {
256    self.data.truncate(until_idx);
257    self.indcs.truncate(until_idx);
258    *self.dim.len_mut() = until_idx;
259  }
260}
261
262#[cfg(all(feature = "quickcheck", feature = "rand"))]
263use mop_common_deps::{
264  quickcheck::{Arbitrary, Gen},
265  rand::{
266    distributions::{Distribution, Standard},
267    Rng,
268  },
269};
270#[cfg(all(feature = "quickcheck", feature = "rand"))]
271impl<T> Arbitrary for CssVec<T>
272where
273  Standard: Distribution<T>,
274  T: Arbitrary,
275{
276  #[inline]
277  fn arbitrary<G>(g: &mut G) -> Self
278  where
279    G: Gen,
280  {
281    let len = g.gen_range(0, g.size());
282    let nnz = g.gen_range(0, len + 1);
283    CssVec::new_rnd(len, nnz, g, |g, _| g.gen())
284  }
285}