1#[cfg(test)]
2mod test;
3
4pub(crate) mod list;
5pub(crate) mod vec;
6
7use crate::math::{
8 Differentiable, Erase, Jacobian, Quantity, Scalar, Solution, Tensor, TensorRank0, Vector,
9};
10use crate::units::UnitHalves;
11use std::{
12 fmt::{Display, Formatter, Result},
13 iter::Sum,
14 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign},
15};
16
17#[derive(Clone, Debug, PartialEq)]
19pub struct TensorTuple<T1, T2>(pub T1, pub T2)
20where
21 T1: Tensor,
22 T2: Tensor;
23
24type First<V> = <V as UnitHalves>::First;
25type Second<V> = <V as UnitHalves>::Second;
26
27impl<T1, T2, V> Mul<Quantity<V>> for TensorTuple<T1, T2>
28where
29 V: UnitHalves,
30 T1: Mul<Quantity<First<V>>> + Tensor,
31 T2: Mul<Quantity<Second<V>>> + Tensor,
32 <T1 as Mul<Quantity<First<V>>>>::Output: Tensor,
33 <T2 as Mul<Quantity<Second<V>>>>::Output: Tensor,
34{
35 type Output = TensorTuple<
36 <T1 as Mul<Quantity<First<V>>>>::Output,
37 <T2 as Mul<Quantity<Second<V>>>>::Output,
38 >;
39 fn mul(self, quantity: Quantity<V>) -> Self::Output {
40 let (first, second) = quantity.halves();
41 TensorTuple(self.0 * first, self.1 * second)
42 }
43}
44
45impl<T1, T2, V> Mul<Quantity<V>> for &TensorTuple<T1, T2>
46where
47 V: UnitHalves,
48 T1: Clone + Mul<Quantity<First<V>>> + Tensor,
49 T2: Clone + Mul<Quantity<Second<V>>> + Tensor,
50 <T1 as Mul<Quantity<First<V>>>>::Output: Tensor,
51 <T2 as Mul<Quantity<Second<V>>>>::Output: Tensor,
52{
53 type Output = TensorTuple<
54 <T1 as Mul<Quantity<First<V>>>>::Output,
55 <T2 as Mul<Quantity<Second<V>>>>::Output,
56 >;
57 fn mul(self, quantity: Quantity<V>) -> Self::Output {
58 let (first, second) = quantity.halves();
59 TensorTuple(self.0.clone() * first, self.1.clone() * second)
60 }
61}
62
63impl<T1, T2, V> Div<Quantity<V>> for TensorTuple<T1, T2>
64where
65 V: UnitHalves,
66 T1: Div<Quantity<First<V>>> + Tensor,
67 T2: Div<Quantity<Second<V>>> + Tensor,
68 <T1 as Div<Quantity<First<V>>>>::Output: Tensor,
69 <T2 as Div<Quantity<Second<V>>>>::Output: Tensor,
70{
71 type Output = TensorTuple<
72 <T1 as Div<Quantity<First<V>>>>::Output,
73 <T2 as Div<Quantity<Second<V>>>>::Output,
74 >;
75 fn div(self, quantity: Quantity<V>) -> Self::Output {
76 let (first, second) = quantity.halves();
77 TensorTuple(self.0 / first, self.1 / second)
78 }
79}
80
81impl<T1, T2> Erase for TensorTuple<T1, T2>
82where
83 T1: Erase + Tensor,
84 T2: Erase + Tensor,
85 <T1 as Erase>::Erased: Tensor,
86 <T2 as Erase>::Erased: Tensor,
87{
88 type Erased = TensorTuple<<T1 as Erase>::Erased, <T2 as Erase>::Erased>;
89 fn erase(&self) -> &Self::Erased {
90 unsafe { &*(self as *const Self as *const Self::Erased) }
91 }
92}
93
94impl<T1, T2> Default for TensorTuple<T1, T2>
95where
96 T1: Tensor,
97 T2: Tensor,
98{
99 fn default() -> Self {
100 Self(T1::default(), T2::default())
101 }
102}
103
104impl<T1, T2> From<(T1, T2)> for TensorTuple<T1, T2>
105where
106 T1: Tensor,
107 T2: Tensor,
108{
109 fn from(tuple: (T1, T2)) -> Self {
110 Self(tuple.0, tuple.1)
111 }
112}
113
114impl<'a, T1, T2> From<&'a TensorTuple<T1, T2>> for (&'a T1, &'a T2)
115where
116 T1: Tensor,
117 T2: Tensor,
118{
119 fn from(tensor_tuple: &'a TensorTuple<T1, T2>) -> Self {
120 (&tensor_tuple.0, &tensor_tuple.1)
121 }
122}
123
124impl<T1, T2> From<TensorTuple<T1, T2>> for (T1, T2)
125where
126 T1: Tensor,
127 T2: Tensor,
128{
129 fn from(tensor_tuple: TensorTuple<T1, T2>) -> Self {
130 (tensor_tuple.0, tensor_tuple.1)
131 }
132}
133
134impl<T1, T2> From<Vector> for TensorTuple<T1, T2>
135where
136 T1: Tensor,
137 T2: Tensor,
138{
139 fn from(_vector: Vector) -> Self {
140 unimplemented!()
141 }
142}
143
144impl<T1, T2> Display for TensorTuple<T1, T2>
145where
146 T1: Tensor,
147 T2: Tensor,
148{
149 fn fmt(&self, f: &mut Formatter) -> Result {
150 write!(f, "({}, {})", self.0, self.1)
151 }
152}
153
154impl<T1, T2> Tensor for TensorTuple<T1, T2>
155where
156 T1: Tensor,
157 T2: Tensor,
158{
159 type Item = T1::Item;
160 type Unit = (<T1 as Tensor>::Unit, <T2 as Tensor>::Unit);
161 fn error_count_zero(&self, tol_abs: Scalar, tol_rel: Scalar) -> Option<usize> {
162 let error_count = self.0.error_count_zero(tol_abs, tol_rel).unwrap_or(0)
163 + self.1.error_count_zero(tol_abs, tol_rel).unwrap_or(0);
164 if error_count > 0 {
165 Some(error_count)
166 } else {
167 None
168 }
169 }
170 fn error_count(&self, tensor_tuple: &Self, tol_abs: Scalar, tol_rel: Scalar) -> Option<usize> {
171 let error_count = self
172 .0
173 .error_count(&tensor_tuple.0, tol_abs, tol_rel)
174 .unwrap_or(0)
175 + self
176 .1
177 .error_count(&tensor_tuple.1, tol_abs, tol_rel)
178 .unwrap_or(0);
179 if error_count > 0 {
180 Some(error_count)
181 } else {
182 None
183 }
184 }
185 fn full_contraction(&self, tensor_tuple: &Self) -> TensorRank0 {
186 self.0.full_contraction(&tensor_tuple.0) + self.1.full_contraction(&tensor_tuple.1)
187 }
188 fn is_zero(&self) -> bool {
189 self.0.is_zero() && self.1.is_zero()
190 }
191 fn iter(&self) -> impl Iterator<Item = &Self::Item> {
192 if self.size() == 0 {
193 self.0.iter()
194 } else {
195 unimplemented!()
196 }
197 }
198 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
199 if self.size() == 0 {
200 self.0.iter_mut()
201 } else {
202 unimplemented!()
203 }
204 }
205 fn len(&self) -> usize {
206 unimplemented!()
207 }
208 fn norm_inf(&self) -> Quantity<Self::Unit> {
209 Quantity::new(self.0.norm_inf().value().max(self.1.norm_inf().value()))
210 }
211 fn norm_l1(&self) -> Quantity<Self::Unit> {
212 Quantity::new(self.0.norm_l1().value() + self.1.norm_l1().value())
213 }
214 fn norm_p_sum(&self, p: TensorRank0) -> TensorRank0 {
215 self.0.norm_p_sum(p) + self.1.norm_p_sum(p)
216 }
217 fn size(&self) -> usize {
218 self.0.size() + self.1.size()
219 }
220 fn sub_abs(&self, tensor_tuple: &Self) -> Self {
221 Self(
222 self.0.sub_abs(&tensor_tuple.0),
223 self.1.sub_abs(&tensor_tuple.1),
224 )
225 }
226 fn sub_rel(&self, tensor_tuple: &Self) -> Self {
227 Self(
228 self.0.sub_rel(&tensor_tuple.0),
229 self.1.sub_rel(&tensor_tuple.1),
230 )
231 }
232}
233
234impl<T1, T2> Jacobian for TensorTuple<T1, T2>
235where
236 T1: Jacobian,
237 T2: Jacobian,
238{
239 fn fill_into(&self, vector: &mut Vector) {
240 let mut head = Vector::zero(self.0.size());
241 self.0.fill_into(&mut head);
242 let mut tail = Vector::zero(self.1.size());
243 self.1.fill_into(&mut tail);
244 head.into_iter()
245 .chain(tail)
246 .zip(vector.iter_mut())
247 .for_each(|(entry, vector_i)| *vector_i = entry)
248 }
249 fn fill_into_chained(self, other: Vector, vector: &mut Vector) {
250 let mut head = Vector::zero(self.0.size());
251 self.0.fill_into(&mut head);
252 let mut tail = Vector::zero(self.1.size());
253 self.1.fill_into(&mut tail);
254 head.into_iter()
255 .chain(tail)
256 .chain(other)
257 .zip(vector.iter_mut())
258 .for_each(|(entry, vector_i)| *vector_i = entry)
259 }
260}
261
262impl<T1, T2> Solution for TensorTuple<T1, T2>
263where
264 T1: Solution,
265 T2: Solution,
266{
267 fn decrement_from(&mut self, other: &Vector) {
268 let split = self.0.size();
269 let head: Vector = other.iter().take(split).copied().collect();
270 let tail: Vector = other.iter().skip(split).copied().collect();
271 self.0.decrement_from(&head);
272 self.1.decrement_from(&tail);
273 }
274 fn decrement_from_chained(&mut self, other: &mut Vector, vector: &Vector) {
275 let split = self.0.size();
276 let tail_len = self.1.size();
277 let head: Vector = vector.iter().take(split).copied().collect();
278 let tail: Vector = vector.iter().skip(split).take(tail_len).copied().collect();
279 self.0.decrement_from(&head);
280 self.1.decrement_from(&tail);
281 other
282 .iter_mut()
283 .zip(vector.iter().skip(split + tail_len))
284 .for_each(|(entry_i, vector_i)| *entry_i -= vector_i)
285 }
286}
287
288impl<T1, T2> Sum for TensorTuple<T1, T2>
289where
290 T1: Tensor,
291 T2: Tensor,
292{
293 fn sum<Ii>(iter: Ii) -> Self
294 where
295 Ii: Iterator<Item = Self>,
296 {
297 iter.reduce(|mut acc, item| {
298 acc.0 += item.0;
299 acc.1 += item.1;
300 acc
301 })
302 .unwrap_or_else(Self::default)
303 }
304}
305
306impl<T1, T2> Div<TensorRank0> for TensorTuple<T1, T2>
307where
308 T1: Tensor,
309 T2: Tensor,
310{
311 type Output = Self;
312 fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
313 self /= tensor_rank_0;
314 self
315 }
316}
317
318impl<T1, T2> Div<&TensorRank0> for TensorTuple<T1, T2>
319where
320 T1: Tensor,
321 T2: Tensor,
322{
323 type Output = Self;
324 fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
325 self /= tensor_rank_0;
326 self
327 }
328}
329
330impl<T1, T2> DivAssign<TensorRank0> for TensorTuple<T1, T2>
331where
332 T1: Tensor,
333 T2: Tensor,
334{
335 fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
336 self.0 /= &tensor_rank_0;
337 self.1 /= tensor_rank_0;
338 }
339}
340
341impl<T1, T2> DivAssign<&TensorRank0> for TensorTuple<T1, T2>
342where
343 T1: Tensor,
344 T2: Tensor,
345{
346 fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
347 self.0 /= tensor_rank_0;
348 self.1 /= tensor_rank_0;
349 }
350}
351
352impl<T1, T2> Mul<TensorRank0> for TensorTuple<T1, T2>
353where
354 T1: Tensor,
355 T2: Tensor,
356{
357 type Output = Self;
358 fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
359 self *= tensor_rank_0;
360 self
361 }
362}
363
364impl<T1, T2> Mul<&TensorRank0> for TensorTuple<T1, T2>
365where
366 T1: Tensor,
367 T2: Tensor,
368{
369 type Output = Self;
370 fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
371 self *= tensor_rank_0;
372 self
373 }
374}
375
376impl<T1, T2> Mul<TensorRank0> for &TensorTuple<T1, T2>
377where
378 T1: Tensor,
379 T2: Tensor,
380{
381 type Output = TensorTuple<T1, T2>;
382 fn mul(self, tensor_rank_0: TensorRank0) -> Self::Output {
383 TensorTuple(
387 self.0.clone() * tensor_rank_0,
388 self.1.clone() * tensor_rank_0,
389 )
390 }
391}
392
393impl<T1, T2> MulAssign<TensorRank0> for TensorTuple<T1, T2>
394where
395 T1: Tensor,
396 T2: Tensor,
397{
398 fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
399 self.0 *= &tensor_rank_0;
400 self.1 *= tensor_rank_0;
401 }
402}
403
404impl<T1, T2> MulAssign<&TensorRank0> for TensorTuple<T1, T2>
405where
406 T1: Tensor,
407 T2: Tensor,
408{
409 fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
410 self.0 *= tensor_rank_0;
411 self.1 *= tensor_rank_0;
412 }
413}
414
415impl<T1, T2> Add for TensorTuple<T1, T2>
416where
417 T1: Tensor,
418 T2: Tensor,
419{
420 type Output = Self;
421 fn add(mut self, tensor_tuple: Self) -> Self::Output {
422 self += tensor_tuple;
423 self
424 }
425}
426
427impl<T1, T2> Add<&Self> for TensorTuple<T1, T2>
428where
429 T1: Tensor,
430 T2: Tensor,
431{
432 type Output = Self;
433 fn add(mut self, tensor_tuple: &Self) -> Self::Output {
434 self += tensor_tuple;
435 self
436 }
437}
438
439impl<T1, T2> AddAssign for TensorTuple<T1, T2>
440where
441 T1: Tensor,
442 T2: Tensor,
443{
444 fn add_assign(&mut self, tensor_tuple: Self) {
445 self.0 += tensor_tuple.0;
446 self.1 += tensor_tuple.1;
447 }
448}
449
450impl<T1, T2> AddAssign<&Self> for TensorTuple<T1, T2>
451where
452 T1: Tensor,
453 T2: Tensor,
454{
455 fn add_assign(&mut self, tensor_tuple: &Self) {
456 self.0 += &tensor_tuple.0;
457 self.1 += &tensor_tuple.1;
458 }
459}
460
461impl<T1, T2> Sub for TensorTuple<T1, T2>
462where
463 T1: Tensor,
464 T2: Tensor,
465{
466 type Output = Self;
467 fn sub(mut self, tensor_tuple: Self) -> Self::Output {
468 self -= tensor_tuple;
469 self
470 }
471}
472
473impl<T1, T2> Sub<&Self> for TensorTuple<T1, T2>
474where
475 T1: Tensor,
476 T2: Tensor,
477{
478 type Output = Self;
479 fn sub(mut self, tensor_tuple: &Self) -> Self::Output {
480 self -= tensor_tuple;
481 self
482 }
483}
484
485impl<T1, T2> Sub for &TensorTuple<T1, T2>
486where
487 T1: Tensor,
488 T2: Tensor,
489{
490 type Output = TensorTuple<T1, T2>;
491 fn sub(self, tensor_tuple: Self) -> Self::Output {
492 self.clone() - tensor_tuple
493 }
494}
495
496impl<T1, T2> SubAssign for TensorTuple<T1, T2>
497where
498 T1: Tensor,
499 T2: Tensor,
500{
501 fn sub_assign(&mut self, tensor_tuple: Self) {
502 self.0 -= tensor_tuple.0;
503 self.1 -= tensor_tuple.1;
504 }
505}
506
507impl<T1, T2> SubAssign<&Self> for TensorTuple<T1, T2>
508where
509 T1: Tensor,
510 T2: Tensor,
511{
512 fn sub_assign(&mut self, tensor_tuple: &Self) {
513 self.0 -= &tensor_tuple.0;
514 self.1 -= &tensor_tuple.1;
515 }
516}
517
518impl<T1, T2> Sub<Vector> for TensorTuple<T1, T2>
519where
520 T1: Tensor + Sub<Vector, Output = T1>,
521 T2: Tensor + Sub<Vector, Output = T2>,
522{
523 type Output = Self;
524 fn sub(mut self, vector: Vector) -> Self::Output {
525 let split = self.0.size();
526 self.0 = self.0 - vector.iter().take(split).copied().collect::<Vector>();
527 self.1 = self.1 - vector.iter().skip(split).copied().collect::<Vector>();
528 self
529 }
530}
531
532impl<T1, T2> Sub<&Vector> for TensorTuple<T1, T2>
533where
534 T1: Tensor + Sub<Vector, Output = T1>,
535 T2: Tensor + Sub<Vector, Output = T2>,
536{
537 type Output = Self;
538 fn sub(mut self, vector: &Vector) -> Self::Output {
539 let split = self.0.size();
540 self.0 = self.0 - vector.iter().take(split).copied().collect::<Vector>();
541 self.1 = self.1 - vector.iter().skip(split).copied().collect::<Vector>();
542 self
543 }
544}
545
546impl<T0, T1, T4, T5> Div<TensorTuple<T0, T1>> for &TensorTuple<T4, T5>
547where
548 T0: Tensor,
549 T1: Tensor,
550 T4: Tensor,
551 T5: Tensor,
552{
553 type Output = TensorTuple<T4, T5>;
554 fn div(self, _tensor_tuple: TensorTuple<T0, T1>) -> Self::Output {
555 unimplemented!()
556 }
557}
558
559impl<T1, T2, T> Differentiable<T> for TensorTuple<T1, T2>
560where
561 T1: Differentiable<T> + Tensor,
562 T2: Differentiable<T> + Tensor,
563 <T1 as Differentiable<T>>::Derivative: Tensor,
564 <T2 as Differentiable<T>>::Derivative: Tensor,
565{
566 type Derivative =
567 TensorTuple<<T1 as Differentiable<T>>::Derivative, <T2 as Differentiable<T>>::Derivative>;
568}