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