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, Tensor, TensorArray, rank_0::TensorRank0, rank_2::TensorRank2,
17 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> Tensor for TensorRank1<D, I> {
95 type Item = TensorRank0;
96 fn full_contraction(&self, tensor_rank_1: &Self) -> TensorRank0 {
97 self * tensor_rank_1
98 }
99 fn iter(&self) -> impl Iterator<Item = &Self::Item> {
100 self.0.iter()
101 }
102 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
103 self.0.iter_mut()
104 }
105 fn norm_inf(&self) -> TensorRank0 {
106 self.iter().fold(0.0, |acc, entry| entry.abs().max(acc))
107 }
108}
109
110impl<const D: usize, const I: usize> IntoIterator for TensorRank1<D, I> {
111 type Item = TensorRank0;
112 type IntoIter = std::array::IntoIter<Self::Item, D>;
113 fn into_iter(self) -> Self::IntoIter {
114 self.0.into_iter()
115 }
116}
117
118impl<const D: usize, const I: usize> TensorArray for TensorRank1<D, I> {
119 type Array = [TensorRank0; D];
120 type Item = TensorRank0;
121 fn as_array(&self) -> Self::Array {
122 self.0
123 }
124 fn identity() -> Self {
125 panic!()
126 }
127 fn new(array: Self::Array) -> Self {
128 array.into_iter().collect()
129 }
130 fn zero() -> Self {
131 zero()
132 }
133}
134
135pub const fn zero<const D: usize, const I: usize>() -> TensorRank1<D, I> {
137 TensorRank1([0.0; D])
138}
139
140impl<const D: usize, const I: usize> From<[TensorRank0; D]> for TensorRank1<D, I> {
141 fn from(array: [TensorRank0; D]) -> Self {
142 Self(array)
143 }
144}
145
146impl<const D: usize, const I: usize> From<Vec<TensorRank0>> for TensorRank1<D, I> {
147 fn from(vec: Vec<TensorRank0>) -> Self {
148 Self(vec.try_into().unwrap())
149 }
150}
151
152impl<const D: usize, const I: usize> From<TensorRank1<D, I>> for [TensorRank0; D] {
153 fn from(tensor_rank_1: TensorRank1<D, I>) -> Self {
154 tensor_rank_1.0
155 }
156}
157
158impl<const D: usize, const I: usize> From<TensorRank1<D, I>> for Vec<TensorRank0> {
159 fn from(tensor_rank_1: TensorRank1<D, I>) -> Self {
160 tensor_rank_1.0.to_vec()
161 }
162}
163
164impl From<TensorRank1<3, 0>> for TensorRank1<3, 1> {
165 fn from(tensor_rank_1: TensorRank1<3, 0>) -> Self {
166 unsafe { transmute::<TensorRank1<3, 0>, TensorRank1<3, 1>>(tensor_rank_1) }
167 }
168}
169
170impl<const D: usize, const I: usize> FromIterator<TensorRank0> for TensorRank1<D, I> {
171 fn from_iter<Ii: IntoIterator<Item = TensorRank0>>(into_iterator: Ii) -> Self {
172 let mut tensor_rank_1 = zero();
173 tensor_rank_1
174 .iter_mut()
175 .zip(into_iterator)
176 .for_each(|(tensor_rank_1_i, value_i)| *tensor_rank_1_i = value_i);
177 tensor_rank_1
178 }
179}
180
181impl<const D: usize, const I: usize> Index<usize> for TensorRank1<D, I> {
182 type Output = TensorRank0;
183 fn index(&self, index: usize) -> &Self::Output {
184 &self.0[index]
185 }
186}
187
188impl<const D: usize, const I: usize> IndexMut<usize> for TensorRank1<D, I> {
189 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
190 &mut self.0[index]
191 }
192}
193
194impl<const D: usize, const I: usize> std::iter::Sum for TensorRank1<D, I> {
195 fn sum<Ii>(iter: Ii) -> Self
196 where
197 Ii: Iterator<Item = Self>,
198 {
199 let mut output = zero();
200 iter.for_each(|item| output += item);
201 output
202 }
203}
204
205impl<const D: usize, const I: usize> Div<TensorRank0> for TensorRank1<D, I> {
206 type Output = Self;
207 fn div(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
208 self /= tensor_rank_0;
209 self
210 }
211}
212
213impl<const D: usize, const I: usize> Div<TensorRank0> for &TensorRank1<D, I> {
214 type Output = TensorRank1<D, I>;
215 fn div(self, tensor_rank_0: TensorRank0) -> Self::Output {
216 self.iter().map(|self_i| self_i / tensor_rank_0).collect()
217 }
218}
219
220impl<const D: usize, const I: usize> Div<&TensorRank0> for TensorRank1<D, I> {
221 type Output = Self;
222 fn div(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
223 self /= tensor_rank_0;
224 self
225 }
226}
227
228impl<const D: usize, const I: usize> Div<&TensorRank0> for &TensorRank1<D, I> {
229 type Output = TensorRank1<D, I>;
230 fn div(self, tensor_rank_0: &TensorRank0) -> Self::Output {
231 self.iter().map(|self_i| self_i / tensor_rank_0).collect()
232 }
233}
234
235impl<const D: usize, const I: usize> DivAssign<TensorRank0> for TensorRank1<D, I> {
236 fn div_assign(&mut self, tensor_rank_0: TensorRank0) {
237 self.iter_mut().for_each(|self_i| *self_i /= &tensor_rank_0);
238 }
239}
240
241impl<const D: usize, const I: usize> DivAssign<&TensorRank0> for TensorRank1<D, I> {
242 fn div_assign(&mut self, tensor_rank_0: &TensorRank0) {
243 self.iter_mut().for_each(|self_i| *self_i /= tensor_rank_0);
244 }
245}
246
247impl<const D: usize, const I: usize> Mul<TensorRank0> for TensorRank1<D, I> {
248 type Output = Self;
249 fn mul(mut self, tensor_rank_0: TensorRank0) -> Self::Output {
250 self *= tensor_rank_0;
251 self
252 }
253}
254
255impl<const D: usize, const I: usize> Mul<TensorRank0> for &TensorRank1<D, I> {
256 type Output = TensorRank1<D, I>;
257 fn mul(self, tensor_rank_0: TensorRank0) -> Self::Output {
258 self.iter().map(|self_i| self_i * tensor_rank_0).collect()
259 }
260}
261
262impl<const D: usize, const I: usize> Mul<&TensorRank0> for TensorRank1<D, I> {
263 type Output = Self;
264 fn mul(mut self, tensor_rank_0: &TensorRank0) -> Self::Output {
265 self *= tensor_rank_0;
266 self
267 }
268}
269
270impl<const D: usize, const I: usize> Mul<&TensorRank0> for &TensorRank1<D, I> {
271 type Output = TensorRank1<D, I>;
272 fn mul(self, tensor_rank_0: &TensorRank0) -> Self::Output {
273 self.iter().map(|self_i| self_i * tensor_rank_0).collect()
274 }
275}
276
277impl<const D: usize, const I: usize> MulAssign<TensorRank0> for TensorRank1<D, I> {
278 fn mul_assign(&mut self, tensor_rank_0: TensorRank0) {
279 self.iter_mut().for_each(|self_i| *self_i *= &tensor_rank_0);
280 }
281}
282
283impl<const D: usize, const I: usize> MulAssign<&TensorRank0> for TensorRank1<D, I> {
284 fn mul_assign(&mut self, tensor_rank_0: &TensorRank0) {
285 self.iter_mut().for_each(|self_i| *self_i *= tensor_rank_0);
286 }
287}
288
289impl<const D: usize, const I: usize> Add for TensorRank1<D, I> {
290 type Output = Self;
291 fn add(mut self, tensor_rank_1: Self) -> Self::Output {
292 self += tensor_rank_1;
293 self
294 }
295}
296
297impl<const D: usize, const I: usize> Add<&Self> for TensorRank1<D, I> {
298 type Output = Self;
299 fn add(mut self, tensor_rank_1: &Self) -> Self::Output {
300 self += tensor_rank_1;
301 self
302 }
303}
304
305impl<const D: usize, const I: usize> Add<TensorRank1<D, I>> for &TensorRank1<D, I> {
306 type Output = TensorRank1<D, I>;
307 fn add(self, mut tensor_rank_1: TensorRank1<D, I>) -> Self::Output {
308 tensor_rank_1 += self;
309 tensor_rank_1
310 }
311}
312
313impl<const D: usize, const I: usize> AddAssign for TensorRank1<D, I> {
314 fn add_assign(&mut self, tensor_rank_1: Self) {
315 self.iter_mut()
316 .zip(tensor_rank_1.iter())
317 .for_each(|(self_i, tensor_rank_1_i)| *self_i += tensor_rank_1_i);
318 }
319}
320
321impl<const D: usize, const I: usize> AddAssign<&Self> for TensorRank1<D, I> {
322 fn add_assign(&mut self, tensor_rank_1: &Self) {
323 self.iter_mut()
324 .zip(tensor_rank_1.iter())
325 .for_each(|(self_i, tensor_rank_1_i)| *self_i += tensor_rank_1_i);
326 }
327}
328
329impl<const D: usize, const I: usize> Sub for TensorRank1<D, I> {
330 type Output = Self;
331 fn sub(mut self, tensor_rank_1: Self) -> Self::Output {
332 self -= tensor_rank_1;
333 self
334 }
335}
336
337impl<const D: usize, const I: usize> Sub<&Self> for TensorRank1<D, I> {
338 type Output = Self;
339 fn sub(mut self, tensor_rank_1: &Self) -> Self::Output {
340 self -= tensor_rank_1;
341 self
342 }
343}
344
345impl<const D: usize, const I: usize> Sub<TensorRank1<D, I>> for &TensorRank1<D, I> {
346 type Output = TensorRank1<D, I>;
347 fn sub(self, mut tensor_rank_1: TensorRank1<D, I>) -> Self::Output {
348 tensor_rank_1
349 .iter_mut()
350 .zip(self.iter())
351 .for_each(|(tensor_rank_1_i, self_i)| *tensor_rank_1_i = self_i - *tensor_rank_1_i);
352 tensor_rank_1
353 }
354}
355
356impl<const D: usize, const I: usize> Sub<Self> for &TensorRank1<D, I> {
357 type Output = TensorRank1<D, I>;
358 fn sub(self, tensor_rank_1: Self) -> Self::Output {
359 tensor_rank_1
360 .iter()
361 .zip(self.iter())
362 .map(|(tensor_rank_1_i, self_i)| self_i - *tensor_rank_1_i)
363 .collect()
364 }
365}
366
367impl<const D: usize, const I: usize> SubAssign for TensorRank1<D, I> {
368 fn sub_assign(&mut self, tensor_rank_1: Self) {
369 self.iter_mut()
370 .zip(tensor_rank_1.iter())
371 .for_each(|(self_i, tensor_rank_1_i)| *self_i -= tensor_rank_1_i);
372 }
373}
374
375impl<const D: usize, const I: usize> SubAssign<&Self> for TensorRank1<D, I> {
376 fn sub_assign(&mut self, tensor_rank_1: &Self) {
377 self.iter_mut()
378 .zip(tensor_rank_1.iter())
379 .for_each(|(self_i, tensor_rank_1_i)| *self_i -= tensor_rank_1_i);
380 }
381}
382
383impl<const D: usize, const I: usize> Mul for TensorRank1<D, I> {
384 type Output = TensorRank0;
385 fn mul(self, tensor_rank_1: Self) -> Self::Output {
386 self.iter()
387 .zip(tensor_rank_1.iter())
388 .map(|(self_i, tensor_rank_1_i)| self_i * tensor_rank_1_i)
389 .sum()
390 }
391}
392
393impl<const D: usize, const I: usize> Mul<&Self> for TensorRank1<D, I> {
394 type Output = TensorRank0;
395 fn mul(self, tensor_rank_1: &Self) -> Self::Output {
396 self.iter()
397 .zip(tensor_rank_1.iter())
398 .map(|(self_i, tensor_rank_1_i)| self_i * tensor_rank_1_i)
399 .sum()
400 }
401}
402
403impl<const D: usize, const I: usize> Mul<TensorRank1<D, I>> for &TensorRank1<D, I> {
404 type Output = TensorRank0;
405 fn mul(self, tensor_rank_1: TensorRank1<D, I>) -> Self::Output {
406 self.iter()
407 .zip(tensor_rank_1.iter())
408 .map(|(self_i, tensor_rank_1_i)| self_i * tensor_rank_1_i)
409 .sum()
410 }
411}
412
413impl<const D: usize, const I: usize> Mul for &TensorRank1<D, I> {
414 type Output = TensorRank0;
415 fn mul(self, tensor_rank_1: Self) -> Self::Output {
416 self.iter()
417 .zip(tensor_rank_1.iter())
418 .map(|(self_i, tensor_rank_1_i)| self_i * tensor_rank_1_i)
419 .sum()
420 }
421}
422
423#[allow(clippy::suspicious_arithmetic_impl)]
424impl<const D: usize, const I: usize, const J: usize> Div<TensorRank2<D, I, J>>
425 for TensorRank1<D, I>
426{
427 type Output = TensorRank1<D, J>;
428 fn div(self, tensor_rank_2: TensorRank2<D, I, J>) -> Self::Output {
429 tensor_rank_2.inverse() * self
430 }
431}