sprs_rssn/
dense_vector.rs

1use crate::Ix1;
2use ndarray::{self, ArrayBase};
3use num_traits::identities::Zero;
4
5/// A trait for types representing dense vectors, useful for expressing
6/// algorithms such as sparse-dense dot product, or linear solves.
7///
8/// This trait is sealed, and cannot be implemented outside of the `sprs`
9/// crate.
10pub trait DenseVector: seal::Sealed {
11    type Owned;
12    type Scalar;
13
14    /// The dimension of the vector
15    fn dim(&self) -> usize;
16
17    /// Random access to an element in the vector.
18    ///
19    /// # Panics
20    ///
21    /// If the index is out of bounds
22    fn index(&self, idx: usize) -> &Self::Scalar;
23
24    /// Create an owned version of this dense vector type, filled with zeros
25    fn zeros(dim: usize) -> Self::Owned;
26
27    /// Copies this vector into an owned version
28    fn to_owned(&self) -> Self::Owned;
29}
30
31impl<N: Zero + Clone> DenseVector for [N] {
32    type Owned = Vec<N>;
33    type Scalar = N;
34
35    fn dim(&self) -> usize {
36        self.len()
37    }
38
39    #[inline(always)]
40    fn index(&self, idx: usize) -> &N {
41        &self[idx]
42    }
43
44    fn zeros(dim: usize) -> Self::Owned {
45        vec![N::zero(); dim]
46    }
47
48    fn to_owned(&self) -> Self::Owned {
49        self.to_vec()
50    }
51}
52
53impl<'a, N: 'a + Zero + Clone> DenseVector for &'a [N] {
54    type Owned = Vec<N>;
55    type Scalar = N;
56
57    fn dim(&self) -> usize {
58        self.len()
59    }
60
61    #[inline(always)]
62    fn index(&self, idx: usize) -> &N {
63        &self[idx]
64    }
65
66    fn zeros(dim: usize) -> Self::Owned {
67        vec![N::zero(); dim]
68    }
69
70    fn to_owned(&self) -> Self::Owned {
71        self.to_vec()
72    }
73}
74
75impl<'a, N: 'a + Zero + Clone> DenseVector for &'a mut [N] {
76    type Owned = Vec<N>;
77    type Scalar = N;
78
79    fn dim(&self) -> usize {
80        self.len()
81    }
82
83    #[inline(always)]
84    fn index(&self, idx: usize) -> &N {
85        &self[idx]
86    }
87
88    fn zeros(dim: usize) -> Self::Owned {
89        vec![N::zero(); dim]
90    }
91
92    fn to_owned(&self) -> Self::Owned {
93        self.to_vec()
94    }
95}
96
97impl<N: Zero + Clone> DenseVector for Vec<N> {
98    type Owned = Self;
99    type Scalar = N;
100
101    fn dim(&self) -> usize {
102        self.len()
103    }
104
105    #[inline(always)]
106    fn index(&self, idx: usize) -> &N {
107        &self[idx]
108    }
109
110    fn zeros(dim: usize) -> Self::Owned {
111        vec![N::zero(); dim]
112    }
113
114    fn to_owned(&self) -> Self::Owned {
115        self.clone()
116    }
117}
118
119impl<'a, N: 'a + Zero + Clone> DenseVector for &'a Vec<N> {
120    type Owned = Vec<N>;
121    type Scalar = N;
122
123    fn dim(&self) -> usize {
124        self.len()
125    }
126
127    #[inline(always)]
128    fn index(&self, idx: usize) -> &N {
129        &self[idx]
130    }
131
132    fn zeros(dim: usize) -> Self::Owned {
133        vec![N::zero(); dim]
134    }
135
136    fn to_owned(&self) -> Self::Owned {
137        (*self).clone()
138    }
139}
140
141impl<'a, N: 'a + Zero + Clone> DenseVector for &'a mut Vec<N> {
142    type Owned = Vec<N>;
143    type Scalar = N;
144
145    fn dim(&self) -> usize {
146        self.len()
147    }
148
149    #[inline(always)]
150    fn index(&self, idx: usize) -> &N {
151        &self[idx]
152    }
153
154    fn zeros(dim: usize) -> Self::Owned {
155        vec![N::zero(); dim]
156    }
157
158    fn to_owned(&self) -> Self::Owned {
159        (**self).clone()
160    }
161}
162
163impl<N, S> DenseVector for ArrayBase<S, Ix1>
164where
165    S: ndarray::Data<Elem = N>,
166    N: Zero + Clone,
167{
168    type Owned = ndarray::Array<N, Ix1>;
169    type Scalar = N;
170
171    fn dim(&self) -> usize {
172        self.shape()[0]
173    }
174
175    #[inline(always)]
176    fn index(&self, idx: usize) -> &N {
177        &self[[idx]]
178    }
179
180    fn zeros(dim: usize) -> Self::Owned {
181        ndarray::Array::zeros(dim)
182    }
183
184    fn to_owned(&self) -> Self::Owned {
185        self.to_owned()
186    }
187}
188
189impl<'a, N, S> DenseVector for &'a ArrayBase<S, Ix1>
190where
191    S: ndarray::Data<Elem = N>,
192    N: 'a + Zero + Clone,
193{
194    type Owned = ndarray::Array<N, Ix1>;
195    type Scalar = N;
196
197    fn dim(&self) -> usize {
198        self.shape()[0]
199    }
200
201    #[inline(always)]
202    fn index(&self, idx: usize) -> &N {
203        &self[[idx]]
204    }
205
206    fn zeros(dim: usize) -> Self::Owned {
207        ndarray::Array::zeros(dim)
208    }
209
210    fn to_owned(&self) -> Self::Owned {
211        ArrayBase::to_owned(self)
212    }
213}
214
215impl<'a, N, S> DenseVector for &'a mut ArrayBase<S, Ix1>
216where
217    S: ndarray::Data<Elem = N>,
218    N: 'a + Zero + Clone,
219{
220    type Owned = ndarray::Array<N, Ix1>;
221    type Scalar = N;
222
223    fn dim(&self) -> usize {
224        self.shape()[0]
225    }
226
227    #[inline(always)]
228    fn index(&self, idx: usize) -> &N {
229        &self[[idx]]
230    }
231
232    fn zeros(dim: usize) -> Self::Owned {
233        ndarray::Array::zeros(dim)
234    }
235
236    fn to_owned(&self) -> Self::Owned {
237        ArrayBase::to_owned(self)
238    }
239}
240
241/// Trait for dense vectors that can be modified, useful for expressing
242/// algorithms which compute a resulting dense vector, such as solvers.
243///
244/// This trait is sealed, and cannot be implemented outside of the `sprs`
245/// crate.
246pub trait DenseVectorMut: DenseVector {
247    /// Random mutable access to an element in the vector.
248    ///
249    /// # Panics
250    ///
251    /// If the index is out of bounds
252    fn index_mut(&mut self, idx: usize) -> &mut Self::Scalar;
253}
254
255impl<N: Zero + Clone> DenseVectorMut for [N] {
256    #[inline(always)]
257    fn index_mut(&mut self, idx: usize) -> &mut N {
258        &mut self[idx]
259    }
260}
261
262impl<'a, N: 'a + Zero + Clone> DenseVectorMut for &'a mut [N] {
263    #[inline(always)]
264    fn index_mut(&mut self, idx: usize) -> &mut N {
265        &mut self[idx]
266    }
267}
268
269impl<N: Zero + Clone> DenseVectorMut for Vec<N> {
270    #[inline(always)]
271    fn index_mut(&mut self, idx: usize) -> &mut N {
272        &mut self[idx]
273    }
274}
275
276impl<'a, N: 'a + Zero + Clone> DenseVectorMut for &'a mut Vec<N> {
277    #[inline(always)]
278    fn index_mut(&mut self, idx: usize) -> &mut N {
279        &mut self[idx]
280    }
281}
282
283impl<N, S> DenseVectorMut for ArrayBase<S, Ix1>
284where
285    S: ndarray::DataMut<Elem = N>,
286    N: Zero + Clone,
287{
288    #[inline(always)]
289    fn index_mut(&mut self, idx: usize) -> &mut N {
290        &mut self[[idx]]
291    }
292}
293
294impl<'a, N, S> DenseVectorMut for &'a mut ArrayBase<S, Ix1>
295where
296    S: ndarray::DataMut<Elem = N>,
297    N: 'a + Zero + Clone,
298{
299    #[inline(always)]
300    fn index_mut(&mut self, idx: usize) -> &mut N {
301        &mut self[[idx]]
302    }
303}
304
305mod seal {
306    pub trait Sealed {}
307
308    impl<N> Sealed for [N] {}
309    impl<'a, N: 'a> Sealed for &'a [N] {}
310    impl<'a, N: 'a> Sealed for &'a mut [N] {}
311    impl<N> Sealed for Vec<N> {}
312    impl<'a, N: 'a> Sealed for &'a Vec<N> {}
313    impl<'a, N: 'a> Sealed for &'a mut Vec<N> {}
314    impl<N, S: ndarray::Data<Elem = N>> Sealed
315        for ndarray::ArrayBase<S, crate::Ix1>
316    {
317    }
318    impl<'a, N: 'a, S: ndarray::Data<Elem = N>> Sealed
319        for &'a ndarray::ArrayBase<S, crate::Ix1>
320    {
321    }
322    impl<'a, N: 'a, S: ndarray::Data<Elem = N>> Sealed
323        for &'a mut ndarray::ArrayBase<S, crate::Ix1>
324    {
325    }
326}
327
328#[cfg(test)]
329mod test {
330    use super::*;
331    use ndarray::{arr1, Array1};
332
333    // Tests on primitive arrays
334    #[test]
335    fn test_dim_of_empty_array() {
336        let vec: [i32; 0] = [];
337        assert_eq!(vec.dim(), 0);
338    }
339
340    #[test]
341    fn test_dim_of_non_empty_array() {
342        let vec = [10, 20];
343        assert_eq!(vec.dim(), 2);
344    }
345
346    #[test]
347    fn test_indexing_array() {
348        let vec: [i32; 3] = [10, 20, 30];
349        assert_eq!(*(vec.index(0)), 10);
350        assert_eq!(*(vec.index(1)), 20);
351        assert_eq!(*(vec.index(2)), 30);
352    }
353
354    #[test]
355    fn test_zeros_on_array() {
356        const DIM: usize = 5;
357        let vec = <[i32] as DenseVector>::zeros(DIM);
358        for i in 0..DIM {
359            assert_eq!(vec[i], 0);
360        }
361    }
362
363    // Tests on vectors
364    #[test]
365    fn test_dim_of_empty_vector() {
366        let vec: Vec<i32> = vec![];
367        assert_eq!(vec.dim(), 0);
368    }
369
370    #[test]
371    fn test_dim_of_non_empty_vector() {
372        let vec = vec![10, 20];
373        assert_eq!(vec.dim(), 2);
374    }
375
376    #[test]
377    fn test_dim_of_varying_size_vector() {
378        let mut vec: Vec<i32> = vec![];
379        assert_eq!(vec.dim(), 0);
380        vec.push(10);
381        assert_eq!(vec.dim(), 1);
382        vec.push(20);
383        assert_eq!(vec.dim(), 2);
384        vec.clear();
385        assert_eq!(vec.dim(), 0);
386    }
387
388    #[test]
389    fn test_indexing_vector() {
390        let vec = vec![10, 20, 30];
391        assert_eq!(*(vec.index(0)), 10);
392        assert_eq!(*(vec.index(1)), 20);
393        assert_eq!(*(vec.index(2)), 30);
394    }
395
396    #[test]
397    fn test_zeros_on_vector() {
398        const DIM: usize = 5;
399        let vec = Vec::<i32>::zeros(DIM);
400        for i in 0..DIM {
401            assert_eq!(vec[i], 0);
402        }
403    }
404
405    // Tests on ArrayBase
406    #[test]
407    fn test_dim_of_empty_ndarray() {
408        let array = Array1::<i32>::zeros(0);
409        assert_eq!(array.dim(), 0);
410    }
411
412    #[test]
413    fn test_dim_of_non_empty_ndarray() {
414        let array = Array1::<i32>::zeros(3);
415        assert_eq!(array.dim(), 3);
416    }
417
418    #[test]
419    fn test_indexing_ndarray() {
420        let array = arr1(&[10, 20, 30]);
421        assert_eq!(*(array.index(0)), 10);
422        assert_eq!(*(array.index(1)), 20);
423        assert_eq!(*(array.index(2)), 30);
424    }
425
426    #[test]
427    fn test_zeros_on_ndarray() {
428        const DIM: usize = 5;
429        let array = <Array1<i32> as DenseVector>::zeros(DIM);
430        for i in 0..DIM {
431            assert_eq!(array[i], 0);
432        }
433    }
434}