conspire/math/tensor/
mod.rs1pub mod test;
3
4pub mod rank_0;
5pub mod rank_1;
6pub mod rank_2;
7pub mod rank_3;
8pub mod rank_4;
9
10use super::{SquareMatrix, Vector};
11use crate::defeat_message;
12use rank_0::TensorRank0;
13use std::{
14 fmt::{self, Debug, Display, Formatter},
15 ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, Sub, SubAssign},
16};
17
18#[derive(PartialEq)]
20pub enum TensorError {
21 NotPositiveDefinite,
22}
23
24impl Debug for TensorError {
25 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
26 let error = match self {
27 Self::NotPositiveDefinite => "\x1b[1;91mResult is not positive definite.".to_string(),
28 };
29 write!(f, "\n{}\n\x1b[0;2;31m{}\x1b[0m\n", error, defeat_message())
30 }
31}
32
33impl Display for TensorError {
34 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
35 let error = match self {
36 Self::NotPositiveDefinite => "\x1b[1;91mResult is not positive definite.".to_string(),
37 };
38 write!(f, "{}\x1b[0m", error)
39 }
40}
41
42pub trait Solution
44where
45 Self: Tensor,
46{
47 fn decrement_from_chained(&mut self, other: &mut Vector, vector: Vector);
49}
50
51pub trait Jacobian
53where
54 Self: Tensor + Sub<Vector, Output = Self>,
55{
56 fn fill_into(self, vector: &mut Vector);
58 fn fill_into_chained(self, other: Vector, vector: &mut Vector);
60}
61
62pub trait Hessian
64where
65 Self: Tensor,
66{
67 fn fill_into(self, square_matrix: &mut SquareMatrix);
69 fn is_positive_definite(&self) -> bool;
71}
72
73pub trait Rank2
75where
76 Self: Sized,
77{
78 type Transpose;
80 fn cholesky_decomposition(&self) -> Result<Self, TensorError>;
82 fn deviatoric(&self) -> Self;
84 fn deviatoric_and_trace(&self) -> (Self, TensorRank0);
86 fn is_diagonal(&self) -> bool;
88 fn is_identity(&self) -> bool;
90 fn second_invariant(&self) -> TensorRank0 {
92 0.5 * (self.trace().powi(2) - self.squared_trace())
93 }
94 fn squared_trace(&self) -> TensorRank0;
96 fn trace(&self) -> TensorRank0;
98 fn transpose(&self) -> Self::Transpose;
100}
101
102pub trait Tensor
104where
105 for<'a> Self: Sized
106 + Debug
107 + Display
108 + Add<Self, Output = Self>
109 + Add<&'a Self, Output = Self>
110 + AddAssign
111 + AddAssign<&'a Self>
112 + Clone
113 + Div<TensorRank0, Output = Self>
114 + DivAssign<TensorRank0>
115 + Mul<TensorRank0, Output = Self>
116 + Sub<Self, Output = Self>
117 + Sub<&'a Self, Output = Self>
118 + SubAssign
119 + SubAssign<&'a Self>,
120 Self::Item: Tensor,
121{
122 type Item;
124 fn full_contraction(&self, tensor: &Self) -> TensorRank0 {
126 self.iter()
127 .zip(tensor.iter())
128 .map(|(self_entry, tensor_entry)| self_entry.full_contraction(tensor_entry))
129 .sum()
130 }
131 fn is_zero(&self) -> bool {
133 self.iter().filter(|entry| !entry.is_zero()).count() == 0
134 }
135 fn iter(&self) -> impl Iterator<Item = &Self::Item>;
139 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item>;
143 fn norm(&self) -> TensorRank0 {
145 self.norm_squared().sqrt()
146 }
147 fn norm_inf(&self) -> TensorRank0 {
149 unimplemented!()
150 }
151 fn norm_squared(&self) -> TensorRank0 {
153 self.full_contraction(self)
154 }
155 fn normalize(&mut self) {
157 *self /= self.norm()
158 }
159 fn normalized(self) -> Self {
161 let norm = self.norm();
162 self / norm
163 }
164 fn num_entries(&self) -> usize {
166 unimplemented!()
167 }
168}
169
170pub trait TensorArray {
172 type Array;
174 type Item;
176 fn as_array(&self) -> Self::Array;
178 fn identity() -> Self;
180 fn new(array: Self::Array) -> Self;
182 fn zero() -> Self;
184}
185
186pub trait TensorVec
188where
189 Self: FromIterator<Self::Item> + Index<usize, Output = Self::Item> + IndexMut<usize>,
190{
191 type Item;
193 type Slice<'a>;
195 fn append(&mut self, other: &mut Self);
197 fn is_empty(&self) -> bool;
199 fn len(&self) -> usize;
201 fn new(slice: Self::Slice<'_>) -> Self;
203 fn push(&mut self, item: Self::Item);
205 fn zero(len: usize) -> Self;
207}