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