1#[cfg(test)]
2mod test;
3
4pub mod list;
5pub mod list_2d;
6pub mod vec;
7pub mod vec_2d;
8
9use std::{
10 fmt::{Display, Formatter, Result},
11 mem::transmute,
12 ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign},
13};
14
15use super::{
16 super::write_tensor_rank_0, Jacobian, Solution, Tensor, TensorArray, Vector,
17 rank_0::TensorRank0, rank_2::TensorRank2, test::ErrorTensor,
18};
19
20#[derive(Clone, Debug, PartialEq)]
24pub struct TensorRank1<const D: usize, const I: usize>([TensorRank0; D]);
25
26pub const fn tensor_rank_1<const D: usize, const I: usize>(
27 array: [TensorRank0; D],
28) -> TensorRank1<D, I> {
29 TensorRank1(array)
30}
31
32impl<const D: usize, const I: usize> Display for TensorRank1<D, I> {
33 fn fmt(&self, f: &mut Formatter) -> Result {
34 write!(f, "[")?;
35 self.iter()
36 .try_for_each(|entry| write_tensor_rank_0(f, entry))?;
37 write!(f, "\x1B[2D]")
38 }
39}
40
41impl<const D: usize, const I: usize> TensorRank1<D, I> {
42 pub fn cross(&self, tensor_rank_1: &Self) -> Self {
44 if D == 3 {
45 let mut output = zero();
46 output[0] = self[1] * tensor_rank_1[2] - self[2] * tensor_rank_1[1];
47 output[1] = self[2] * tensor_rank_1[0] - self[0] * tensor_rank_1[2];
48 output[2] = self[0] * tensor_rank_1[1] - self[1] * tensor_rank_1[0];
49 output
50 } else {
51 panic!()
52 }
53 }
54}
55
56impl<const D: usize, const I: usize> ErrorTensor for TensorRank1<D, I> {
57 fn error(
58 &self,
59 comparator: &Self,
60 tol_abs: &TensorRank0,
61 tol_rel: &TensorRank0,
62 ) -> Option<usize> {
63 let error_count = self
64 .iter()
65 .zip(comparator.iter())
66 .filter(|&(&self_i, &comparator_i)| {
67 &(self_i - comparator_i).abs() >= tol_abs
68 && &(self_i / comparator_i - 1.0).abs() >= tol_rel
69 })
70 .count();
71 if error_count > 0 {
72 Some(error_count)
73 } else {
74 None
75 }
76 }
77 fn error_fd(&self, comparator: &Self, epsilon: &TensorRank0) -> Option<(bool, usize)> {
78 let error_count = self
79 .iter()
80 .zip(comparator.iter())
81 .filter(|&(&self_i, &comparator_i)| {
82 &(self_i / comparator_i - 1.0).abs() >= epsilon
83 && (&self_i.abs() >= epsilon || &comparator_i.abs() >= epsilon)
84 })
85 .count();
86 if error_count > 0 {
87 Some((true, error_count))
88 } else {
89 None
90 }
91 }
92}
93
94impl<const D: usize, const I: usize> Solution for TensorRank1<D, I> {
95 fn decrement_from_chained(&mut self, _other: &mut Vector, _vector: Vector) {
96 unimplemented!()
97 }
98}
99
100impl<const D: usize, const I: usize> Jacobian for TensorRank1<D, I> {
101 fn fill_into(self, _vector: &mut Vector) {
102 unimplemented!()
103 }
104 fn fill_into_chained(self, _other: Vector, _vector: &mut Vector) {
105 unimplemented!()
106 }
107}
108
109impl<const D: usize, const I: usize> Sub<Vector> for TensorRank1<D, I> {
110 type Output = Self;
111 fn sub(self, _vector: Vector) -> Self::Output {
112 unimplemented!()
113 }
114}
115
116impl<const D: usize, const I: usize> Sub<&Vector> for TensorRank1<D, I> {
117 type Output = Self;
118 fn sub(self, _vector: &Vector) -> Self::Output {
119 unimplemented!()
120 }
121}
122
123impl<const D: usize, const I: usize> Tensor for TensorRank1<D, I> {
124 type Item = TensorRank0;
125 fn full_contraction(&self, tensor_rank_1: &Self) -> TensorRank0 {
126 self * tensor_rank_1
127 }
128 fn iter(&self) -> impl Iterator<Item = &Self::Item> {
129 self.0.iter()
130 }
131 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
132 self.0.iter_mut()
133 }
134 fn norm_inf(&self) -> TensorRank0 {
135 self.iter().fold(0.0, |acc, entry| entry.abs().max(acc))
136 }
137}
138
139impl<const D: usize, const I: usize> IntoIterator for TensorRank1<D, I> {
140 type Item = TensorRank0;
141 type IntoIter = std::array::IntoIter<Self::Item, D>;
142 fn into_iter(self) -> Self::IntoIter {
143 self.0.into_iter()
144 }
145}
146
147impl<const D: usize, const I: usize> TensorArray for TensorRank1<D, I> {
148 type Array = [TensorRank0; D];
149 type Item = TensorRank0;
150 fn as_array(&self) -> Self::Array {
151 self.0
152 }
153 fn identity() -> Self {
154 ones()
155 }
156 fn new(array: Self::Array) -> Self {
157 array.into_iter().collect()
158 }
159 fn zero() -> Self {
160 zero()
161 }
162}
163
164pub const fn ones<const D: usize, const I: usize>() -> TensorRank1<D, I> {
166 TensorRank1([1.0; D])
167}
168
169pub const fn zero<const D: usize, const I: usize>() -> TensorRank1<D, I> {
171 TensorRank1([0.0; D])
172}
173
174impl<const D: usize, const I: usize> From<[TensorRank0; D]> for TensorRank1<D, I> {
175 fn from(array: [TensorRank0; D]) -> Self {
176 Self(array)
177 }
178}
179
180impl<const D: usize, const I: usize> From<Vec<TensorRank0>> for TensorRank1<D, I> {
181 fn from(vec: Vec<TensorRank0>) -> Self {
182 Self(vec.try_into().unwrap())
183 }
184}
185
186impl<const D: usize, const I: usize> From<TensorRank1<D, I>> for [TensorRank0; D] {
187 fn from(tensor_rank_1: TensorRank1<D, I>) -> Self {
188 tensor_rank_1.0
189 }
190}
191
192impl<const D: usize, const I: usize> From<TensorRank1<D, I>> for Vec<TensorRank0> {
193 fn from(tensor_rank_1: TensorRank1<D, I>) -> Self {
194 tensor_rank_1.0.to_vec()
195 }
196}
197
198impl From<TensorRank1<3, 0>> for TensorRank1<3, 1> {
199 fn from(tensor_rank_1: TensorRank1<3, 0>) -> Self {
200 unsafe { transmute::<TensorRank1<3, 0>, TensorRank1<3, 1>>(tensor_rank_1) }
201 }
202}
203
204impl<const D: usize, const I: usize> FromIterator<TensorRank0> for TensorRank1<D, I> {
205 fn from_iter<Ii: IntoIterator<Item = TensorRank0>>(into_iterator: Ii) -> Self {
206 let mut tensor_rank_1 = zero();
207 tensor_rank_1
208 .iter_mut()
209 .zip(into_iterator)
210 .for_each(|(tensor_rank_1_i, value_i)| *tensor_rank_1_i = value_i);
211 tensor_rank_1
212 }
213}
214
215impl<const D: usize, const I: usize> Index<usize> for TensorRank1<D, I> {
216 type Output = TensorRank0;
217 fn index(&self, index: usize) -> &Self::Output {
218 &self.0[index]
219 }
220}
221
222impl<const D: usize, const I: usize> IndexMut<usize> for TensorRank1<D, I> {
223 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
224 &mut self.0[index]
225 }
226}
227
228impl<const D: usize, const I: usize> std::iter::Sum for TensorRank1<D, I> {
229 fn sum<Ii>(iter: Ii) -> Self
230 where
231 Ii: Iterator<Item = Self>,
232 {
233 let mut output = zero();
234 iter.for_each(|item| output += item);
235 output
236 }
237}
238
239impl<const D: usize, const I: usize> Div<TensorRank0> for TensorRank1<D, I> {
240 type Output = Self;
241 fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
242 self /= tensor_rank_0;
243 self
244 }
245}
246
247impl<const D: usize, const I: usize> Div<TensorRank0> for &TensorRank1<D, I> {
248 type Output = TensorRank1<D, I>;
249 fn div(self, tensor_rank_0: TensorRank0) -> Self::Output {
250 self.iter().map(|self_i| self_i / tensor_rank_0).collect()
251 }
252}
253
254impl<const D: usize, const I: usize> Div<&TensorRank0> for TensorRank1<D, I> {
255 type Output = Self;
256 fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
257 self /= tensor_rank_0;
258 self
259 }
260}
261
262impl<const D: usize, const I: usize> Div<&TensorRank0> for &TensorRank1<D, I> {
263 type Output = TensorRank1<D, I>;
264 fn div(self, tensor_rank_0: &TensorRank0) -> Self::Output {
265 self.iter().map(|self_i| self_i / tensor_rank_0).collect()
266 }
267}
268
269impl<const D: usize, const I: usize> DivAssign<TensorRank0> for TensorRank1<D, I> {
270 fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
271 self.iter_mut().for_each(|self_i| *self_i /= &tensor_rank_0);
272 }
273}
274
275impl<const D: usize, const I: usize> DivAssign<&TensorRank0> for TensorRank1<D, I> {
276 fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
277 self.iter_mut().for_each(|self_i| *self_i /= tensor_rank_0);
278 }
279}
280
281impl<const D: usize, const I: usize> Mul<TensorRank0> for TensorRank1<D, I> {
282 type Output = Self;
283 fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
284 self *= tensor_rank_0;
285 self
286 }
287}
288
289impl<const D: usize, const I: usize> Mul<TensorRank0> for &TensorRank1<D, I> {
290 type Output = TensorRank1<D, I>;
291 fn mul(self, tensor_rank_0: TensorRank0) -> Self::Output {
292 self.iter().map(|self_i| self_i * tensor_rank_0).collect()
293 }
294}
295
296impl<const D: usize, const I: usize> Mul<&TensorRank0> for TensorRank1<D, I> {
297 type Output = Self;
298 fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
299 self *= tensor_rank_0;
300 self
301 }
302}
303
304impl<const D: usize, const I: usize> Mul<&TensorRank0> for &TensorRank1<D, I> {
305 type Output = TensorRank1<D, I>;
306 fn mul(self, tensor_rank_0: &TensorRank0) -> Self::Output {
307 self.iter().map(|self_i| self_i * tensor_rank_0).collect()
308 }
309}
310
311impl<const D: usize, const I: usize> MulAssign<TensorRank0> for TensorRank1<D, I> {
312 fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
313 self.iter_mut().for_each(|self_i| *self_i *= &tensor_rank_0);
314 }
315}
316
317impl<const D: usize, const I: usize> MulAssign<&TensorRank0> for TensorRank1<D, I> {
318 fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
319 self.iter_mut().for_each(|self_i| *self_i *= tensor_rank_0);
320 }
321}
322
323impl<const D: usize, const I: usize> Add for TensorRank1<D, I> {
324 type Output = Self;
325 fn add(mut self, tensor_rank_1: Self) -> Self::Output {
326 self += tensor_rank_1;
327 self
328 }
329}
330
331impl<const D: usize, const I: usize> Add<&Self> for TensorRank1<D, I> {
332 type Output = Self;
333 fn add(mut self, tensor_rank_1: &Self) -> Self::Output {
334 self += tensor_rank_1;
335 self
336 }
337}
338
339impl<const D: usize, const I: usize> Add<TensorRank1<D, I>> for &TensorRank1<D, I> {
340 type Output = TensorRank1<D, I>;
341 fn add(self, mut tensor_rank_1: TensorRank1<D, I>) -> Self::Output {
342 tensor_rank_1 += self;
343 tensor_rank_1
344 }
345}
346
347impl<const D: usize, const I: usize> AddAssign for TensorRank1<D, I> {
348 fn add_assign(&mut self, tensor_rank_1: Self) {
349 self.iter_mut()
350 .zip(tensor_rank_1.iter())
351 .for_each(|(self_i, tensor_rank_1_i)| *self_i += tensor_rank_1_i);
352 }
353}
354
355impl<const D: usize, const I: usize> AddAssign<&Self> for TensorRank1<D, I> {
356 fn add_assign(&mut self, tensor_rank_1: &Self) {
357 self.iter_mut()
358 .zip(tensor_rank_1.iter())
359 .for_each(|(self_i, tensor_rank_1_i)| *self_i += tensor_rank_1_i);
360 }
361}
362
363impl<const D: usize, const I: usize> Sub for TensorRank1<D, I> {
364 type Output = Self;
365 fn sub(mut self, tensor_rank_1: Self) -> Self::Output {
366 self -= tensor_rank_1;
367 self
368 }
369}
370
371impl<const D: usize, const I: usize> Sub<&Self> for TensorRank1<D, I> {
372 type Output = Self;
373 fn sub(mut self, tensor_rank_1: &Self) -> Self::Output {
374 self -= tensor_rank_1;
375 self
376 }
377}
378
379impl<const D: usize, const I: usize> Sub<TensorRank1<D, I>> for &TensorRank1<D, I> {
380 type Output = TensorRank1<D, I>;
381 fn sub(self, mut tensor_rank_1: TensorRank1<D, I>) -> Self::Output {
382 tensor_rank_1
383 .iter_mut()
384 .zip(self.iter())
385 .for_each(|(tensor_rank_1_i, self_i)| *tensor_rank_1_i = self_i - *tensor_rank_1_i);
386 tensor_rank_1
387 }
388}
389
390impl<const D: usize, const I: usize> Sub<Self> for &TensorRank1<D, I> {
391 type Output = TensorRank1<D, I>;
392 fn sub(self, tensor_rank_1: Self) -> Self::Output {
393 tensor_rank_1
394 .iter()
395 .zip(self.iter())
396 .map(|(tensor_rank_1_i, self_i)| self_i - *tensor_rank_1_i)
397 .collect()
398 }
399}
400
401impl<const D: usize, const I: usize> SubAssign for TensorRank1<D, I> {
402 fn sub_assign(&mut self, tensor_rank_1: Self) {
403 self.iter_mut()
404 .zip(tensor_rank_1.iter())
405 .for_each(|(self_i, tensor_rank_1_i)| *self_i -= tensor_rank_1_i);
406 }
407}
408
409impl<const D: usize, const I: usize> SubAssign<&Self> for TensorRank1<D, I> {
410 fn sub_assign(&mut self, tensor_rank_1: &Self) {
411 self.iter_mut()
412 .zip(tensor_rank_1.iter())
413 .for_each(|(self_i, tensor_rank_1_i)| *self_i -= tensor_rank_1_i);
414 }
415}
416
417impl<const D: usize, const I: usize> Mul for TensorRank1<D, I> {
418 type Output = TensorRank0;
419 fn mul(self, tensor_rank_1: Self) -> Self::Output {
420 self.iter()
421 .zip(tensor_rank_1.iter())
422 .map(|(self_i, tensor_rank_1_i)| self_i * tensor_rank_1_i)
423 .sum()
424 }
425}
426
427impl<const D: usize, const I: usize> Mul<&Self> for TensorRank1<D, I> {
428 type Output = TensorRank0;
429 fn mul(self, tensor_rank_1: &Self) -> Self::Output {
430 self.iter()
431 .zip(tensor_rank_1.iter())
432 .map(|(self_i, tensor_rank_1_i)| self_i * tensor_rank_1_i)
433 .sum()
434 }
435}
436
437impl<const D: usize, const I: usize> Mul<TensorRank1<D, I>> for &TensorRank1<D, I> {
438 type Output = TensorRank0;
439 fn mul(self, tensor_rank_1: TensorRank1<D, I>) -> Self::Output {
440 self.iter()
441 .zip(tensor_rank_1.iter())
442 .map(|(self_i, tensor_rank_1_i)| self_i * tensor_rank_1_i)
443 .sum()
444 }
445}
446
447impl<const D: usize, const I: usize> Mul for &TensorRank1<D, I> {
448 type Output = TensorRank0;
449 fn mul(self, tensor_rank_1: Self) -> Self::Output {
450 self.iter()
451 .zip(tensor_rank_1.iter())
452 .map(|(self_i, tensor_rank_1_i)| self_i * tensor_rank_1_i)
453 .sum()
454 }
455}
456
457#[allow(clippy::suspicious_arithmetic_impl)]
458impl<const D: usize, const I: usize, const J: usize> Div<TensorRank2<D, I, J>>
459 for &TensorRank1<D, I>
460{
461 type Output = TensorRank1<D, J>;
462 fn div(self, tensor_rank_2: TensorRank2<D, I, J>) -> Self::Output {
463 tensor_rank_2.inverse() * self
464 }
465}