conspire/math/tensor/tuple/
mod.rs

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        //
288        // Cloning for now to avoid trait recursion nightmare.
289        //
290        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}