1#[cfg(test)]
2mod test;
3
4mod inverse;
5pub(crate) mod list;
6pub(crate) mod list_2d;
7mod logarithm;
8pub(crate) mod sparse_symmetric_vec_2d;
9pub(crate) mod sparse_vec;
10pub(crate) mod sparse_vec_2d;
11pub(crate) mod vec;
12pub(crate) mod vec_2d;
13
14use std::{
15 array::{IntoIter, from_fn},
16 fmt::{self, Display, Formatter},
17 iter::Sum,
18 mem::transmute,
19 ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign},
20};
21
22use super::{
23 Hessian, Jacobian, Rank2, Solution, SquareMatrix, Tensor, TensorArray, Vector,
24 rank_0::TensorRank0,
25 rank_1::{TensorRank1, list::TensorRank1List, vec::TensorRank1Vec, zero as tensor_rank_1_zero},
26 rank_4::TensorRank4,
27};
28use crate::ABS_TOL;
29use list_2d::TensorRank2List2D;
30use vec_2d::TensorRank2Vec2D;
31
32use crate::math::assert::FiniteDifference;
33
34#[repr(transparent)]
38#[derive(Clone, Debug, PartialEq)]
39pub struct TensorRank2<const D: usize, const I: usize, const J: usize>([TensorRank1<D, J>; D]);
40
41impl<const D: usize, const I: usize, const J: usize> Default for TensorRank2<D, I, J> {
42 fn default() -> Self {
43 Self::zero()
44 }
45}
46
47impl<const D: usize, const I: usize, const J: usize> From<[[TensorRank0; D]; D]>
48 for TensorRank2<D, I, J>
49{
50 fn from(array: [[TensorRank0; D]; D]) -> Self {
51 Self(from_fn(|i| array[i].into()))
52 }
53}
54
55impl<const D: usize, const I: usize, const J: usize> From<TensorRank2<D, I, J>>
56 for [[TensorRank0; D]; D]
57{
58 fn from(tensor_rank_2: TensorRank2<D, I, J>) -> Self {
59 from_fn(|i| from_fn(|j| tensor_rank_2[i][j]))
60 }
61}
62
63pub(crate) const fn get_levi_civita_parts<const I: usize, const J: usize>()
64-> [TensorRank2<3, I, J>; 3] {
65 [
66 TensorRank2([
67 tensor_rank_1_zero(),
68 TensorRank1::const_from([0.0, 0.0, 1.0]),
69 TensorRank1::const_from([0.0, -1.0, 0.0]),
70 ]),
71 TensorRank2([
72 TensorRank1::const_from([0.0, 0.0, -1.0]),
73 tensor_rank_1_zero(),
74 TensorRank1::const_from([1.0, 0.0, 0.0]),
75 ]),
76 TensorRank2([
77 TensorRank1::const_from([0.0, 1.0, 0.0]),
78 TensorRank1::const_from([-1.0, 0.0, 0.0]),
79 tensor_rank_1_zero(),
80 ]),
81 ]
82}
83
84pub(crate) const fn get_identity_1010_parts_1<const I: usize, const J: usize>()
85-> [TensorRank2<3, I, J>; 3] {
86 [
87 TensorRank2([
88 TensorRank1::const_from([1.0, 0.0, 0.0]),
89 tensor_rank_1_zero(),
90 tensor_rank_1_zero(),
91 ]),
92 TensorRank2([
93 TensorRank1::const_from([0.0, 1.0, 0.0]),
94 tensor_rank_1_zero(),
95 tensor_rank_1_zero(),
96 ]),
97 TensorRank2([
98 TensorRank1::const_from([0.0, 0.0, 1.0]),
99 tensor_rank_1_zero(),
100 tensor_rank_1_zero(),
101 ]),
102 ]
103}
104
105pub(crate) const fn get_identity_1010_parts_2<const I: usize, const J: usize>()
106-> [TensorRank2<3, I, J>; 3] {
107 [
108 TensorRank2([
109 tensor_rank_1_zero(),
110 TensorRank1::const_from([1.0, 0.0, 0.0]),
111 tensor_rank_1_zero(),
112 ]),
113 TensorRank2([
114 tensor_rank_1_zero(),
115 TensorRank1::const_from([0.0, 1.0, 0.0]),
116 tensor_rank_1_zero(),
117 ]),
118 TensorRank2([
119 tensor_rank_1_zero(),
120 TensorRank1::const_from([0.0, 0.0, 1.0]),
121 tensor_rank_1_zero(),
122 ]),
123 ]
124}
125
126pub(crate) const fn get_identity_1010_parts_3<const I: usize, const J: usize>()
127-> [TensorRank2<3, I, J>; 3] {
128 [
129 TensorRank2([
130 tensor_rank_1_zero(),
131 tensor_rank_1_zero(),
132 TensorRank1::const_from([1.0, 0.0, 0.0]),
133 ]),
134 TensorRank2([
135 tensor_rank_1_zero(),
136 tensor_rank_1_zero(),
137 TensorRank1::const_from([0.0, 1.0, 0.0]),
138 ]),
139 TensorRank2([
140 tensor_rank_1_zero(),
141 tensor_rank_1_zero(),
142 TensorRank1::const_from([0.0, 0.0, 1.0]),
143 ]),
144 ]
145}
146
147pub const IDENTITY: TensorRank2<3, 1, 1> = TensorRank2([
149 TensorRank1::const_from([1.0, 0.0, 0.0]),
150 TensorRank1::const_from([0.0, 1.0, 0.0]),
151 TensorRank1::const_from([0.0, 0.0, 1.0]),
152]);
153
154pub const IDENTITY_00: TensorRank2<3, 0, 0> = TensorRank2([
156 TensorRank1::const_from([1.0, 0.0, 0.0]),
157 TensorRank1::const_from([0.0, 1.0, 0.0]),
158 TensorRank1::const_from([0.0, 0.0, 1.0]),
159]);
160
161pub const IDENTITY_10: TensorRank2<3, 1, 0> = TensorRank2([
163 TensorRank1::const_from([1.0, 0.0, 0.0]),
164 TensorRank1::const_from([0.0, 1.0, 0.0]),
165 TensorRank1::const_from([0.0, 0.0, 1.0]),
166]);
167
168pub const IDENTITY_22: TensorRank2<3, 2, 2> = TensorRank2([
170 TensorRank1::const_from([1.0, 0.0, 0.0]),
171 TensorRank1::const_from([0.0, 1.0, 0.0]),
172 TensorRank1::const_from([0.0, 0.0, 1.0]),
173]);
174
175pub const ZERO: TensorRank2<3, 1, 1> = TensorRank2([
177 tensor_rank_1_zero(),
178 tensor_rank_1_zero(),
179 tensor_rank_1_zero(),
180]);
181
182pub const ZERO_10: TensorRank2<3, 1, 0> = TensorRank2([
184 tensor_rank_1_zero(),
185 tensor_rank_1_zero(),
186 tensor_rank_1_zero(),
187]);
188
189impl<const D: usize, const I: usize, const J: usize> From<TensorRank1List<D, J, D>>
190 for TensorRank2<D, I, J>
191{
192 fn from(tensor_rank_1_list: TensorRank1List<D, J, D>) -> Self {
193 tensor_rank_1_list.into_iter().collect()
194 }
195}
196
197impl<const D: usize, const I: usize, const J: usize> From<(TensorRank1<D, I>, TensorRank1<D, J>)>
198 for TensorRank2<D, I, J>
199{
200 fn from((vector_a, vector_b): (TensorRank1<D, I>, TensorRank1<D, J>)) -> Self {
201 vector_a
202 .into_iter()
203 .map(|vector_a_i| {
204 vector_b
205 .iter()
206 .map(|vector_b_j| vector_a_i * vector_b_j)
207 .collect()
208 })
209 .collect()
210 }
211}
212
213impl<const D: usize, const I: usize, const J: usize> From<(TensorRank1<D, I>, &TensorRank1<D, J>)>
214 for TensorRank2<D, I, J>
215{
216 fn from((vector_a, vector_b): (TensorRank1<D, I>, &TensorRank1<D, J>)) -> Self {
217 vector_a
218 .into_iter()
219 .map(|vector_a_i| {
220 vector_b
221 .iter()
222 .map(|vector_b_j| vector_a_i * vector_b_j)
223 .collect()
224 })
225 .collect()
226 }
227}
228
229impl<const D: usize, const I: usize, const J: usize> From<(&TensorRank1<D, I>, TensorRank1<D, J>)>
230 for TensorRank2<D, I, J>
231{
232 fn from((vector_a, vector_b): (&TensorRank1<D, I>, TensorRank1<D, J>)) -> Self {
233 vector_a
234 .iter()
235 .map(|vector_a_i| {
236 vector_b
237 .iter()
238 .map(|vector_b_j| vector_a_i * vector_b_j)
239 .collect()
240 })
241 .collect()
242 }
243}
244
245impl<const D: usize, const I: usize, const J: usize> From<(&TensorRank1<D, I>, &TensorRank1<D, J>)>
246 for TensorRank2<D, I, J>
247{
248 fn from((vector_a, vector_b): (&TensorRank1<D, I>, &TensorRank1<D, J>)) -> Self {
249 vector_a
250 .iter()
251 .map(|vector_a_i| {
252 vector_b
253 .iter()
254 .map(|vector_b_j| vector_a_i * vector_b_j)
255 .collect()
256 })
257 .collect()
258 }
259}
260
261impl<const D: usize, const I: usize, const J: usize> From<Vec<Vec<TensorRank0>>>
262 for TensorRank2<D, I, J>
263{
264 fn from(vec: Vec<Vec<TensorRank0>>) -> Self {
265 assert_eq!(vec.len(), D);
266 vec.iter().for_each(|entry| assert_eq!(entry.len(), D));
267 vec.into_iter()
268 .map(|entry| entry.into_iter().collect())
269 .collect()
270 }
271}
272
273impl<const D: usize, const I: usize, const J: usize> From<TensorRank2<D, I, J>>
274 for Vec<Vec<TensorRank0>>
275{
276 fn from(tensor: TensorRank2<D, I, J>) -> Self {
277 tensor
278 .iter()
279 .map(|entry| entry.iter().copied().collect())
280 .collect()
281 }
282}
283
284impl<const D: usize, const I: usize, const J: usize> Display for TensorRank2<D, I, J> {
285 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
286 write!(f, "[")?;
287 self.iter()
288 .enumerate()
289 .try_for_each(|(i, row)| write!(f, "{row},\n\x1B[u\x1B[{}B", i + 1))?;
290 write!(f, "\x1B[u\x1B[1A\x1B[{}C]", 16 * D)
291 }
292}
293
294impl<const D: usize, const I: usize, const J: usize> FiniteDifference for TensorRank2<D, I, J> {
295 fn error_fd(&self, comparator: &Self, epsilon: TensorRank0) -> Option<(bool, usize)> {
296 let error_count = self
297 .iter()
298 .zip(comparator.iter())
299 .map(|(self_i, comparator_i)| {
300 self_i
301 .iter()
302 .zip(comparator_i.iter())
303 .filter(|&(&self_ij, &comparator_ij)| {
304 (self_ij / comparator_ij - 1.0).abs() >= epsilon
305 && (self_ij.abs() >= epsilon || comparator_ij.abs() >= epsilon)
306 })
307 .count()
308 })
309 .sum();
310 if error_count > 0 {
311 Some((true, error_count))
312 } else {
313 None
314 }
315 }
316}
317
318impl<const D: usize, const I: usize, const J: usize> TensorRank2<D, I, J> {
319 pub const fn as_ptr(&self) -> *const TensorRank1<D, J> {
321 self.0.as_ptr()
322 }
323 pub fn as_tensor_rank_1(&self) -> TensorRank1<9, 88> {
325 assert_eq!(D, 3);
326 let mut tensor_rank_1 = TensorRank1::<9, 88>::zero();
327 self.iter().enumerate().for_each(|(i, self_i)| {
328 self_i
329 .iter()
330 .enumerate()
331 .for_each(|(j, self_ij)| tensor_rank_1[3 * i + j] = *self_ij)
332 });
333 tensor_rank_1
334 }
335}
336
337impl<const D: usize, const I: usize, const J: usize> Hessian for TensorRank2<D, I, J> {
338 fn entry(&self, row: usize, column: usize) -> TensorRank0 {
339 self[row][column]
340 }
341 fn fill_into(self, square_matrix: &mut SquareMatrix) {
342 self.into_iter().enumerate().for_each(|(i, self_i)| {
343 self_i
344 .into_iter()
345 .enumerate()
346 .for_each(|(j, self_ij)| square_matrix[i][j] = self_ij)
347 })
348 }
349}
350
351impl<const D: usize, const I: usize, const J: usize> Rank2 for TensorRank2<D, I, J> {
352 type Transpose = TensorRank2<D, J, I>;
353 fn deviatoric(&self) -> Self {
354 Self::identity() * (self.trace() / -(D as TensorRank0)) + self
355 }
356 fn deviatoric_and_trace(&self) -> (Self, TensorRank0) {
357 let trace = self.trace();
358 (
359 Self::identity() * (trace / -(D as TensorRank0)) + self,
360 trace,
361 )
362 }
363 fn is_diagonal(&self) -> bool {
364 self.iter()
365 .enumerate()
366 .map(|(i, self_i)| {
367 self_i
368 .iter()
369 .enumerate()
370 .map(|(j, self_ij)| (self_ij.abs() < ABS_TOL) as u8 * (i != j) as u8)
371 .sum::<u8>()
372 })
373 .sum::<u8>()
374 == (D.pow(2) - D) as u8
375 }
376 fn is_identity(&self) -> bool {
377 self.iter().enumerate().all(|(i, self_i)| {
378 self_i
379 .iter()
380 .enumerate()
381 .all(|(j, self_ij)| self_ij == &((i == j) as u8 as TensorRank0))
382 })
383 }
384 fn is_symmetric(&self) -> bool {
385 self.iter().enumerate().all(|(i, self_i)| {
386 self_i
387 .iter()
388 .zip(self.iter())
389 .all(|(self_ij, self_j)| self_ij == &self_j[i])
390 })
391 }
392 fn squared_trace(&self) -> TensorRank0 {
393 self.iter()
394 .enumerate()
395 .map(|(i, self_i)| {
396 self_i
397 .iter()
398 .zip(self.iter())
399 .map(|(self_ij, self_j)| self_ij * self_j[i])
400 .sum::<TensorRank0>()
401 })
402 .sum()
403 }
404 fn trace(&self) -> TensorRank0 {
405 self.iter().enumerate().map(|(i, self_i)| self_i[i]).sum()
406 }
407 fn transpose(&self) -> Self::Transpose {
408 (0..D)
409 .map(|i| (0..D).map(|j| self[j][i]).collect())
410 .collect()
412 }
413}
414
415impl<const D: usize, const I: usize, const J: usize> Tensor for TensorRank2<D, I, J> {
416 type Item = TensorRank1<D, J>;
417 fn iter(&self) -> impl Iterator<Item = &Self::Item> {
418 self.0.iter()
419 }
420 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
421 self.0.iter_mut()
422 }
423 fn len(&self) -> usize {
424 D
425 }
426 fn size(&self) -> usize {
427 D * D
428 }
429}
430
431impl<const D: usize, const I: usize, const J: usize> IntoIterator for TensorRank2<D, I, J> {
432 type Item = TensorRank1<D, J>;
433 type IntoIter = IntoIter<Self::Item, D>;
434 fn into_iter(self) -> Self::IntoIter {
435 self.0.into_iter()
436 }
437}
438
439impl<const D: usize, const I: usize, const J: usize> TensorArray for TensorRank2<D, I, J> {
440 type Array = [[TensorRank0; D]; D];
441 type Item = TensorRank1<D, J>;
442 fn as_array(&self) -> Self::Array {
443 let mut array = [[0.0; D]; D];
444 array
445 .iter_mut()
446 .zip(self.iter())
447 .for_each(|(entry, tensor_rank_1)| *entry = tensor_rank_1.as_array());
448 array
449 }
450 fn identity() -> Self {
451 (0..D)
452 .map(|i| (0..D).map(|j| ((i == j) as u8) as TensorRank0).collect())
453 .collect()
454 }
455 fn zero() -> Self {
456 Self(from_fn(|_| Self::Item::zero()))
457 }
458}
459
460impl<const D: usize, const I: usize, const J: usize> Solution for TensorRank2<D, I, J> {
461 fn decrement_from(&mut self, other: &Vector) {
462 self.iter_mut()
463 .flat_map(|x| x.iter_mut())
464 .zip(other.iter())
465 .for_each(|(self_i, vector_i)| *self_i -= vector_i)
466 }
467 fn decrement_from_chained(&mut self, other: &mut Vector, vector: Vector) {
468 self.iter_mut()
469 .flat_map(|x| x.iter_mut())
470 .chain(other.iter_mut())
471 .zip(vector)
472 .for_each(|(entry_i, vector_i)| *entry_i -= vector_i)
473 }
474}
475
476impl<const D: usize, const I: usize, const J: usize> Jacobian for TensorRank2<D, I, J> {
477 fn fill_into(self, vector: &mut Vector) {
478 self.into_iter()
479 .flatten()
480 .zip(vector.iter_mut())
481 .for_each(|(self_i, vector_i)| *vector_i = self_i)
482 }
483 fn fill_into_chained(self, other: Vector, vector: &mut Vector) {
484 self.into_iter()
485 .flatten()
486 .chain(other)
487 .zip(vector.iter_mut())
488 .for_each(|(self_i, vector_i)| *vector_i = self_i)
489 }
490}
491
492impl<const D: usize, const I: usize, const J: usize> Sub<Vector> for TensorRank2<D, I, J> {
493 type Output = Self;
494 fn sub(mut self, vector: Vector) -> Self::Output {
495 self.iter_mut().enumerate().for_each(|(i, self_i)| {
496 self_i
497 .iter_mut()
498 .enumerate()
499 .for_each(|(j, self_ij)| *self_ij -= vector[D * i + j])
500 });
501 self
502 }
503}
504
505impl<const D: usize, const I: usize, const J: usize> Sub<&Vector> for TensorRank2<D, I, J> {
506 type Output = Self;
507 fn sub(mut self, vector: &Vector) -> Self::Output {
508 self.iter_mut().enumerate().for_each(|(i, self_i)| {
509 self_i
510 .iter_mut()
511 .enumerate()
512 .for_each(|(j, self_ij)| *self_ij -= vector[D * i + j])
513 });
514 self
515 }
516}
517
518impl<const D: usize, const I: usize, const J: usize, const K: usize, const L: usize>
519 From<TensorRank4<D, I, J, K, L>> for TensorRank2<9, 88, 99>
520{
521 fn from(tensor_rank_4: TensorRank4<D, I, J, K, L>) -> Self {
522 assert_eq!(D, 3);
523 tensor_rank_4
524 .into_iter()
525 .flatten()
526 .map(|entry_ij| entry_ij.into_iter().flatten().collect())
527 .collect()
528 }
529}
530
531impl<const D: usize, const I: usize, const J: usize, const K: usize, const L: usize>
532 From<&TensorRank4<D, I, J, K, L>> for TensorRank2<9, 88, 99>
533{
534 fn from(tensor_rank_4: &TensorRank4<D, I, J, K, L>) -> Self {
535 assert_eq!(D, 3);
536 tensor_rank_4
537 .clone()
538 .into_iter()
539 .flatten()
540 .map(|entry_ij| entry_ij.into_iter().flatten().collect())
541 .collect()
542 }
543}
544
545impl From<TensorRank2<3, 0, 0>> for TensorRank2<3, 2, 2> {
546 fn from(tensor_rank_2: TensorRank2<3, 0, 0>) -> Self {
547 unsafe { transmute::<TensorRank2<3, 0, 0>, TensorRank2<3, 2, 2>>(tensor_rank_2) }
548 }
549}
550
551impl From<TensorRank2<3, 1, 1>> for TensorRank2<3, 2, 2> {
552 fn from(tensor_rank_2: TensorRank2<3, 1, 1>) -> Self {
553 unsafe { transmute::<TensorRank2<3, 1, 1>, TensorRank2<3, 2, 2>>(tensor_rank_2) }
554 }
555}
556
557impl<const I: usize> From<TensorRank2<3, I, 0>> for TensorRank2<3, I, 2> {
558 fn from(tensor_rank_2: TensorRank2<3, I, 0>) -> Self {
559 unsafe { transmute::<TensorRank2<3, I, 0>, TensorRank2<3, I, 2>>(tensor_rank_2) }
560 }
561}
562
563impl<const I: usize> From<TensorRank2<3, I, 1>> for TensorRank2<3, I, 0> {
564 fn from(tensor_rank_2: TensorRank2<3, I, 1>) -> Self {
565 unsafe { transmute::<TensorRank2<3, I, 1>, TensorRank2<3, I, 0>>(tensor_rank_2) }
566 }
567}
568
569impl<const I: usize> From<TensorRank2<3, I, 2>> for TensorRank2<3, I, 0> {
570 fn from(tensor_rank_2: TensorRank2<3, I, 2>) -> Self {
571 unsafe { transmute::<TensorRank2<3, I, 2>, TensorRank2<3, I, 0>>(tensor_rank_2) }
572 }
573}
574
575impl<const J: usize> From<TensorRank2<3, 0, J>> for TensorRank2<3, 1, J> {
576 fn from(tensor_rank_2: TensorRank2<3, 0, J>) -> Self {
577 unsafe { transmute::<TensorRank2<3, 0, J>, TensorRank2<3, 1, J>>(tensor_rank_2) }
578 }
579}
580
581impl<const J: usize> From<TensorRank2<3, 1, J>> for TensorRank2<3, 0, J> {
582 fn from(tensor_rank_2: TensorRank2<3, 1, J>) -> Self {
583 unsafe { transmute::<TensorRank2<3, 1, J>, TensorRank2<3, 0, J>>(tensor_rank_2) }
584 }
585}
586
587impl<const J: usize> From<TensorRank2<3, 1, J>> for TensorRank2<3, 2, J> {
588 fn from(tensor_rank_2: TensorRank2<3, 1, J>) -> Self {
589 unsafe { transmute::<TensorRank2<3, 1, J>, TensorRank2<3, 2, J>>(tensor_rank_2) }
590 }
591}
592
593impl<const J: usize> From<TensorRank2<3, 2, J>> for TensorRank2<3, 1, J> {
594 fn from(tensor_rank_2: TensorRank2<3, 2, J>) -> Self {
595 unsafe { transmute::<TensorRank2<3, 2, J>, TensorRank2<3, 1, J>>(tensor_rank_2) }
596 }
597}
598
599impl<const J: usize> From<&TensorRank2<3, 2, J>> for &TensorRank2<3, 1, J> {
600 fn from(tensor_rank_2: &TensorRank2<3, 2, J>) -> Self {
601 unsafe { transmute::<&TensorRank2<3, 2, J>, &TensorRank2<3, 1, J>>(tensor_rank_2) }
602 }
603}
604
605impl From<TensorRank2<3, 0, 0>> for TensorRank2<3, 1, 1> {
606 fn from(tensor_rank_2: TensorRank2<3, 0, 0>) -> Self {
607 unsafe { transmute::<TensorRank2<3, 0, 0>, TensorRank2<3, 1, 1>>(tensor_rank_2) }
608 }
609}
610
611impl<const D: usize, const I: usize, const J: usize> From<Vector> for TensorRank2<D, I, J> {
612 fn from(_vector: Vector) -> Self {
613 unimplemented!()
614 }
615}
616
617impl<const D: usize, const I: usize, const J: usize> FromIterator<TensorRank1<D, J>>
618 for TensorRank2<D, I, J>
619{
620 fn from_iter<Ii: IntoIterator<Item = TensorRank1<D, J>>>(into_iterator: Ii) -> Self {
621 let mut tensor_rank_2 = Self::zero();
622 tensor_rank_2
623 .iter_mut()
624 .zip(into_iterator)
625 .for_each(|(tensor_rank_2_i, value_i)| *tensor_rank_2_i = value_i);
626 tensor_rank_2
627 }
628}
629
630impl<const D: usize, const I: usize, const J: usize> Index<usize> for TensorRank2<D, I, J> {
631 type Output = TensorRank1<D, J>;
632 fn index(&self, index: usize) -> &Self::Output {
633 &self.0[index]
634 }
635}
636
637impl<const D: usize, const I: usize, const J: usize> IndexMut<usize> for TensorRank2<D, I, J> {
638 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
639 &mut self.0[index]
640 }
641}
642
643impl<const D: usize, const I: usize, const J: usize> Sum for TensorRank2<D, I, J> {
644 fn sum<Ii>(iter: Ii) -> Self
645 where
646 Ii: Iterator<Item = Self>,
647 {
648 iter.reduce(|mut acc, item| {
649 acc += item;
650 acc
651 })
652 .unwrap_or_else(Self::default)
653 }
654}
655
656impl<'a, const D: usize, const I: usize, const J: usize> Sum<&'a Self> for TensorRank2<D, I, J> {
657 fn sum<Ii>(iter: Ii) -> Self
658 where
659 Ii: Iterator<Item = &'a Self>,
660 {
661 iter.fold(Self::default(), |mut acc, item| {
662 acc += item;
663 acc
664 })
665 }
666}
667
668impl<const D: usize, const I: usize, const J: usize> Div<TensorRank0> for TensorRank2<D, I, J> {
669 type Output = Self;
670 fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
671 self /= tensor_rank_0;
672 self
673 }
674}
675
676impl<const D: usize, const I: usize, const J: usize> Div<TensorRank0> for &TensorRank2<D, I, J> {
677 type Output = TensorRank2<D, I, J>;
678 fn div(self, tensor_rank_0: TensorRank0) -> Self::Output {
679 self.iter().map(|self_i| self_i / tensor_rank_0).collect()
680 }
681}
682
683impl<const D: usize, const I: usize, const J: usize> Div<&TensorRank0> for TensorRank2<D, I, J> {
684 type Output = Self;
685 fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
686 self /= tensor_rank_0;
687 self
688 }
689}
690
691impl<const D: usize, const I: usize, const J: usize> Div<&TensorRank0> for &TensorRank2<D, I, J> {
692 type Output = TensorRank2<D, I, J>;
693 fn div(self, tensor_rank_0: &TensorRank0) -> Self::Output {
694 self.iter().map(|self_i| self_i / tensor_rank_0).collect()
695 }
696}
697
698impl<const D: usize, const I: usize, const J: usize> DivAssign<TensorRank0>
699 for TensorRank2<D, I, J>
700{
701 fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
702 self.iter_mut().for_each(|self_i| *self_i /= &tensor_rank_0);
703 }
704}
705
706impl<const D: usize, const I: usize, const J: usize> DivAssign<&TensorRank0>
707 for TensorRank2<D, I, J>
708{
709 fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
710 self.iter_mut().for_each(|self_i| *self_i /= tensor_rank_0);
711 }
712}
713
714impl<const D: usize, const I: usize, const J: usize> Mul<TensorRank0> for TensorRank2<D, I, J> {
715 type Output = Self;
716 fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
717 self *= &tensor_rank_0;
718 self
719 }
720}
721
722impl<const D: usize, const I: usize, const J: usize> Mul<TensorRank0> for &TensorRank2<D, I, J> {
723 type Output = TensorRank2<D, I, J>;
724 fn mul(self, tensor_rank_0: TensorRank0) -> Self::Output {
725 self.iter().map(|self_i| self_i * tensor_rank_0).collect()
726 }
727}
728
729impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank0> for TensorRank2<D, I, J> {
730 type Output = Self;
731 fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
732 self *= tensor_rank_0;
733 self
734 }
735}
736
737impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank0> for &TensorRank2<D, I, J> {
738 type Output = TensorRank2<D, I, J>;
739 fn mul(self, tensor_rank_0: &TensorRank0) -> Self::Output {
740 self.iter().map(|self_i| self_i * tensor_rank_0).collect()
741 }
742}
743
744impl<const D: usize, const I: usize, const J: usize> MulAssign<TensorRank0>
745 for TensorRank2<D, I, J>
746{
747 fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
748 self.iter_mut().for_each(|self_i| *self_i *= &tensor_rank_0);
749 }
750}
751
752impl<const D: usize, const I: usize, const J: usize> MulAssign<&TensorRank0>
753 for TensorRank2<D, I, J>
754{
755 fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
756 self.iter_mut().for_each(|self_i| *self_i *= tensor_rank_0);
757 }
758}
759
760impl<const D: usize, const I: usize, const J: usize> Mul<TensorRank1<D, J>>
761 for TensorRank2<D, I, J>
762{
763 type Output = TensorRank1<D, I>;
764 fn mul(self, tensor_rank_1: TensorRank1<D, J>) -> Self::Output {
765 self.into_iter()
766 .map(|self_i| self_i * &tensor_rank_1)
767 .collect()
768 }
769}
770
771impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank1<D, J>>
772 for TensorRank2<D, I, J>
773{
774 type Output = TensorRank1<D, I>;
775 fn mul(self, tensor_rank_1: &TensorRank1<D, J>) -> Self::Output {
776 self.into_iter()
777 .map(|self_i| self_i * tensor_rank_1)
778 .collect()
779 }
780}
781
782impl<const D: usize, const I: usize, const J: usize> Mul<TensorRank1<D, J>>
783 for &TensorRank2<D, I, J>
784{
785 type Output = TensorRank1<D, I>;
786 fn mul(self, tensor_rank_1: TensorRank1<D, J>) -> Self::Output {
787 self.iter().map(|self_i| self_i * &tensor_rank_1).collect()
788 }
789}
790
791impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank1<D, J>>
792 for &TensorRank2<D, I, J>
793{
794 type Output = TensorRank1<D, I>;
795 fn mul(self, tensor_rank_1: &TensorRank1<D, J>) -> Self::Output {
796 self.iter().map(|self_i| self_i * tensor_rank_1).collect()
797 }
798}
799
800impl<const D: usize, const I: usize, const J: usize> Add for TensorRank2<D, I, J> {
801 type Output = Self;
802 fn add(mut self, tensor_rank_2: Self) -> Self::Output {
803 self += tensor_rank_2;
804 self
805 }
806}
807
808impl<const D: usize, const I: usize, const J: usize> Add<&Self> for TensorRank2<D, I, J> {
809 type Output = Self;
810 fn add(mut self, tensor_rank_2: &Self) -> Self::Output {
811 self += tensor_rank_2;
812 self
813 }
814}
815
816impl<const D: usize, const I: usize, const J: usize> Add<TensorRank2<D, I, J>>
817 for &TensorRank2<D, I, J>
818{
819 type Output = TensorRank2<D, I, J>;
820 fn add(self, mut tensor_rank_2: TensorRank2<D, I, J>) -> Self::Output {
821 tensor_rank_2 += self;
822 tensor_rank_2
823 }
824}
825
826impl<const D: usize, const I: usize, const J: usize> AddAssign for TensorRank2<D, I, J> {
827 fn add_assign(&mut self, tensor_rank_2: Self) {
828 self.iter_mut()
829 .zip(tensor_rank_2)
830 .for_each(|(self_i, tensor_rank_2_i)| *self_i += tensor_rank_2_i);
831 }
832}
833
834impl<const D: usize, const I: usize, const J: usize> AddAssign<&Self> for TensorRank2<D, I, J> {
835 fn add_assign(&mut self, tensor_rank_2: &Self) {
836 self.iter_mut()
837 .zip(tensor_rank_2.iter())
838 .for_each(|(self_i, tensor_rank_2_i)| *self_i += tensor_rank_2_i);
839 }
840}
841
842impl<const D: usize, const I: usize, const J: usize, const K: usize> Mul<TensorRank2<D, J, K>>
843 for TensorRank2<D, I, J>
844{
845 type Output = TensorRank2<D, I, K>;
846 fn mul(self, tensor_rank_2: TensorRank2<D, J, K>) -> Self::Output {
847 self.into_iter()
848 .map(|self_i| {
849 self_i
850 .into_iter()
851 .zip(tensor_rank_2.iter())
852 .map(|(self_ij, tensor_rank_2_j)| tensor_rank_2_j * self_ij)
853 .sum()
854 })
855 .collect()
856 }
857}
858
859impl<const D: usize, const I: usize, const J: usize, const K: usize> Mul<&TensorRank2<D, J, K>>
860 for TensorRank2<D, I, J>
861{
862 type Output = TensorRank2<D, I, K>;
863 fn mul(self, tensor_rank_2: &TensorRank2<D, J, K>) -> Self::Output {
864 self.into_iter()
865 .map(|self_i| {
866 self_i
867 .into_iter()
868 .zip(tensor_rank_2.iter())
869 .map(|(self_ij, tensor_rank_2_j)| tensor_rank_2_j * self_ij)
870 .sum()
871 })
872 .collect()
873 }
874}
875
876impl<const D: usize, const I: usize, const J: usize, const K: usize> Mul<TensorRank2<D, J, K>>
877 for &TensorRank2<D, I, J>
878{
879 type Output = TensorRank2<D, I, K>;
880 fn mul(self, tensor_rank_2: TensorRank2<D, J, K>) -> Self::Output {
881 self.iter()
882 .map(|self_i| {
883 self_i
884 .iter()
885 .zip(tensor_rank_2.iter())
886 .map(|(self_ij, tensor_rank_2_j)| tensor_rank_2_j * self_ij)
887 .sum()
888 })
889 .collect()
890 }
891}
892
893impl<const D: usize, const I: usize, const J: usize, const K: usize> Mul<&TensorRank2<D, J, K>>
894 for &TensorRank2<D, I, J>
895{
896 type Output = TensorRank2<D, I, K>;
897 fn mul(self, tensor_rank_2: &TensorRank2<D, J, K>) -> Self::Output {
898 self.iter()
899 .map(|self_i| {
900 self_i
901 .iter()
902 .zip(tensor_rank_2.iter())
903 .map(|(self_ij, tensor_rank_2_j)| tensor_rank_2_j * self_ij)
904 .sum()
905 })
906 .collect()
907 }
908}
909
910impl<const D: usize, const I: usize, const J: usize> MulAssign<TensorRank2<D, J, J>>
911 for TensorRank2<D, I, J>
912{
913 fn mul_assign(&mut self, tensor_rank_2: TensorRank2<D, J, J>) {
914 *self = &*self * tensor_rank_2
915 }
916}
917
918impl<const D: usize, const I: usize, const J: usize> MulAssign<&TensorRank2<D, J, J>>
919 for TensorRank2<D, I, J>
920{
921 fn mul_assign(&mut self, tensor_rank_2: &TensorRank2<D, J, J>) {
922 *self = &*self * tensor_rank_2
923 }
924}
925
926impl<const D: usize, const I: usize, const J: usize> Sub for TensorRank2<D, I, J> {
927 type Output = Self;
928 fn sub(mut self, tensor_rank_2: Self) -> Self::Output {
929 self -= tensor_rank_2;
930 self
931 }
932}
933
934impl<const D: usize, const I: usize, const J: usize> Sub<&Self> for TensorRank2<D, I, J> {
935 type Output = Self;
936 fn sub(mut self, tensor_rank_2: &Self) -> Self::Output {
937 self -= tensor_rank_2;
938 self
939 }
940}
941
942impl<const D: usize, const I: usize, const J: usize> Sub<TensorRank2<D, I, J>>
943 for &TensorRank2<D, I, J>
944{
945 type Output = TensorRank2<D, I, J>;
946 fn sub(self, tensor_rank_2: TensorRank2<D, I, J>) -> Self::Output {
947 let mut output = self.clone();
948 output -= tensor_rank_2;
949 output
950 }
951}
952
953impl<const D: usize, const I: usize, const J: usize> Sub for &TensorRank2<D, I, J> {
954 type Output = TensorRank2<D, I, J>;
955 fn sub(self, tensor_rank_2: Self) -> Self::Output {
956 let mut output = self.clone();
957 output -= tensor_rank_2;
958 output
959 }
960}
961
962impl<const D: usize, const I: usize, const J: usize> SubAssign for TensorRank2<D, I, J> {
963 fn sub_assign(&mut self, tensor_rank_2: Self) {
964 self.iter_mut()
965 .zip(tensor_rank_2)
966 .for_each(|(self_i, tensor_rank_2_i)| *self_i -= tensor_rank_2_i);
967 }
968}
969
970impl<const D: usize, const I: usize, const J: usize> SubAssign<&Self> for TensorRank2<D, I, J> {
971 fn sub_assign(&mut self, tensor_rank_2: &Self) {
972 self.iter_mut()
973 .zip(tensor_rank_2.iter())
974 .for_each(|(self_i, tensor_rank_2_i)| *self_i -= tensor_rank_2_i);
975 }
976}
977
978impl<const D: usize, const I: usize, const J: usize, const W: usize> Mul<TensorRank1List<D, J, W>>
979 for TensorRank2<D, I, J>
980{
981 type Output = TensorRank1List<D, I, W>;
982 fn mul(self, tensor_rank_1_list: TensorRank1List<D, J, W>) -> Self::Output {
983 tensor_rank_1_list
984 .into_iter()
985 .map(|tensor_rank_1| &self * tensor_rank_1)
986 .collect()
987 }
988}
989
990impl<const D: usize, const I: usize, const J: usize, const W: usize> Mul<&TensorRank1List<D, J, W>>
991 for TensorRank2<D, I, J>
992{
993 type Output = TensorRank1List<D, I, W>;
994 fn mul(self, tensor_rank_1_list: &TensorRank1List<D, J, W>) -> Self::Output {
995 tensor_rank_1_list
996 .iter()
997 .map(|tensor_rank_1| &self * tensor_rank_1)
998 .collect()
999 }
1000}
1001
1002impl<const D: usize, const I: usize, const J: usize, const W: usize> Mul<TensorRank1List<D, J, W>>
1003 for &TensorRank2<D, I, J>
1004{
1005 type Output = TensorRank1List<D, I, W>;
1006 fn mul(self, tensor_rank_1_list: TensorRank1List<D, J, W>) -> Self::Output {
1007 tensor_rank_1_list
1008 .into_iter()
1009 .map(|tensor_rank_1| self * tensor_rank_1)
1010 .collect()
1011 }
1012}
1013
1014impl<const D: usize, const I: usize, const J: usize, const W: usize> Mul<&TensorRank1List<D, J, W>>
1015 for &TensorRank2<D, I, J>
1016{
1017 type Output = TensorRank1List<D, I, W>;
1018 fn mul(self, tensor_rank_1_list: &TensorRank1List<D, J, W>) -> Self::Output {
1019 tensor_rank_1_list
1020 .iter()
1021 .map(|tensor_rank_1| self * tensor_rank_1)
1022 .collect()
1023 }
1024}
1025
1026impl<const D: usize, const I: usize, const J: usize> Mul<TensorRank1Vec<D, J>>
1027 for TensorRank2<D, I, J>
1028{
1029 type Output = TensorRank1Vec<D, I>;
1030 fn mul(self, tensor_rank_1_vec: TensorRank1Vec<D, J>) -> Self::Output {
1031 tensor_rank_1_vec
1032 .into_iter()
1033 .map(|tensor_rank_1| &self * tensor_rank_1)
1034 .collect()
1035 }
1036}
1037
1038impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank1Vec<D, J>>
1039 for TensorRank2<D, I, J>
1040{
1041 type Output = TensorRank1Vec<D, I>;
1042 fn mul(self, tensor_rank_1_vec: &TensorRank1Vec<D, J>) -> Self::Output {
1043 tensor_rank_1_vec
1044 .iter()
1045 .map(|tensor_rank_1| &self * tensor_rank_1)
1046 .collect()
1047 }
1048}
1049
1050impl<const D: usize, const I: usize, const J: usize> Mul<TensorRank1Vec<D, J>>
1051 for &TensorRank2<D, I, J>
1052{
1053 type Output = TensorRank1Vec<D, I>;
1054 fn mul(self, tensor_rank_1_vec: TensorRank1Vec<D, J>) -> Self::Output {
1055 tensor_rank_1_vec
1056 .into_iter()
1057 .map(|tensor_rank_1| self * tensor_rank_1)
1058 .collect()
1059 }
1060}
1061
1062impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank1Vec<D, J>>
1063 for &TensorRank2<D, I, J>
1064{
1065 type Output = TensorRank1Vec<D, I>;
1066 fn mul(self, tensor_rank_1_vec: &TensorRank1Vec<D, J>) -> Self::Output {
1067 tensor_rank_1_vec
1068 .iter()
1069 .map(|tensor_rank_1| self * tensor_rank_1)
1070 .collect()
1071 }
1072}
1073
1074impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
1075 Mul<TensorRank2List2D<D, J, K, W, X>> for TensorRank2<D, I, J>
1076{
1077 type Output = TensorRank2List2D<D, I, K, W, X>;
1078 fn mul(self, tensor_rank_2_list_2d: TensorRank2List2D<D, J, K, W, X>) -> Self::Output {
1079 tensor_rank_2_list_2d
1080 .into_iter()
1081 .map(|tensor_rank_2_list_2d_entry| {
1082 tensor_rank_2_list_2d_entry
1083 .into_iter()
1084 .map(|tensor_rank_2| &self * tensor_rank_2)
1085 .collect()
1086 })
1087 .collect()
1088 }
1089}
1090
1091impl<const D: usize, const I: usize, const J: usize, const K: usize, const W: usize, const X: usize>
1092 Mul<TensorRank2List2D<D, J, K, W, X>> for &TensorRank2<D, I, J>
1093{
1094 type Output = TensorRank2List2D<D, I, K, W, X>;
1095 fn mul(self, tensor_rank_2_list_2d: TensorRank2List2D<D, J, K, W, X>) -> Self::Output {
1096 tensor_rank_2_list_2d
1097 .into_iter()
1098 .map(|tensor_rank_2_list_2d_entry| {
1099 tensor_rank_2_list_2d_entry
1100 .into_iter()
1101 .map(|tensor_rank_2| self * tensor_rank_2)
1102 .collect()
1103 })
1104 .collect()
1105 }
1106}
1107
1108impl<const D: usize, const I: usize, const J: usize, const K: usize> Mul<TensorRank2Vec2D<D, J, K>>
1109 for TensorRank2<D, I, J>
1110{
1111 type Output = TensorRank2Vec2D<D, I, K>;
1112 fn mul(self, tensor_rank_2_list_2d: TensorRank2Vec2D<D, J, K>) -> Self::Output {
1113 tensor_rank_2_list_2d
1114 .into_iter()
1115 .map(|tensor_rank_2_list_2d_entry| {
1116 tensor_rank_2_list_2d_entry
1117 .into_iter()
1118 .map(|tensor_rank_2| &self * tensor_rank_2)
1119 .collect()
1120 })
1121 .collect()
1122 }
1123}
1124
1125impl<const D: usize, const I: usize, const J: usize, const K: usize> Mul<TensorRank2Vec2D<D, J, K>>
1126 for &TensorRank2<D, I, J>
1127{
1128 type Output = TensorRank2Vec2D<D, I, K>;
1129 fn mul(self, tensor_rank_2_list_2d: TensorRank2Vec2D<D, J, K>) -> Self::Output {
1130 tensor_rank_2_list_2d
1131 .into_iter()
1132 .map(|tensor_rank_2_list_2d_entry| {
1133 tensor_rank_2_list_2d_entry
1134 .into_iter()
1135 .map(|tensor_rank_2| self * tensor_rank_2)
1136 .collect()
1137 })
1138 .collect()
1139 }
1140}
1141
1142#[allow(clippy::suspicious_arithmetic_impl)]
1143impl<const I: usize, const J: usize, const K: usize, const L: usize> Div<TensorRank4<3, I, J, K, L>>
1144 for &TensorRank2<3, I, J>
1145{
1146 type Output = TensorRank2<3, K, L>;
1147 fn div(self, tensor_rank_4: TensorRank4<3, I, J, K, L>) -> Self::Output {
1148 let tensor_rank_2: TensorRank2<9, 88, 99> = tensor_rank_4.into();
1149 let output_tensor_rank_1 = tensor_rank_2.inverse() * self.as_tensor_rank_1();
1150 let mut output = TensorRank2::zero();
1151 output.iter_mut().enumerate().for_each(|(i, output_i)| {
1152 output_i
1153 .iter_mut()
1154 .enumerate()
1155 .for_each(|(j, output_ij)| *output_ij = output_tensor_rank_1[3 * i + j])
1156 });
1157 output
1158 }
1159}