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}
233
234impl<const D: usize, const I: usize, const J: usize, const K: usize> Mul<TensorRank2<D, J, K>>
235 for TensorRank2Vec2D<D, I, J>
236{
237 type Output = TensorRank2Vec2D<D, I, K>;
238 fn mul(self, tensor_rank_2: TensorRank2<D, J, K>) -> Self::Output {
239 self.iter()
240 .map(|self_entry| {
241 self_entry
242 .iter()
243 .map(|self_tensor_rank_2| self_tensor_rank_2 * &tensor_rank_2)
244 .collect()
245 })
246 .collect()
247 }
248}
249
250impl<const D: usize, const I: usize, const J: usize, const K: usize> Mul<&TensorRank2<D, J, K>>
251 for TensorRank2Vec2D<D, I, J>
252{
253 type Output = TensorRank2Vec2D<D, I, K>;
254 fn mul(self, tensor_rank_2: &TensorRank2<D, J, K>) -> Self::Output {
255 self.iter()
256 .map(|self_entry| {
257 self_entry
258 .iter()
259 .map(|self_tensor_rank_2| self_tensor_rank_2 * tensor_rank_2)
260 .collect()
261 })
262 .collect()
263 }
264}
265
266impl<const D: usize, const I: usize, const J: usize> Add for TensorRank2Vec2D<D, I, J> {
267 type Output = Self;
268 fn add(mut self, tensor_rank_2_vec_2d: Self) -> Self::Output {
269 self += tensor_rank_2_vec_2d;
270 self
271 }
272}
273
274impl<const D: usize, const I: usize, const J: usize> Add<&Self> for TensorRank2Vec2D<D, I, J> {
275 type Output = Self;
276 fn add(mut self, tensor_rank_2_vec_2d: &Self) -> Self::Output {
277 self += tensor_rank_2_vec_2d;
278 self
279 }
280}
281
282impl<const D: usize, const I: usize, const J: usize> AddAssign for TensorRank2Vec2D<D, I, J> {
283 fn add_assign(&mut self, tensor_rank_2_vec_2d: Self) {
284 self.iter_mut()
285 .zip(tensor_rank_2_vec_2d.iter())
286 .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry += tensor_rank_2_vec);
287 }
288}
289
290impl<const D: usize, const I: usize, const J: usize> AddAssign<&Self>
291 for TensorRank2Vec2D<D, I, J>
292{
293 fn add_assign(&mut self, tensor_rank_2_vec_2d: &Self) {
294 self.iter_mut()
295 .zip(tensor_rank_2_vec_2d.iter())
296 .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry += tensor_rank_2_vec);
297 }
298}
299
300impl<const D: usize, const I: usize, const J: usize> Div<TensorRank0>
301 for TensorRank2Vec2D<D, I, J>
302{
303 type Output = Self;
304 fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
305 self /= &tensor_rank_0;
306 self
307 }
308}
309
310impl<const D: usize, const I: usize, const J: usize> Div<&TensorRank0>
311 for TensorRank2Vec2D<D, I, J>
312{
313 type Output = Self;
314 fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
315 self /= tensor_rank_0;
316 self
317 }
318}
319
320impl<const D: usize, const I: usize, const J: usize> DivAssign<TensorRank0>
321 for TensorRank2Vec2D<D, I, J>
322{
323 fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
324 self.iter_mut().for_each(|entry| *entry /= &tensor_rank_0);
325 }
326}
327
328impl<const D: usize, const I: usize, const J: usize> DivAssign<&TensorRank0>
329 for TensorRank2Vec2D<D, I, J>
330{
331 fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
332 self.iter_mut().for_each(|entry| *entry /= tensor_rank_0);
333 }
334}
335
336impl<const D: usize, const I: usize, const J: usize> Mul<TensorRank0>
337 for TensorRank2Vec2D<D, I, J>
338{
339 type Output = Self;
340 fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
341 self *= &tensor_rank_0;
342 self
343 }
344}
345
346impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank0>
347 for TensorRank2Vec2D<D, I, J>
348{
349 type Output = Self;
350 fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
351 self *= tensor_rank_0;
352 self
353 }
354}
355
356impl<const D: usize, const I: usize, const J: usize> MulAssign<TensorRank0>
357 for TensorRank2Vec2D<D, I, J>
358{
359 fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
360 self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
361 }
362}
363
364impl<const D: usize, const I: usize, const J: usize> MulAssign<&TensorRank0>
365 for TensorRank2Vec2D<D, I, J>
366{
367 fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
368 self.iter_mut().for_each(|entry| *entry *= tensor_rank_0);
369 }
370}
371
372impl<const D: usize, const I: usize, const J: usize> Sub for TensorRank2Vec2D<D, I, J> {
373 type Output = Self;
374 fn sub(mut self, tensor_rank_2_vec_2d: Self) -> Self::Output {
375 self -= tensor_rank_2_vec_2d;
376 self
377 }
378}
379
380impl<const D: usize, const I: usize, const J: usize> Sub<&Self> for TensorRank2Vec2D<D, I, J> {
381 type Output = Self;
382 fn sub(mut self, tensor_rank_2_vec_2d: &Self) -> Self::Output {
383 self -= tensor_rank_2_vec_2d;
384 self
385 }
386}
387
388impl<const D: usize, const I: usize, const J: usize> SubAssign for TensorRank2Vec2D<D, I, J> {
389 fn sub_assign(&mut self, tensor_rank_2_vec_2d: Self) {
390 self.iter_mut()
391 .zip(tensor_rank_2_vec_2d.iter())
392 .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry -= tensor_rank_2_vec);
393 }
394}
395
396impl<const D: usize, const I: usize, const J: usize> SubAssign<&Self>
397 for TensorRank2Vec2D<D, I, J>
398{
399 fn sub_assign(&mut self, tensor_rank_2_vec_2d: &Self) {
400 self.iter_mut()
401 .zip(tensor_rank_2_vec_2d.iter())
402 .for_each(|(self_entry, tensor_rank_2_vec)| *self_entry -= tensor_rank_2_vec);
403 }
404}