1#[cfg(test)]
2use super::super::test::ErrorTensor;
3
4use crate::math::{
5 Jacobian, Solution, Tensor, TensorArray, TensorRank0, TensorRank1, TensorRank2,
6 TensorRank2Vec2D, TensorVec, Vector, write_tensor_rank_0,
7};
8use std::{
9 fmt::{Display, Formatter, Result},
10 mem::transmute,
11 ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign},
12};
13
14#[derive(Clone, Debug)]
18pub struct TensorRank1Vec<const D: usize, const I: usize>(Vec<TensorRank1<D, I>>);
19
20impl<const D: usize, const I: usize> Display for TensorRank1Vec<D, I> {
21 fn fmt(&self, f: &mut Formatter) -> Result {
22 write!(f, "\x1B[s")?;
23 write!(f, "[[")?;
24 self.iter().enumerate().try_for_each(|(i, tensor_rank_1)| {
25 tensor_rank_1
26 .iter()
27 .try_for_each(|entry| write_tensor_rank_0(f, entry))?;
28 if i + 1 < self.len() {
29 writeln!(f, "\x1B[2D],")?;
30 write!(f, "\x1B[u")?;
31 write!(f, "\x1B[{}B [", i + 1)?;
32 }
33 Ok(())
34 })?;
35 write!(f, "\x1B[2D]]")
36 }
37}
38
39#[cfg(test)]
40impl<const D: usize, const I: usize> ErrorTensor for TensorRank1Vec<D, I> {
41 fn error(
42 &self,
43 comparator: &Self,
44 tol_abs: &TensorRank0,
45 tol_rel: &TensorRank0,
46 ) -> Option<usize> {
47 let error_count = self
48 .iter()
49 .zip(comparator.iter())
50 .map(|(entry, comparator_entry)| {
51 entry
52 .iter()
53 .zip(comparator_entry.iter())
54 .filter(|&(&entry_i, &comparator_entry_i)| {
55 &(entry_i - comparator_entry_i).abs() >= tol_abs
56 && &(entry_i / comparator_entry_i - 1.0).abs() >= tol_rel
57 })
58 .count()
59 })
60 .sum();
61 if error_count > 0 {
62 Some(error_count)
63 } else {
64 None
65 }
66 }
67 fn error_fd(&self, comparator: &Self, epsilon: &TensorRank0) -> Option<(bool, usize)> {
68 let error_count = self
69 .iter()
70 .zip(comparator.iter())
71 .map(|(entry, comparator_entry)| {
72 entry
73 .iter()
74 .zip(comparator_entry.iter())
75 .filter(|&(&entry_i, &comparator_entry_i)| {
76 &(entry_i / comparator_entry_i - 1.0).abs() >= epsilon
77 && (&entry_i.abs() >= epsilon || &comparator_entry_i.abs() >= epsilon)
78 })
79 .count()
80 })
81 .sum();
82 if error_count > 0 {
83 let auxillary = self
84 .iter()
85 .zip(comparator.iter())
86 .map(|(entry, comparator_entry)| {
87 entry
88 .iter()
89 .zip(comparator_entry.iter())
90 .filter(|&(&entry_i, &comparator_entry_i)| {
91 &(entry_i / comparator_entry_i - 1.0).abs() >= epsilon
92 && &(entry_i - comparator_entry_i).abs() >= epsilon
93 && (&entry_i.abs() >= epsilon
94 || &comparator_entry_i.abs() >= epsilon)
95 })
96 .count()
97 })
98 .sum::<usize>()
99 > 0;
100 Some((auxillary, error_count))
101 } else {
102 None
103 }
104 }
105}
106
107impl<const D: usize, const I: usize> From<Vec<[TensorRank0; D]>> for TensorRank1Vec<D, I> {
108 fn from(vec: Vec<[TensorRank0; D]>) -> Self {
109 vec.into_iter()
110 .map(|tensor_rank_1| tensor_rank_1.into())
111 .collect()
112 }
113}
114
115impl<const D: usize, const I: usize> From<Vec<Vec<TensorRank0>>> for TensorRank1Vec<D, I> {
116 fn from(vec: Vec<Vec<TensorRank0>>) -> Self {
117 vec.into_iter()
118 .map(|tensor_rank_1| tensor_rank_1.into())
119 .collect()
120 }
121}
122
123impl<const D: usize, const I: usize> From<TensorRank1Vec<D, I>> for Vec<[TensorRank0; D]> {
124 fn from(tensor_rank_1_vec: TensorRank1Vec<D, I>) -> Self {
125 tensor_rank_1_vec
126 .iter()
127 .map(|tensor_rank_1| tensor_rank_1.clone().into())
128 .collect()
129 }
130}
131
132impl<const D: usize, const I: usize> From<TensorRank1Vec<D, I>> for Vec<Vec<TensorRank0>> {
133 fn from(tensor_rank_1_vec: TensorRank1Vec<D, I>) -> Self {
134 tensor_rank_1_vec
135 .iter()
136 .map(|tensor_rank_1| tensor_rank_1.clone().into())
137 .collect()
138 }
139}
140
141impl From<TensorRank1Vec<3, 0>> for TensorRank1Vec<3, 1> {
142 fn from(tensor_rank_1_vec: TensorRank1Vec<3, 0>) -> Self {
143 unsafe { transmute::<TensorRank1Vec<3, 0>, TensorRank1Vec<3, 1>>(tensor_rank_1_vec) }
144 }
145}
146
147impl From<TensorRank1Vec<3, 1>> for TensorRank1Vec<3, 0> {
148 fn from(tensor_rank_1_vec: TensorRank1Vec<3, 1>) -> Self {
149 unsafe { transmute::<TensorRank1Vec<3, 1>, TensorRank1Vec<3, 0>>(tensor_rank_1_vec) }
150 }
151}
152
153impl<const D: usize, const I: usize> From<Vector> for TensorRank1Vec<D, I> {
154 fn from(vector: Vector) -> Self {
155 let n = vector.len();
156 if n % D != 0 {
157 panic!("Vector length mismatch.")
158 } else {
159 (0..n / D)
160 .map(|a| (0..D).map(|i| vector[D * a + i]).collect())
161 .collect()
162 }
163 }
164}
165
166impl<const D: usize, const I: usize> From<&Vector> for TensorRank1Vec<D, I> {
167 fn from(vector: &Vector) -> Self {
168 let n = vector.len();
169 if n % D != 0 {
170 panic!("Vector length mismatch.")
171 } else {
172 (0..n / D)
173 .map(|a| (0..D).map(|i| vector[D * a + i]).collect())
174 .collect()
175 }
176 }
177}
178
179impl<const D: usize, const I: usize> FromIterator<TensorRank1<D, I>> for TensorRank1Vec<D, I> {
180 fn from_iter<Ii: IntoIterator<Item = TensorRank1<D, I>>>(into_iterator: Ii) -> Self {
181 Self(Vec::from_iter(into_iterator))
182 }
183}
184
185impl<const D: usize, const I: usize> Index<usize> for TensorRank1Vec<D, I> {
186 type Output = TensorRank1<D, I>;
187 fn index(&self, index: usize) -> &Self::Output {
188 &self.0[index]
189 }
190}
191
192impl<const D: usize, const I: usize> IndexMut<usize> for TensorRank1Vec<D, I> {
193 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
194 &mut self.0[index]
195 }
196}
197
198impl<const D: usize, const I: usize> TensorRank1Vec<D, I> {
199 pub fn dot(&self, tensors: &Self) -> TensorRank0 {
201 self.iter()
202 .zip(tensors.iter())
203 .map(|(entry, tensor)| entry * tensor)
204 .sum()
205 }
206}
207
208impl<const D: usize, const I: usize> TensorVec for TensorRank1Vec<D, I> {
209 type Item = TensorRank1<D, I>;
210 type Slice<'a> = &'a [[TensorRank0; D]];
211 fn append(&mut self, other: &mut Self) {
212 self.0.append(&mut other.0)
213 }
214 fn is_empty(&self) -> bool {
215 self.0.is_empty()
216 }
217 fn len(&self) -> usize {
218 self.0.len()
219 }
220 fn new(slice: Self::Slice<'_>) -> Self {
221 slice
222 .iter()
223 .map(|slice_entry| Self::Item::new(*slice_entry))
224 .collect()
225 }
226 fn push(&mut self, item: Self::Item) {
227 self.0.push(item)
228 }
229 fn zero(len: usize) -> Self {
230 (0..len).map(|_| super::zero()).collect()
231 }
232}
233
234impl<const D: usize, const I: usize> Tensor for TensorRank1Vec<D, I> {
235 type Item = TensorRank1<D, I>;
236 fn iter(&self) -> impl Iterator<Item = &Self::Item> {
237 self.0.iter()
238 }
239 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
240 self.0.iter_mut()
241 }
242 fn norm_inf(&self) -> TensorRank0 {
243 self.iter()
244 .map(|tensor_rank_1| {
245 tensor_rank_1
246 .iter()
247 .fold(0.0, |acc, entry| entry.abs().max(acc))
248 })
249 .reduce(TensorRank0::max)
250 .unwrap()
251 }
252 fn num_entries(&self) -> usize {
253 D * self.len()
254 }
255}
256
257impl<const D: usize, const I: usize> IntoIterator for TensorRank1Vec<D, I> {
258 type Item = TensorRank1<D, I>;
259 type IntoIter = std::vec::IntoIter<Self::Item>;
260 fn into_iter(self) -> Self::IntoIter {
261 self.0.into_iter()
262 }
263}
264
265impl<const D: usize, const I: usize> Solution for TensorRank1Vec<D, I> {
266 fn decrement_from_chained(&mut self, other: &mut Vector, vector: Vector) {
267 self.iter_mut()
268 .flat_map(|x| x.iter_mut())
269 .chain(other.iter_mut())
270 .zip(vector)
271 .for_each(|(entry_i, vector_i)| *entry_i -= vector_i)
272 }
273}
274
275impl<const D: usize, const I: usize> Jacobian for TensorRank1Vec<D, I> {
276 fn fill_into(self, vector: &mut Vector) {
277 self.into_iter()
278 .flatten()
279 .zip(vector.iter_mut())
280 .for_each(|(self_i, vector_i)| *vector_i = self_i)
281 }
282 fn fill_into_chained(self, other: Vector, vector: &mut Vector) {
283 self.into_iter()
284 .flatten()
285 .chain(other)
286 .zip(vector.iter_mut())
287 .for_each(|(self_i, vector_i)| *vector_i = self_i)
288 }
289}
290
291impl<const D: usize, const I: usize, const J: usize> Div<TensorRank2Vec2D<D, I, J>>
292 for TensorRank1Vec<D, I>
293{
294 type Output = Self;
295 fn div(self, _tensor_rank_2_vec_2d: TensorRank2Vec2D<D, I, J>) -> Self::Output {
296 todo!()
297 }
298}
299
300impl<const D: usize, const I: usize> Sub<Vector> for TensorRank1Vec<D, I> {
301 type Output = Self;
302 fn sub(mut self, vector: Vector) -> Self::Output {
303 self.iter_mut().enumerate().for_each(|(a, self_a)| {
304 self_a
305 .iter_mut()
306 .enumerate()
307 .for_each(|(i, self_a_i)| *self_a_i -= vector[D * a + i])
308 });
309 self
310 }
311}
312
313impl<const D: usize, const I: usize> Div<TensorRank0> for TensorRank1Vec<D, I> {
314 type Output = Self;
315 fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
316 self /= &tensor_rank_0;
317 self
318 }
319}
320
321impl<const D: usize, const I: usize> Div<&TensorRank0> for TensorRank1Vec<D, I> {
322 type Output = Self;
323 fn div(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> DivAssign<TensorRank0> for TensorRank1Vec<D, I> {
330 fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
331 self.iter_mut().for_each(|entry| *entry /= &tensor_rank_0);
332 }
333}
334
335impl<const D: usize, const I: usize> DivAssign<&TensorRank0> for TensorRank1Vec<D, I> {
336 fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
337 self.iter_mut().for_each(|entry| *entry /= tensor_rank_0);
338 }
339}
340
341impl<const D: usize, const I: usize> Mul<TensorRank0> for TensorRank1Vec<D, I> {
342 type Output = Self;
343 fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
344 self *= &tensor_rank_0;
345 self
346 }
347}
348
349impl<const D: usize, const I: usize> Mul<&TensorRank0> for TensorRank1Vec<D, I> {
350 type Output = Self;
351 fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
352 self *= tensor_rank_0;
353 self
354 }
355}
356
357impl<const D: usize, const I: usize> Mul<TensorRank0> for &TensorRank1Vec<D, I> {
358 type Output = TensorRank1Vec<D, I>;
359 fn mul(self, tensor_rank_0: TensorRank0) -> Self::Output {
360 self.iter().map(|self_i| self_i * tensor_rank_0).collect()
361 }
362}
363
364impl<const D: usize, const I: usize> Mul<&TensorRank0> for &TensorRank1Vec<D, I> {
365 type Output = TensorRank1Vec<D, I>;
366 fn mul(self, tensor_rank_0: &TensorRank0) -> Self::Output {
367 self.iter().map(|self_i| self_i * tensor_rank_0).collect()
368 }
369}
370
371impl<const D: usize, const I: usize> MulAssign<TensorRank0> for TensorRank1Vec<D, I> {
372 fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
373 self.iter_mut().for_each(|entry| *entry *= &tensor_rank_0);
374 }
375}
376
377impl<const D: usize, const I: usize> MulAssign<&TensorRank0> for TensorRank1Vec<D, I> {
378 fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
379 self.iter_mut().for_each(|entry| *entry *= tensor_rank_0);
380 }
381}
382
383impl<const D: usize, const I: usize> Add for TensorRank1Vec<D, I> {
384 type Output = Self;
385 fn add(mut self, tensor_rank_1_vec: Self) -> Self::Output {
386 self += tensor_rank_1_vec;
387 self
388 }
389}
390
391impl<const D: usize, const I: usize> Add<&Self> for TensorRank1Vec<D, I> {
392 type Output = Self;
393 fn add(mut self, tensor_rank_1_vec: &Self) -> Self::Output {
394 self += tensor_rank_1_vec;
395 self
396 }
397}
398
399impl<const D: usize, const I: usize> AddAssign for TensorRank1Vec<D, I> {
400 fn add_assign(&mut self, tensor_rank_1_vec: Self) {
401 self.iter_mut()
402 .zip(tensor_rank_1_vec.iter())
403 .for_each(|(self_entry, tensor_rank_1)| *self_entry += tensor_rank_1);
404 }
405}
406
407impl<const D: usize, const I: usize> AddAssign<&Self> for TensorRank1Vec<D, I> {
408 fn add_assign(&mut self, tensor_rank_1_vec: &Self) {
409 self.iter_mut()
410 .zip(tensor_rank_1_vec.iter())
411 .for_each(|(self_entry, tensor_rank_1)| *self_entry += tensor_rank_1);
412 }
413}
414
415impl<const D: usize, const I: usize, const J: usize> Mul<TensorRank1Vec<D, J>>
416 for TensorRank1Vec<D, I>
417{
418 type Output = TensorRank2<D, I, J>;
419 fn mul(self, tensor_rank_1_vec: TensorRank1Vec<D, J>) -> Self::Output {
420 self.iter()
421 .zip(tensor_rank_1_vec.iter())
422 .map(|(self_entry, tensor_rank_1_vec_entry)| {
423 TensorRank2::dyad(self_entry, tensor_rank_1_vec_entry)
424 })
425 .sum()
426 }
427}
428
429impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank1Vec<D, J>>
430 for TensorRank1Vec<D, I>
431{
432 type Output = TensorRank2<D, I, J>;
433 fn mul(self, tensor_rank_1_vec: &TensorRank1Vec<D, J>) -> Self::Output {
434 self.iter()
435 .zip(tensor_rank_1_vec.iter())
436 .map(|(self_entry, tensor_rank_1_vec_entry)| {
437 TensorRank2::dyad(self_entry, tensor_rank_1_vec_entry)
438 })
439 .sum()
440 }
441}
442
443impl<const D: usize, const I: usize, const J: usize> Mul<TensorRank1Vec<D, J>>
444 for &TensorRank1Vec<D, I>
445{
446 type Output = TensorRank2<D, I, J>;
447 fn mul(self, tensor_rank_1_vec: TensorRank1Vec<D, J>) -> Self::Output {
448 self.iter()
449 .zip(tensor_rank_1_vec.iter())
450 .map(|(self_entry, tensor_rank_1_vec_entry)| {
451 TensorRank2::dyad(self_entry, tensor_rank_1_vec_entry)
452 })
453 .sum()
454 }
455}
456
457impl<const D: usize, const I: usize, const J: usize> Mul<&TensorRank1Vec<D, J>>
458 for &TensorRank1Vec<D, I>
459{
460 type Output = TensorRank2<D, I, J>;
461 fn mul(self, tensor_rank_1_vec: &TensorRank1Vec<D, J>) -> Self::Output {
462 self.iter()
463 .zip(tensor_rank_1_vec.iter())
464 .map(|(self_entry, tensor_rank_1_vec_entry)| {
465 TensorRank2::dyad(self_entry, tensor_rank_1_vec_entry)
466 })
467 .sum()
468 }
469}
470
471impl<const D: usize, const I: usize> Sub for TensorRank1Vec<D, I> {
472 type Output = Self;
473 fn sub(mut self, tensor_rank_1_vec: Self) -> Self::Output {
474 self -= tensor_rank_1_vec;
475 self
476 }
477}
478
479impl<const D: usize, const I: usize> Sub<&Self> for TensorRank1Vec<D, I> {
480 type Output = Self;
481 fn sub(mut self, tensor_rank_1_vec: &Self) -> Self::Output {
482 self -= tensor_rank_1_vec;
483 self
484 }
485}
486
487impl<const D: usize, const I: usize> Sub for &TensorRank1Vec<D, I> {
488 type Output = TensorRank1Vec<D, I>;
489 fn sub(self, tensor_rank_1_vec: Self) -> Self::Output {
490 tensor_rank_1_vec
491 .iter()
492 .zip(self.iter())
493 .map(|(tensor_rank_1_vec_a, self_a)| {
494 tensor_rank_1_vec_a
495 .iter()
496 .zip(self_a.iter())
497 .map(|(tensor_rank_1_vec_a_i, self_a_i)| self_a_i - *tensor_rank_1_vec_a_i)
498 .collect()
499 })
500 .collect()
501 }
502}
503
504impl<const D: usize, const I: usize> SubAssign for TensorRank1Vec<D, I> {
505 fn sub_assign(&mut self, tensor_rank_1_vec: Self) {
506 self.iter_mut()
507 .zip(tensor_rank_1_vec.iter())
508 .for_each(|(self_entry, tensor_rank_1)| *self_entry -= tensor_rank_1);
509 }
510}
511
512impl<const D: usize, const I: usize> SubAssign<&Self> for TensorRank1Vec<D, I> {
513 fn sub_assign(&mut self, tensor_rank_1_vec: &Self) {
514 self.iter_mut()
515 .zip(tensor_rank_1_vec.iter())
516 .for_each(|(self_entry, tensor_rank_1)| *self_entry -= tensor_rank_1);
517 }
518}