1pub mod list;
2pub mod vec;
3
4use crate::math::{
5 Hessian, Jacobian, Solution, SquareMatrix, Tensor, TensorRank0, TensorRank2, TensorRank4,
6 Vector,
7};
8use std::{
9 fmt::{Display, Formatter, Result},
10 iter::Sum,
11 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign},
12};
13
14#[derive(Clone, Debug)]
15pub struct TensorTuple<T1, T2>(T1, T2)
16where
17 T1: Tensor,
18 T2: Tensor;
19
20impl<T1, T2> Default for TensorTuple<T1, T2>
21where
22 T1: Tensor,
23 T2: Tensor,
24{
25 fn default() -> Self {
26 Self(T1::default(), T2::default())
27 }
28}
29
30impl<T1, T2> From<(T1, T2)> for TensorTuple<T1, T2>
31where
32 T1: Tensor,
33 T2: Tensor,
34{
35 fn from(tuple: (T1, T2)) -> Self {
36 Self(tuple.0, tuple.1)
37 }
38}
39
40impl<'a, T1, T2> From<&'a TensorTuple<T1, T2>> for (&'a T1, &'a T2)
41where
42 T1: Tensor,
43 T2: Tensor,
44{
45 fn from(tensor_tuple: &'a TensorTuple<T1, T2>) -> Self {
46 (&tensor_tuple.0, &tensor_tuple.1)
47 }
48}
49
50impl<T1, T2> From<TensorTuple<T1, T2>> for (T1, T2)
51where
52 T1: Tensor,
53 T2: Tensor,
54{
55 fn from(tensor_tuple: TensorTuple<T1, T2>) -> Self {
56 (tensor_tuple.0, tensor_tuple.1)
57 }
58}
59
60impl<T1, T2> From<Vector> for TensorTuple<T1, T2>
61where
62 T1: Tensor,
63 T2: Tensor,
64{
65 fn from(_vector: Vector) -> Self {
66 unimplemented!()
67 }
68}
69
70impl<T1, T2> Display for TensorTuple<T1, T2>
71where
72 T1: Tensor,
73 T2: Tensor,
74{
75 fn fmt(&self, f: &mut Formatter) -> Result {
76 write!(f, "Need to implement Display")
77 }
78}
79
80impl<T1, T2> Tensor for TensorTuple<T1, T2>
81where
82 T1: Tensor,
83 T2: Tensor,
84{
85 type Item = T1::Item;
86 fn full_contraction(&self, tensor_tuple: &Self) -> TensorRank0 {
87 self.0.full_contraction(&tensor_tuple.0) + self.1.full_contraction(&tensor_tuple.1)
88 }
89 fn iter(&self) -> impl Iterator<Item = &Self::Item> {
90 if self.size() == 0 {
91 self.0.iter()
92 } else {
93 unimplemented!()
94 }
95 }
96 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
97 if self.size() == 0 {
98 self.0.iter_mut()
99 } else {
100 unimplemented!()
101 }
102 }
103 fn len(&self) -> usize {
104 unimplemented!()
105 }
106 fn norm_inf(&self) -> TensorRank0 {
107 self.0.norm_inf().max(self.1.norm_inf())
108 }
109 fn size(&self) -> usize {
110 self.0.size() + self.1.size()
111 }
112}
113
114impl<const D: usize, const I: usize, const J: usize, const K: usize, const L: usize> Hessian
115 for TensorTuple<
116 TensorRank4<D, I, J, I, J>,
117 TensorTuple<
118 TensorRank4<D, K, L, I, J>,
119 TensorTuple<TensorRank4<D, I, J, K, L>, TensorRank4<D, K, L, K, L>>,
120 >,
121 >
122{
123 fn fill_into(self, square_matrix: &mut SquareMatrix) {
124 let offset = D * D;
125 let (tangent_0, tangent_123) = self.into();
126 let (tangent_1, tangent_23) = tangent_123.into();
127 let (tangent_2, tangent_3) = tangent_23.into();
128
129 tangent_0.into_iter().zip(tangent_1.into_iter().zip(tangent_2.into_iter().zip(tangent_3))).enumerate()
130 .for_each(|(i, (tangent_0_i, (tangent_1_i, (tangent_2_i, tangent_3_i))))| {
131 tangent_0_i.into_iter().zip(tangent_1_i.into_iter().zip(tangent_2_i.into_iter().zip(tangent_3_i))).enumerate()
132 .for_each(|(j, (tangent_0_ij, (tangent_1_ij, (tangent_2_ij, tangent_3_ij))))| {
133 tangent_0_ij.into_iter().zip(tangent_1_ij.into_iter().zip(tangent_2_ij.into_iter().zip(tangent_3_ij))).enumerate()
134 .for_each(|(k, (tangent_0_ijk, (tangent_1_ijk, (tangent_2_ijk, tangent_3_ijk))))| {
135 tangent_0_ijk.into_iter().zip(tangent_1_ijk.into_iter().zip(tangent_2_ijk.into_iter().zip(tangent_3_ijk))).enumerate()
136 .for_each(|(l, (tangent_0_ijkl, (tangent_1_ijkl, (tangent_2_ijkl, tangent_3_ijkl))))| {
137 square_matrix[D * i + j][D * k + l] = tangent_0_ijkl;
138 square_matrix[offset + D * i + j][D * k + l] = tangent_1_ijkl;
139 square_matrix[D * i + j][offset + D * k + l] = tangent_2_ijkl;
140 square_matrix[offset + D * i + j][offset + D * k + l] = tangent_3_ijkl;
141 })
142 })
143 })
144 })
145 }
146}
147
148impl<const D: usize, const I: usize, const J: usize, const K: usize, const L: usize> Jacobian
149 for TensorTuple<TensorRank2<D, I, J>, TensorRank2<D, K, L>>
150{
151 fn fill_into(self, vector: &mut Vector) {
152 self.0
153 .into_iter()
154 .flatten()
155 .chain(self.1.into_iter().flatten())
156 .zip(vector.iter_mut())
157 .for_each(|(self_i, vector_i)| *vector_i = self_i)
158 }
159 fn fill_into_chained(self, other: Vector, vector: &mut Vector) {
160 self.0
161 .into_iter()
162 .flatten()
163 .chain(self.1.into_iter().flatten())
164 .chain(other)
165 .zip(vector.iter_mut())
166 .for_each(|(self_i, vector_i)| *vector_i = self_i)
167 }
168}
169
170impl<const D: usize, const I: usize, const J: usize, const K: usize, const L: usize> Solution
171 for TensorTuple<TensorRank2<D, I, J>, TensorRank2<D, K, L>>
172{
173 fn decrement_from(&mut self, other: &Vector) {
174 self.0
175 .iter_mut()
176 .flat_map(|x| x.iter_mut())
177 .chain(self.1.iter_mut().flat_map(|x| x.iter_mut()))
178 .zip(other.iter())
179 .for_each(|(self_i, vector_i)| *self_i -= vector_i)
180 }
181 fn decrement_from_chained(&mut self, other: &mut Vector, vector: Vector) {
182 self.0
183 .iter_mut()
184 .flat_map(|x| x.iter_mut())
185 .chain(self.1.iter_mut().flat_map(|x| x.iter_mut()))
186 .chain(other.iter_mut())
187 .zip(vector)
188 .for_each(|(entry_i, vector_i)| *entry_i -= vector_i)
189 }
190}
191
192impl<T1, T2> Sum for TensorTuple<T1, T2>
193where
194 T1: Tensor,
195 T2: Tensor,
196{
197 fn sum<Ii>(iter: Ii) -> Self
198 where
199 Ii: Iterator<Item = Self>,
200 {
201 iter.reduce(|mut acc, item| {
202 acc.0 += item.0;
203 acc.1 += item.1;
204 acc
205 })
206 .unwrap_or_else(Self::default)
207 }
208}
209
210impl<T1, T2> Div<TensorRank0> for TensorTuple<T1, T2>
211where
212 T1: Tensor,
213 T2: Tensor,
214{
215 type Output = Self;
216 fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
217 self /= tensor_rank_0;
218 self
219 }
220}
221
222impl<T1, T2> Div<&TensorRank0> for TensorTuple<T1, T2>
223where
224 T1: Tensor,
225 T2: Tensor,
226{
227 type Output = Self;
228 fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
229 self /= tensor_rank_0;
230 self
231 }
232}
233
234impl<T1, T2> DivAssign<TensorRank0> for TensorTuple<T1, T2>
235where
236 T1: Tensor,
237 T2: Tensor,
238{
239 fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
240 self.0 /= &tensor_rank_0;
241 self.1 /= tensor_rank_0;
242 }
243}
244
245impl<T1, T2> DivAssign<&TensorRank0> for TensorTuple<T1, T2>
246where
247 T1: Tensor,
248 T2: Tensor,
249{
250 fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
251 self.0 /= tensor_rank_0;
252 self.1 /= tensor_rank_0;
253 }
254}
255
256impl<T1, T2> Mul<TensorRank0> for TensorTuple<T1, T2>
257where
258 T1: Tensor,
259 T2: Tensor,
260{
261 type Output = Self;
262 fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
263 self *= tensor_rank_0;
264 self
265 }
266}
267
268impl<T1, T2> Mul<&TensorRank0> for TensorTuple<T1, T2>
269where
270 T1: Tensor,
271 T2: Tensor,
272{
273 type Output = Self;
274 fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
275 self *= tensor_rank_0;
276 self
277 }
278}
279
280impl<T1, T2> Mul<TensorRank0> for &TensorTuple<T1, T2>
281where
282 T1: Tensor,
283 T2: Tensor,
284{
285 type Output = TensorTuple<T1, T2>;
286 fn mul(self, tensor_rank_0: TensorRank0) -> Self::Output {
287 TensorTuple(
291 self.0.clone() * tensor_rank_0,
292 self.1.clone() * tensor_rank_0,
293 )
294 }
295}
296
297impl<T1, T2> MulAssign<TensorRank0> for TensorTuple<T1, T2>
298where
299 T1: Tensor,
300 T2: Tensor,
301{
302 fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
303 self.0 *= &tensor_rank_0;
304 self.1 *= tensor_rank_0;
305 }
306}
307
308impl<T1, T2> MulAssign<&TensorRank0> for TensorTuple<T1, T2>
309where
310 T1: Tensor,
311 T2: Tensor,
312{
313 fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
314 self.0 *= tensor_rank_0;
315 self.1 *= tensor_rank_0;
316 }
317}
318
319impl<T1, T2> Add for TensorTuple<T1, T2>
320where
321 T1: Tensor,
322 T2: Tensor,
323{
324 type Output = Self;
325 fn add(mut self, tensor_tuple: Self) -> Self::Output {
326 self += tensor_tuple;
327 self
328 }
329}
330
331impl<T1, T2> Add<&Self> for TensorTuple<T1, T2>
332where
333 T1: Tensor,
334 T2: Tensor,
335{
336 type Output = Self;
337 fn add(mut self, tensor_tuple: &Self) -> Self::Output {
338 self += tensor_tuple;
339 self
340 }
341}
342
343impl<T1, T2> AddAssign for TensorTuple<T1, T2>
344where
345 T1: Tensor,
346 T2: Tensor,
347{
348 fn add_assign(&mut self, tensor_tuple: Self) {
349 self.0 += tensor_tuple.0;
350 self.1 += tensor_tuple.1;
351 }
352}
353
354impl<T1, T2> AddAssign<&Self> for TensorTuple<T1, T2>
355where
356 T1: Tensor,
357 T2: Tensor,
358{
359 fn add_assign(&mut self, tensor_tuple: &Self) {
360 self.0 += &tensor_tuple.0;
361 self.1 += &tensor_tuple.1;
362 }
363}
364
365impl<T1, T2> Sub for TensorTuple<T1, T2>
366where
367 T1: Tensor,
368 T2: Tensor,
369{
370 type Output = Self;
371 fn sub(mut self, tensor_tuple: Self) -> Self::Output {
372 self -= tensor_tuple;
373 self
374 }
375}
376
377impl<T1, T2> Sub<&Self> for TensorTuple<T1, T2>
378where
379 T1: Tensor,
380 T2: Tensor,
381{
382 type Output = Self;
383 fn sub(mut self, tensor_tuple: &Self) -> Self::Output {
384 self -= tensor_tuple;
385 self
386 }
387}
388
389impl<T1, T2> Sub for &TensorTuple<T1, T2>
390where
391 T1: Tensor,
392 T2: Tensor,
393{
394 type Output = TensorTuple<T1, T2>;
395 fn sub(self, _tensor_tuple: Self) -> Self::Output {
396 unimplemented!("Avoiding trait recursion nightmare")
397 }
398}
399
400impl<T1, T2> SubAssign for TensorTuple<T1, T2>
401where
402 T1: Tensor,
403 T2: Tensor,
404{
405 fn sub_assign(&mut self, tensor_tuple: Self) {
406 self.0 -= tensor_tuple.0;
407 self.1 -= tensor_tuple.1;
408 }
409}
410
411impl<T1, T2> SubAssign<&Self> for TensorTuple<T1, T2>
412where
413 T1: Tensor,
414 T2: Tensor,
415{
416 fn sub_assign(&mut self, tensor_tuple: &Self) {
417 self.0 -= &tensor_tuple.0;
418 self.1 -= &tensor_tuple.1;
419 }
420}
421
422impl<const D: usize, const I: usize, const J: usize, const K: usize, const L: usize> Sub<Vector>
423 for TensorTuple<TensorRank2<D, I, J>, TensorRank2<D, K, L>>
424{
425 type Output = Self;
426 fn sub(mut self, vector: Vector) -> Self::Output {
427 self.0 = self.0 - vector.iter().take(D * D).copied().collect::<Vector>();
428 self.1 = self.1 - vector.iter().skip(D * D).copied().collect::<Vector>();
429 self
430 }
431}
432
433impl<const D: usize, const I: usize, const J: usize, const K: usize, const L: usize> Sub<&Vector>
434 for TensorTuple<TensorRank2<D, I, J>, TensorRank2<D, K, L>>
435{
436 type Output = Self;
437 fn sub(mut self, vector: &Vector) -> Self::Output {
438 self.0 = self.0 - vector.iter().take(D * D).copied().collect::<Vector>();
439 self.1 = self.1 - vector.iter().skip(D * D).copied().collect::<Vector>();
440 self
441 }
442}
443
444impl<T0, T1, T4, T5> Div<TensorTuple<T0, T1>> for &TensorTuple<T4, T5>
445where
446 T0: Tensor,
447 T1: Tensor,
448 T4: Tensor,
449 T5: Tensor,
450{
451 type Output = TensorTuple<T4, T5>;
452 fn div(self, _tensor_tuple: TensorTuple<T0, T1>) -> Self::Output {
453 unimplemented!()
454 }
455}