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