conspire/math/tensor/rank_1/vec/
mod.rs1#[cfg(test)]
2mod test;
3
4use crate::math::{
5 Jacobian, Solution, Tensor, TensorRank0, TensorRank1, TensorRank1List, TensorRank2SparseVec2D,
6 TensorRank2SparseVec2DSymmetric, TensorRank2Vec2D, Vector, tensor::vec::TensorVector,
7};
8use std::{
9 array::from_fn,
10 mem::{forget, transmute},
11 ops::{Div, Sub},
12};
13
14use crate::math::assert::FiniteDifference;
15
16pub type TensorRank1Vec<const D: usize, const I: usize> = TensorVector<TensorRank1<D, I>>;
18
19impl<const D: usize, const I: usize> TensorRank1Vec<D, I> {
20 pub fn bounding_box(&self) -> TensorRank1List<D, I, 2> {
21 self.iter()
22 .skip(1)
23 .fold(
24 [self[0].clone(), self[0].clone()],
25 |[mut min, mut max], entry| {
26 entry
27 .iter()
28 .zip(min.iter_mut().zip(max.iter_mut()))
29 .for_each(|(&entry_i, (min_i, max_i))| {
30 *min_i = min_i.min(entry_i);
31 *max_i = max_i.max(entry_i);
32 });
33 [min, max]
34 },
35 )
36 .into()
37 }
38 pub fn zero(len: usize) -> Self {
39 (0..len).map(|_| super::zero()).collect()
40 }
41}
42
43impl<const D: usize, const I: usize, const N: usize> From<[[TensorRank0; D]; N]>
44 for TensorRank1Vec<D, I>
45{
46 fn from(array: [[TensorRank0; D]; N]) -> Self {
47 array.into_iter().map(TensorRank1::from).collect()
48 }
49}
50
51impl<const D: usize, const I: usize> From<Vec<[TensorRank0; D]>> for TensorRank1Vec<D, I> {
52 fn from(vec: Vec<[TensorRank0; D]>) -> Self {
53 unsafe { transmute(vec) }
54 }
55}
56
57impl<const D: usize, const I: usize> From<TensorRank1Vec<D, I>> for Vec<[TensorRank0; D]> {
58 fn from(tensor_rank_1_vec: TensorRank1Vec<D, I>) -> Self {
59 unsafe { transmute(tensor_rank_1_vec) }
60 }
61}
62
63impl<const D: usize, const I: usize> From<Vec<Vec<TensorRank0>>> for TensorRank1Vec<D, I> {
64 fn from(vec: Vec<Vec<TensorRank0>>) -> Self {
65 vec.into_iter()
66 .map(|tensor_rank_1| tensor_rank_1.into())
67 .collect()
68 }
69}
70
71impl<const D: usize, const I: usize> From<TensorRank1Vec<D, I>> for Vec<Vec<TensorRank0>> {
72 fn from(tensor_rank_1_vec: TensorRank1Vec<D, I>) -> Self {
73 tensor_rank_1_vec
74 .into_iter()
75 .map(|tensor_rank_1| tensor_rank_1.into())
76 .collect()
77 }
78}
79
80impl<const D: usize, const I: usize> TryFrom<[Vec<TensorRank0>; D]> for TensorRank1Vec<D, I> {
81 type Error = String;
82 fn try_from(vec_array: [Vec<TensorRank0>; D]) -> Result<Self, Self::Error> {
83 let length = vec_array[0].len();
84 if vec_array.iter().any(|vec| vec.len() != length) {
85 Err("Vector length mismatch in type conversion".to_string())
86 } else {
87 Ok((0..length)
88 .map(|j| TensorRank1::const_from(from_fn(|i| vec_array[i][j])))
89 .collect())
90 }
91 }
92}
93
94impl<const D: usize, const I: usize> From<TensorRank1Vec<D, I>> for [Vec<TensorRank0>; D] {
95 fn from(tensor_rank_1_vec: TensorRank1Vec<D, I>) -> Self {
96 let length = tensor_rank_1_vec.len();
97 let mut output = from_fn(|_| Vec::with_capacity(length));
98 tensor_rank_1_vec.into_iter().for_each(|tensor_rank_1| {
99 output
100 .iter_mut()
101 .zip(tensor_rank_1)
102 .for_each(|(entry, value)| entry.push(value))
103 });
104 output
105 }
106}
107
108impl<const D: usize, const I: usize> From<&TensorRank1Vec<D, I>> for [Vec<TensorRank0>; D] {
109 fn from(tensor_rank_1_vec: &TensorRank1Vec<D, I>) -> Self {
110 let length = tensor_rank_1_vec.len();
111 let mut output = from_fn(|_| Vec::with_capacity(length));
112 tensor_rank_1_vec.iter().for_each(|tensor_rank_1| {
113 output
114 .iter_mut()
115 .zip(tensor_rank_1.iter())
116 .for_each(|(entry, &value)| entry.push(value))
117 });
118 output
119 }
120}
121
122impl<const D: usize> From<TensorRank1Vec<D, 0>> for TensorRank1Vec<D, 1> {
123 fn from(tensor_rank_1_vec: TensorRank1Vec<D, 0>) -> Self {
124 let length = tensor_rank_1_vec.len();
125 let pointer = tensor_rank_1_vec.as_ptr() as *mut TensorRank1<D, 1>;
126 forget(tensor_rank_1_vec);
127 unsafe { Self::from(Vec::from_raw_parts(pointer, length, length)) }
128 }
129}
130
131impl<const D: usize> From<&TensorRank1Vec<D, 0>> for TensorRank1Vec<D, 1> {
132 fn from(tensor_rank_1_vec: &TensorRank1Vec<D, 0>) -> Self {
133 tensor_rank_1_vec
134 .iter()
135 .map(|tensor_rank_1| tensor_rank_1.into())
136 .collect()
137 }
138}
139
140impl<const D: usize> From<TensorRank1Vec<D, 1>> for TensorRank1Vec<D, 0> {
141 fn from(tensor_rank_1_vec: TensorRank1Vec<D, 1>) -> Self {
142 let length = tensor_rank_1_vec.len();
143 let pointer = tensor_rank_1_vec.as_ptr() as *mut TensorRank1<D, 0>;
144 forget(tensor_rank_1_vec);
145 unsafe { Self::from(Vec::from_raw_parts(pointer, length, length)) }
146 }
147}
148
149impl<const D: usize> From<&TensorRank1Vec<D, 1>> for TensorRank1Vec<D, 0> {
150 fn from(tensor_rank_1_vec: &TensorRank1Vec<D, 1>) -> Self {
151 tensor_rank_1_vec
152 .iter()
153 .map(|tensor_rank_1| tensor_rank_1.into())
154 .collect()
155 }
156}
157
158impl<const D: usize, const I: usize> From<Vector> for TensorRank1Vec<D, I> {
159 fn from(vector: Vector) -> Self {
160 let n = vector.len();
161 if n.is_multiple_of(D) {
162 let length = n / D;
163 let pointer = vector.as_ptr() as *mut TensorRank1<D, I>;
164 forget(vector);
165 unsafe { Self::from(Vec::from_raw_parts(pointer, length, length)) }
166 } else {
167 panic!("Vector length mismatch.")
168 }
169 }
170}
171
172impl<const D: usize, const I: usize> Jacobian for TensorRank1Vec<D, I> {
173 fn fill_into(self, vector: &mut Vector) {
174 self.into_iter()
175 .flatten()
176 .zip(vector.iter_mut())
177 .for_each(|(self_i, vector_i)| *vector_i = self_i)
178 }
179 fn fill_into_chained(self, other: Vector, vector: &mut Vector) {
180 self.into_iter()
181 .flatten()
182 .chain(other)
183 .zip(vector.iter_mut())
184 .for_each(|(self_i, vector_i)| *vector_i = self_i)
185 }
186 fn retain_from(self, retained: &[bool]) -> Vector {
187 self.into_iter()
188 .flatten()
189 .zip(retained.iter())
190 .filter(|(_, retained)| **retained)
191 .map(|(entry, _)| entry)
192 .collect()
193 }
194 fn zero_out(&mut self, indices: &[usize]) {
195 indices
196 .iter()
197 .for_each(|index| self[index / D][index % D] = 0.0)
198 }
199}
200
201impl<const D: usize, const I: usize> Solution for TensorRank1Vec<D, I> {
202 fn decrement_from(&mut self, other: &Vector) {
203 self.iter_mut()
204 .flat_map(|x| x.iter_mut())
205 .zip(other.iter())
206 .for_each(|(self_i, vector_i)| *self_i -= vector_i)
207 }
208 fn decrement_from_chained(&mut self, other: &mut Vector, vector: Vector) {
209 self.iter_mut()
210 .flat_map(|x| x.iter_mut())
211 .chain(other.iter_mut())
212 .zip(vector)
213 .for_each(|(entry_i, vector_i)| *entry_i -= vector_i)
214 }
215 fn decrement_from_retained(&mut self, retained: &[bool], other: &Vector) {
216 self.iter_mut()
217 .flat_map(|x| x.iter_mut())
218 .zip(retained.iter())
219 .filter(|(_, retained_i)| **retained_i)
220 .zip(other.iter())
221 .for_each(|((self_i, _), vector_i)| *self_i -= vector_i)
222 }
223}
224
225impl<const D: usize, const I: usize> Sub<Vector> for TensorRank1Vec<D, I> {
226 type Output = Self;
227 fn sub(mut self, vector: Vector) -> Self::Output {
228 self.iter_mut().enumerate().for_each(|(a, self_a)| {
229 self_a
230 .iter_mut()
231 .enumerate()
232 .for_each(|(i, self_a_i)| *self_a_i -= vector[D * a + i])
233 });
234 self
235 }
236}
237
238impl<const D: usize, const I: usize> Sub<&Vector> for TensorRank1Vec<D, I> {
239 type Output = Self;
240 fn sub(mut self, vector: &Vector) -> Self::Output {
241 self.iter_mut().enumerate().for_each(|(a, self_a)| {
242 self_a
243 .iter_mut()
244 .enumerate()
245 .for_each(|(i, self_a_i)| *self_a_i -= vector[D * a + i])
246 });
247 self
248 }
249}
250
251impl<const D: usize, const I: usize, const J: usize> Div<TensorRank2Vec2D<D, I, J>>
252 for &TensorRank1Vec<D, I>
253{
254 type Output = TensorRank1Vec<D, J>;
255 fn div(self, _tensor_rank_2_vec_2d: TensorRank2Vec2D<D, I, J>) -> Self::Output {
256 todo!()
257 }
258}
259
260impl<const D: usize, const I: usize, const J: usize> Div<TensorRank2SparseVec2D<D, I, J>>
261 for &TensorRank1Vec<D, I>
262{
263 type Output = TensorRank1Vec<D, J>;
264 fn div(self, _tensor_rank_2_sparse_vec_2d: TensorRank2SparseVec2D<D, I, J>) -> Self::Output {
265 todo!()
266 }
267}
268
269impl<const D: usize, const I: usize, const J: usize> Div<TensorRank2SparseVec2DSymmetric<D, I, J>>
270 for &TensorRank1Vec<D, I>
271{
272 type Output = TensorRank1Vec<D, J>;
273 fn div(
274 self,
275 _tensor_rank_2_sparse_symmetric_vec_2d: TensorRank2SparseVec2DSymmetric<D, I, J>,
276 ) -> Self::Output {
277 todo!()
278 }
279}
280
281impl<const D: usize, const I: usize> FiniteDifference for TensorRank1Vec<D, I> {
282 fn error_fd(&self, comparator: &Self, epsilon: TensorRank0) -> Option<(bool, usize)> {
283 let error_count = self
284 .iter()
285 .zip(comparator.iter())
286 .map(|(entry, comparator_entry)| {
287 entry
288 .iter()
289 .zip(comparator_entry.iter())
290 .filter(|&(&entry_i, &comparator_entry_i)| {
291 (entry_i / comparator_entry_i - 1.0).abs() >= epsilon
292 && (entry_i.abs() >= epsilon || comparator_entry_i.abs() >= epsilon)
293 })
294 .count()
295 })
296 .sum();
297 if error_count > 0 {
298 let auxiliary = self
299 .iter()
300 .zip(comparator.iter())
301 .map(|(entry, comparator_entry)| {
302 entry
303 .iter()
304 .zip(comparator_entry.iter())
305 .filter(|&(&entry_i, &comparator_entry_i)| {
306 (entry_i / comparator_entry_i - 1.0).abs() >= epsilon
307 && (entry_i - comparator_entry_i).abs() >= epsilon
308 && (entry_i.abs() >= epsilon || comparator_entry_i.abs() >= epsilon)
309 })
310 .count()
311 })
312 .sum::<usize>()
313 > 0;
314 Some((auxiliary, error_count))
315 } else {
316 None
317 }
318 }
319}