conspire/math/tensor/quantity/sparse_vec/
mod.rs1use super::Quantity;
2use crate::math::{Tensor, TensorRank0};
3use crate::units::Dimensionless;
4use std::{
5 fmt::{self, Debug, Display, Formatter, Result},
6 iter::Sum,
7 ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign},
8};
9
10pub struct QuantitySparseVec<U = Dimensionless>(pub(super) Vec<(usize, Quantity<U>)>);
12
13impl<U> Clone for QuantitySparseVec<U> {
14 fn clone(&self) -> Self {
15 Self(self.0.clone())
16 }
17}
18
19impl<U> Debug for QuantitySparseVec<U> {
20 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
21 Debug::fmt(&self.0, f)
22 }
23}
24
25impl<U> Default for QuantitySparseVec<U> {
26 fn default() -> Self {
27 Self(Vec::new())
28 }
29}
30
31impl<U> PartialEq for QuantitySparseVec<U> {
32 fn eq(&self, other: &Self) -> bool {
33 self.0 == other.0
34 }
35}
36
37impl<U> QuantitySparseVec<U> {
38 pub fn entries(&self) -> impl Iterator<Item = (usize, &Quantity<U>)> {
39 self.0.iter().map(|(column, entry)| (*column, entry))
40 }
41}
42
43impl<U> FromIterator<Quantity<U>> for QuantitySparseVec<U> {
44 fn from_iter<T>(into_iterator: T) -> Self
45 where
46 T: IntoIterator<Item = Quantity<U>>,
47 {
48 Self(into_iterator.into_iter().enumerate().collect())
49 }
50}
51
52impl<U> Index<usize> for QuantitySparseVec<U> {
53 type Output = Quantity<U>;
54 fn index(&self, index: usize) -> &Self::Output {
55 match self.0.binary_search_by_key(&index, |&(column, _)| column) {
56 Ok(k) => &self.0[k].1,
57 Err(_) => panic!("Entry ({index}) not present."),
58 }
59 }
60}
61
62impl<U> IndexMut<usize> for QuantitySparseVec<U> {
63 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
64 let k = match self.0.binary_search_by_key(&index, |&(column, _)| column) {
65 Ok(k) => k,
66 Err(k) => {
67 self.0.insert(k, (index, Quantity::new(0.0)));
68 k
69 }
70 };
71 &mut self.0[k].1
72 }
73}
74
75impl<U> Display for QuantitySparseVec<U> {
76 fn fmt(&self, f: &mut Formatter) -> Result {
77 write!(f, "Need to implement Display")
78 }
79}
80
81impl<U> Tensor for QuantitySparseVec<U> {
82 type Item = Quantity<U>;
83 type Unit = U;
84 fn iter(&self) -> impl Iterator<Item = &Self::Item> {
85 self.0.iter().map(|(_, entry)| entry)
86 }
87 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
88 self.0.iter_mut().map(|(_, entry)| entry)
89 }
90 fn len(&self) -> usize {
91 self.0.len()
92 }
93 fn size(&self) -> usize {
94 self.0.len()
95 }
96}
97
98fn merge<U>(
99 a: QuantitySparseVec<U>,
100 b: &QuantitySparseVec<U>,
101 sign: TensorRank0,
102) -> QuantitySparseVec<U> {
103 let mut merged = a;
104 b.0.iter()
105 .for_each(|(column, entry)| merged[*column] += entry * sign);
106 merged
107}
108
109impl<U> Add for QuantitySparseVec<U> {
110 type Output = Self;
111 fn add(self, other: Self) -> Self {
112 merge(self, &other, 1.0)
113 }
114}
115
116impl<U> Add<&Self> for QuantitySparseVec<U> {
117 type Output = Self;
118 fn add(self, other: &Self) -> Self {
119 merge(self, other, 1.0)
120 }
121}
122
123impl<U> AddAssign for QuantitySparseVec<U> {
124 fn add_assign(&mut self, other: Self) {
125 other
126 .0
127 .into_iter()
128 .for_each(|(column, entry)| self[column] += entry);
129 }
130}
131
132impl<U> AddAssign<&Self> for QuantitySparseVec<U> {
133 fn add_assign(&mut self, other: &Self) {
134 other
135 .0
136 .iter()
137 .for_each(|(column, entry)| self[*column] += entry);
138 }
139}
140
141impl<U> Sub for QuantitySparseVec<U> {
142 type Output = Self;
143 fn sub(self, other: Self) -> Self {
144 merge(self, &other, -1.0)
145 }
146}
147
148impl<U> Sub<&Self> for QuantitySparseVec<U> {
149 type Output = Self;
150 fn sub(self, other: &Self) -> Self {
151 merge(self, other, -1.0)
152 }
153}
154
155impl<U> SubAssign for QuantitySparseVec<U> {
156 fn sub_assign(&mut self, other: Self) {
157 other
158 .0
159 .into_iter()
160 .for_each(|(column, entry)| self[column] -= entry);
161 }
162}
163
164impl<U> SubAssign<&Self> for QuantitySparseVec<U> {
165 fn sub_assign(&mut self, other: &Self) {
166 other
167 .0
168 .iter()
169 .for_each(|(column, entry)| self[*column] -= entry);
170 }
171}
172
173impl<U> Mul<TensorRank0> for QuantitySparseVec<U> {
174 type Output = Self;
175 fn mul(mut self, scalar: TensorRank0) -> Self {
176 self *= &scalar;
177 self
178 }
179}
180
181impl<U> MulAssign<TensorRank0> for QuantitySparseVec<U> {
182 fn mul_assign(&mut self, scalar: TensorRank0) {
183 self.0.iter_mut().for_each(|(_, entry)| *entry *= &scalar);
184 }
185}
186
187impl<U> MulAssign<&TensorRank0> for QuantitySparseVec<U> {
188 fn mul_assign(&mut self, scalar: &TensorRank0) {
189 self.0.iter_mut().for_each(|(_, entry)| *entry *= scalar);
190 }
191}
192
193impl<U> Div<TensorRank0> for QuantitySparseVec<U> {
194 type Output = Self;
195 fn div(mut self, scalar: TensorRank0) -> Self {
196 self /= &scalar;
197 self
198 }
199}
200
201impl<U> DivAssign<TensorRank0> for QuantitySparseVec<U> {
202 fn div_assign(&mut self, scalar: TensorRank0) {
203 self.0.iter_mut().for_each(|(_, entry)| *entry /= &scalar);
204 }
205}
206
207impl<U> DivAssign<&TensorRank0> for QuantitySparseVec<U> {
208 fn div_assign(&mut self, scalar: &TensorRank0) {
209 self.0.iter_mut().for_each(|(_, entry)| *entry /= scalar);
210 }
211}
212
213impl<U> Sum for QuantitySparseVec<U> {
214 fn sum<T>(iter: T) -> Self
215 where
216 T: Iterator<Item = Self>,
217 {
218 iter.fold(Self::default(), |sum, entry| sum + entry)
219 }
220}