conspire/math/tensor/
mod.rs1pub mod test;
2
3pub mod rank_0;
4pub mod rank_1;
5pub mod rank_2;
6pub mod rank_3;
7pub mod rank_4;
8
9use super::{SquareMatrix, Vector};
10use crate::defeat_message;
11use rank_0::TensorRank0;
12use std::{
13 fmt::{self, Debug, Display, Formatter},
14 ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign},
15};
16
17pub type Scalar = TensorRank0;
19
20#[derive(PartialEq)]
22pub enum TensorError {
23 NotPositiveDefinite,
24}
25
26impl Debug for TensorError {
27 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
28 let error = match self {
29 Self::NotPositiveDefinite => "\x1b[1;91mResult is not positive definite.".to_string(),
30 };
31 write!(f, "\n{error}\n\x1b[0;2;31m{}\x1b[0m\n", defeat_message())
32 }
33}
34
35impl Display for TensorError {
36 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
37 let error = match self {
38 Self::NotPositiveDefinite => "\x1b[1;91mResult is not positive definite.".to_string(),
39 };
40 write!(f, "{error}\x1b[0m")
41 }
42}
43
44pub trait Solution
46where
47 Self: From<Vector> + Tensor,
48{
49 fn decrement_from(&mut self, other: &Vector);
51 fn decrement_from_chained(&mut self, other: &mut Vector, vector: Vector);
53 fn decrement_from_retained(&mut self, _retained: &[bool], _other: &Vector) {
55 unimplemented!()
56 }
57}
58
59pub trait Jacobian
61where
62 Self:
63 From<Vector> + Tensor + Sub<Vector, Output = Self> + for<'a> Sub<&'a Vector, Output = Self>,
64{
65 fn fill_into(self, vector: &mut Vector);
67 fn fill_into_chained(self, other: Vector, vector: &mut Vector);
69 fn retain_from(self, _retained: &[bool]) -> Vector {
71 unimplemented!()
72 }
73 fn zero_out(&mut self, _indices: &[usize]) {
75 unimplemented!()
76 }
77}
78
79pub trait Hessian
81where
82 Self: Tensor,
83{
84 fn fill_into(self, square_matrix: &mut SquareMatrix);
86 fn retain_from(self, _retained: &[bool]) -> SquareMatrix {
88 unimplemented!()
89 }
90}
91
92pub trait Rank2
94where
95 Self: Sized,
96{
97 type Transpose;
99 fn deviatoric(&self) -> Self;
101 fn deviatoric_and_trace(&self) -> (Self, TensorRank0);
103 fn is_diagonal(&self) -> bool;
105 fn is_identity(&self) -> bool;
107 fn is_symmetric(&self) -> bool;
109 fn second_invariant(&self) -> TensorRank0 {
111 0.5 * (self.trace().powi(2) - self.squared_trace())
112 }
113 fn squared_trace(&self) -> TensorRank0;
115 fn trace(&self) -> TensorRank0;
117 fn transpose(&self) -> Self::Transpose;
119}
120
121pub trait Tensor
123where
124 for<'a> Self: Sized
125 + Debug
126 + Default
127 + Display
128 + Add<Self, Output = Self>
129 + Add<&'a Self, Output = Self>
130 + AddAssign
131 + AddAssign<&'a Self>
132 + Clone
133 + Div<TensorRank0, Output = Self>
134 + DivAssign<TensorRank0>
135 + Mul<TensorRank0, Output = Self>
136 + MulAssign<TensorRank0>
137 + Sub<Self, Output = Self>
138 + Sub<&'a Self, Output = Self>
139 + SubAssign
140 + SubAssign<&'a Self>,
141 Self::Item: Tensor,
142{
143 type Item;
145 fn error_count(&self, other: &Self, tol_abs: &Scalar, tol_rel: &Scalar) -> Option<usize> {
147 let error_count = self
148 .iter()
149 .zip(other.iter())
150 .filter_map(|(self_entry, other_entry)| {
151 self_entry.error_count(other_entry, tol_abs, tol_rel)
152 })
153 .sum();
154 if error_count > 0 {
155 Some(error_count)
156 } else {
157 None
158 }
159 }
160 fn full_contraction(&self, tensor: &Self) -> TensorRank0 {
162 self.iter()
163 .zip(tensor.iter())
164 .map(|(self_entry, tensor_entry)| self_entry.full_contraction(tensor_entry))
165 .sum()
166 }
167 fn is_zero(&self) -> bool {
169 self.iter().filter(|entry| !entry.is_zero()).count() == 0
170 }
171 fn iter(&self) -> impl Iterator<Item = &Self::Item>;
175 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item>;
179 fn norm(&self) -> TensorRank0 {
181 self.norm_squared().sqrt()
182 }
183 fn norm_inf(&self) -> TensorRank0 {
185 unimplemented!()
186 }
187 fn norm_squared(&self) -> TensorRank0 {
189 self.full_contraction(self)
190 }
191 fn normalize(&mut self) {
193 *self /= self.norm()
194 }
195 fn normalized(self) -> Self {
197 let norm = self.norm();
198 self / norm
199 }
200 fn num_entries(&self) -> usize {
202 unimplemented!()
203 }
204 fn sub_abs(&self, other: &Self) -> Self {
206 let mut difference = self.clone();
207 difference
208 .iter_mut()
209 .zip(self.iter().zip(other.iter()))
210 .for_each(|(entry, (self_entry, other_entry))| {
211 *entry = self_entry.sub_abs(other_entry)
212 });
213 difference
214 }
215 fn sub_rel(&self, other: &Self) -> Self {
217 let mut difference = self.clone();
218 difference
219 .iter_mut()
220 .zip(self.iter().zip(other.iter()))
221 .for_each(|(entry, (self_entry, other_entry))| {
222 *entry = self_entry.sub_rel(other_entry)
223 });
224 difference
225 }
226}
227
228pub trait TensorArray {
230 type Array;
232 type Item;
234 fn as_array(&self) -> Self::Array;
236 fn identity() -> Self;
238 fn new(array: Self::Array) -> Self;
240 fn zero() -> Self;
242}
243
244pub trait TensorVec
246where
247 Self: FromIterator<Self::Item> + Index<usize, Output = Self::Item> + IndexMut<usize>,
248{
249 type Item;
251 type Slice<'a>;
253 fn append(&mut self, other: &mut Self);
255 fn capacity(&self) -> usize;
257 fn is_empty(&self) -> bool;
259 fn len(&self) -> usize;
261 fn new(slice: Self::Slice<'_>) -> Self;
263 fn push(&mut self, item: Self::Item);
265 fn remove(&mut self, _index: usize) -> Self::Item;
267 fn retain<F>(&mut self, f: F)
269 where
270 F: FnMut(&Self::Item) -> bool;
271 fn swap_remove(&mut self, _index: usize) -> Self::Item;
273 fn zero(len: usize) -> Self;
275}