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