1#[cfg(test)]
2use super::super::test::ErrorTensor;
3
4use crate::math::{
5 Hessian, SquareMatrix, Tensor, TensorRank0, TensorRank2, TensorRank2Vec, TensorVec,
6};
7use std::{
8 fmt::{Display, Formatter, Result},
9 ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign},
10};
11
12#[derive(Clone, Debug)]
16pub struct TensorRank2Vec2D<const D: usize, const I: usize, const J: usize>(
17 Vec<TensorRank2Vec<D, I, J>>,
18);
19
20impl<const D: usize, const I: usize, const J: usize> Display for TensorRank2Vec2D<D, I, J> {
21 fn fmt(&self, _f: &mut Formatter) -> Result {
22 Ok(())
23 }
24}
25
26#[cfg(test)]
27impl<const D: usize, const I: usize, const J: usize> ErrorTensor for TensorRank2Vec2D<D, I, J> {
28 fn error(
29 &self,
30 comparator: &Self,
31 tol_abs: &TensorRank0,
32 tol_rel: &TensorRank0,
33 ) -> Option<usize> {
34 let error_count = self
35 .iter()
36 .zip(comparator.iter())
37 .map(|(self_a, comparator_a)| {
38 self_a
39 .iter()
40 .zip(comparator_a.iter())
41 .map(|(self_ab, comparator_ab)| {
42 self_ab
43 .iter()
44 .zip(comparator_ab.iter())
45 .map(|(self_ab_i, comparator_ab_i)| {
46 self_ab_i
47 .iter()
48 .zip(comparator_ab_i.iter())
49 .filter(|&(&self_ab_ij, &comparator_ab_ij)| {
50 &(self_ab_ij - comparator_ab_ij).abs() >= tol_abs
51 && &(self_ab_ij / comparator_ab_ij - 1.0).abs()
52 >= tol_rel
53 })
54 .count()
55 })
56 .sum::<usize>()
57 })
58 .sum::<usize>()
59 })
60 .sum();
61 if error_count > 0 {
62 Some(error_count)
63 } else {
64 None
65 }
66 }
67 fn error_fd(&self, comparator: &Self, epsilon: &TensorRank0) -> Option<(bool, usize)> {
68 let error_count = self
69 .iter()
70 .zip(comparator.iter())
71 .map(|(self_a, comparator_a)| {
72 self_a
73 .iter()
74 .zip(comparator_a.iter())
75 .map(|(self_ab, comparator_ab)| {
76 self_ab
77 .iter()
78 .zip(comparator_ab.iter())
79 .map(|(self_ab_i, comparator_ab_i)| {
80 self_ab_i
81 .iter()
82 .zip(comparator_ab_i.iter())
83 .filter(|&(&self_ab_ij, &comparator_ab_ij)| {
84 &(self_ab_ij / comparator_ab_ij - 1.0).abs() >= epsilon
85 && (&self_ab_ij.abs() >= epsilon
86 || &comparator_ab_ij.abs() >= epsilon)
87 })
88 .count()
89 })
90 .sum::<usize>()
91 })
92 .sum::<usize>()
93 })
94 .sum();
95 if error_count > 0 {
96 let auxillary = self
97 .iter()
98 .zip(comparator.iter())
99 .map(|(self_a, comparator_a)| {
100 self_a
101 .iter()
102 .zip(comparator_a.iter())
103 .map(|(self_ab, comparator_ab)| {
104 self_ab
105 .iter()
106 .zip(comparator_ab.iter())
107 .map(|(self_ab_i, comparator_ab_i)| {
108 self_ab_i
109 .iter()
110 .zip(comparator_ab_i.iter())
111 .filter(|&(&self_ab_ij, &comparator_ab_ij)| {
112 &(self_ab_ij / comparator_ab_ij - 1.0).abs() >= epsilon
113 && &(self_ab_ij - comparator_ab_ij).abs() >= epsilon
114 && (&self_ab_ij.abs() >= epsilon
115 || &comparator_ab_ij.abs() >= epsilon)
116 })
117 .count()
118 })
119 .sum::<usize>()
120 })
121 .sum::<usize>()
122 })
123 .sum::<usize>()
124 > 0;
125 Some((auxillary, error_count))
126 } else {
127 None
128 }
129 }
130}
131
132impl<const D: usize, const I: usize, const J: usize> FromIterator<TensorRank2Vec<D, I, J>>
133 for TensorRank2Vec2D<D, I, J>
134{
135 fn from_iter<Ii: IntoIterator<Item = TensorRank2Vec<D, I, J>>>(into_iterator: Ii) -> Self {
136 Self(Vec::from_iter(into_iterator))
137 }
138}
139
140impl<const D: usize, const I: usize, const J: usize> From<TensorRank2Vec2D<D, I, J>>
141 for Vec<TensorRank0>
142{
143 fn from(tensor_rank_2_vec_2d: TensorRank2Vec2D<D, I, J>) -> Self {
144 tensor_rank_2_vec_2d
145 .iter()
146 .flat_map(|tensor_rank_2_vec_1d| {
147 tensor_rank_2_vec_1d.iter().flat_map(|tensor_rank_2| {
148 tensor_rank_2
149 .iter()
150 .flat_map(|tensor_rank_1| tensor_rank_1.iter().copied())
151 })
152 })
153 .collect()
154 }
155}
156
157impl<const D: usize, const I: usize, const J: usize> Index<usize> for TensorRank2Vec2D<D, I, J> {
158 type Output = TensorRank2Vec<D, I, J>;
159 fn index(&self, index: usize) -> &Self::Output {
160 &self.0[index]
161 }
162}
163
164impl<const D: usize, const I: usize, const J: usize> IndexMut<usize> for TensorRank2Vec2D<D, I, J> {
165 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
166 &mut self.0[index]
167 }
168}
169
170impl<const D: usize, const I: usize, const J: usize> TensorVec for TensorRank2Vec2D<D, I, J> {
171 type Item = TensorRank2Vec<D, I, J>;
172 type Slice<'a> = &'a [&'a [[[TensorRank0; D]; D]]];
173 fn append(&mut self, other: &mut Self) {
174 self.0.append(&mut other.0)
175 }
176 fn is_empty(&self) -> bool {
177 self.0.is_empty()
178 }
179 fn len(&self) -> usize {
180 self.0.len()
181 }
182 fn new(slice: Self::Slice<'_>) -> Self {
183 slice
184 .iter()
185 .map(|slice_entry| Self::Item::new(slice_entry))
186 .collect()
187 }
188 fn push(&mut self, item: Self::Item) {
189 self.0.push(item)
190 }
191 fn zero(len: usize) -> Self {
192 (0..len).map(|_| Self::Item::zero(len)).collect()
193 }
194}
195
196impl<const D: usize, const I: usize, const J: usize> Tensor for TensorRank2Vec2D<D, I, J> {
197 type Item = TensorRank2Vec<D, I, J>;
198 fn iter(&self) -> impl Iterator<Item = &Self::Item> {
199 self.0.iter()
200 }
201 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
202 self.0.iter_mut()
203 }
204}
205
206impl<const D: usize, const I: usize, const J: usize> IntoIterator for TensorRank2Vec2D<D, I, J> {
207 type Item = TensorRank2Vec<D, I, J>;
208 type IntoIter = std::vec::IntoIter<Self::Item>;
209 fn into_iter(self) -> Self::IntoIter {
210 self.0.into_iter()
211 }
212}
213
214impl<const D: usize, const I: usize, const J: usize> Hessian for TensorRank2Vec2D<D, I, J> {
215 fn fill_into(self, square_matrix: &mut SquareMatrix) {
216 self.into_iter().enumerate().for_each(|(a, entry_a)| {
217 entry_a.into_iter().enumerate().for_each(|(b, entry_ab)| {
218 entry_ab
219 .into_iter()
220 .enumerate()
221 .for_each(|(i, entry_ab_i)| {
222 entry_ab_i
223 .into_iter()
224 .enumerate()
225 .for_each(|(j, entry_ab_ij)| {
226 square_matrix[D * a + i][D * b + j] = entry_ab_ij
227 })
228 })
229 })
230 });
231 }
232 fn is_positive_definite(&self) -> bool {
233 todo!()
234 }
235}
236
237impl<const D: usize, const I: usize, const J: usize, const K: usize> Mul<TensorRank2<D, J, K>>
238 for TensorRank2Vec2D<D, I, J>
239{
240 type Output = TensorRank2Vec2D<D, I, K>;
241 fn mul(self, tensor_rank_2: TensorRank2<D, J, K>) -> Self::Output {
242 self.iter()
243 .map(|self_entry| {
244 self_entry
245 .iter()
246 .map(|self_tensor_rank_2| self_tensor_rank_2 * &tensor_rank_2)
247 .collect()
248 })
249 .collect()
250 }
251}
252
253impl<const D: usize, const I: usize, const J: usize, const K: usize> Mul<&TensorRank2<D, J, K>>
254 for TensorRank2Vec2D<D, I, J>
255{
256 type Output = TensorRank2Vec2D<D, I, K>;
257 fn mul(self, tensor_rank_2: &TensorRank2<D, J, K>) -> Self::Output {
258 self.iter()
259 .map(|self_entry| {
260 self_entry
261 .iter()
262 .map(|self_tensor_rank_2| self_tensor_rank_2 * tensor_rank_2)
263 .collect()
264 })
265 .collect()
266 }
267}
268
269impl<const D: usize, const I: usize, const J: usize> Add for TensorRank2Vec2D<D, I, J> {
270 type Output = Self;
271 fn add(mut self, tensor_rank_2_vec_2d: Self) -> Self::Output {
272 self += tensor_rank_2_vec_2d;
273 self
274 }
275}
276
277impl<const D: usize, const I: usize, const J: usize> Add<&Self> for TensorRank2Vec2D<D, I, J> {
278 type Output = Self;
279 fn add(mut self, tensor_rank_2_vec_2d: &Self) -> Self::Output {
280 self += tensor_rank_2_vec_2d;
281 self
282 }
283}
284
285impl<const D: usize, const I: usize, const J: usize> AddAssign for TensorRank2Vec2D<D, I, J> {
286 fn add_assign(&mut self, tensor_rank_2_vec_2d: Self) {
287 self.iter_mut()
288 .zip(tensor_rank_2_vec_2d.iter())
289 .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry += tensor_rank_2_vec);
290 }
291}
292
293impl<const D: usize, const I: usize, const J: usize> AddAssign<&Self>
294 for TensorRank2Vec2D<D, I, J>
295{
296 fn add_assign(&mut self, tensor_rank_2_vec_2d: &Self) {
297 self.iter_mut()
298 .zip(tensor_rank_2_vec_2d.iter())
299 .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry += tensor_rank_2_vec);
300 }
301}
302
303impl<const D: usize, const I: usize, const J: usize> Div<TensorRank0>
304 for TensorRank2Vec2D<D, I, J>
305{
306 type Output = Self;
307 fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
308 self /= &tensor_rank_0;
309 self
310 }
311}
312
313impl<const D: usize, const I: usize, const J: usize> Div<&TensorRank0>
314 for TensorRank2Vec2D<D, I, J>
315{
316 type Output = Self;
317 fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
318 self /= tensor_rank_0;
319 self
320 }
321}
322
323impl<const D: usize, const I: usize, const J: usize> DivAssign<TensorRank0>
324 for TensorRank2Vec2D<D, I, J>
325{
326 fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
327 self.iter_mut().for_each(|entry| *entry /= &tensor_rank_0);
328 }
329}
330
331impl<const D: usize, const I: usize, const J: usize> DivAssign<&TensorRank0>
332 for TensorRank2Vec2D<D, I, J>
333{
334 fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
335 self.iter_mut().for_each(|entry| *entry /= tensor_rank_0);
336 }
337}
338
339impl<const D: usize, const I: usize, const J: usize> Mul<TensorRank0>
340 for TensorRank2Vec2D<D, I, J>
341{
342 type Output = Self;
343 fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
344 self *= &tensor_rank_0;
345 self
346 }
347}
348
349impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank0>
350 for TensorRank2Vec2D<D, I, J>
351{
352 type Output = Self;
353 fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
354 self *= tensor_rank_0;
355 self
356 }
357}
358
359impl<const D: usize, const I: usize, const J: usize> MulAssign<TensorRank0>
360 for TensorRank2Vec2D<D, I, J>
361{
362 fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
363 self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
364 }
365}
366
367impl<const D: usize, const I: usize, const J: usize> MulAssign<&TensorRank0>
368 for TensorRank2Vec2D<D, I, J>
369{
370 fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
371 self.iter_mut().for_each(|entry| *entry *= tensor_rank_0);
372 }
373}
374
375impl<const D: usize, const I: usize, const J: usize> Sub for TensorRank2Vec2D<D, I, J> {
376 type Output = Self;
377 fn sub(mut self, tensor_rank_2_vec_2d: Self) -> Self::Output {
378 self -= tensor_rank_2_vec_2d;
379 self
380 }
381}
382
383impl<const D: usize, const I: usize, const J: usize> Sub<&Self> for TensorRank2Vec2D<D, I, J> {
384 type Output = Self;
385 fn sub(mut self, tensor_rank_2_vec_2d: &Self) -> Self::Output {
386 self -= tensor_rank_2_vec_2d;
387 self
388 }
389}
390
391impl<const D: usize, const I: usize, const J: usize> SubAssign for TensorRank2Vec2D<D, I, J> {
392 fn sub_assign(&mut self, tensor_rank_2_vec_2d: Self) {
393 self.iter_mut()
394 .zip(tensor_rank_2_vec_2d.iter())
395 .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry -= tensor_rank_2_vec);
396 }
397}
398
399impl<const D: usize, const I: usize, const J: usize> SubAssign<&Self>
400 for TensorRank2Vec2D<D, I, J>
401{
402 fn sub_assign(&mut self, tensor_rank_2_vec_2d: &Self) {
403 self.iter_mut()
404 .zip(tensor_rank_2_vec_2d.iter())
405 .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry -= tensor_rank_2_vec);
406 }
407}