1use crate::{
2 dim::Dim,
3 prelude::{Array, DynDenseStoMut, DynDenseStoRef, StDenseStoMut, StDenseStoRef},
4 vec::VecArray,
5};
6
7#[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 #[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}