Skip to main content

conspire/math/tensor/rank_0/
mod.rs

1#[cfg(test)]
2mod test;
3
4use super::Quantity;
5use crate::math::assert::FiniteDifference;
6use crate::units::Dimensionless;
7
8pub(crate) mod list;
9pub(crate) mod list_2d;
10
11use super::{Hessian, Jacobian, Solution, SquareMatrix, Tensor, TensorArray, Vector};
12use std::{ops::Sub, slice::from_ref};
13
14/// A tensor of rank 0 (a scalar).
15pub type TensorRank0 = f64;
16
17impl FiniteDifference for TensorRank0 {
18    fn error_fd(&self, comparator: &Self, epsilon: TensorRank0) -> Option<(bool, usize)> {
19        if ((self / comparator - 1.0).abs() >= epsilon && (self - comparator).abs() >= epsilon)
20            || self.is_nan()
21            || comparator.is_nan()
22        {
23            Some((true, 1))
24        } else {
25            None
26        }
27    }
28}
29
30impl Solution for TensorRank0 {
31    fn decrement_from(&mut self, _other: &Vector) {
32        unimplemented!()
33    }
34    fn decrement_from_chained(&mut self, _other: &mut Vector, _vector: &Vector) {
35        unimplemented!()
36    }
37}
38
39impl Jacobian for TensorRank0 {
40    fn fill_into(&self, _vector: &mut Vector) {
41        unimplemented!()
42    }
43    fn fill_into_chained(self, _other: Vector, _vector: &mut Vector) {
44        unimplemented!()
45    }
46}
47
48impl Sub<Vector> for TensorRank0 {
49    type Output = Self;
50    fn sub(self, _vector: Vector) -> Self::Output {
51        unimplemented!()
52    }
53}
54
55impl Sub<&Vector> for TensorRank0 {
56    type Output = Self;
57    fn sub(self, _vector: &Vector) -> Self::Output {
58        unimplemented!()
59    }
60}
61
62impl Hessian for TensorRank0 {
63    fn quadratic_form(&self, vector: &Vector) -> TensorRank0 {
64        self * vector[0] * vector[0]
65    }
66    fn entry(&self, _row: usize, _column: usize) -> TensorRank0 {
67        unimplemented!()
68    }
69    fn fill_into(self, _square_matrix: &mut SquareMatrix) {
70        unimplemented!()
71    }
72}
73
74impl Tensor for TensorRank0 {
75    type Item = TensorRank0;
76    type Unit = Dimensionless;
77    fn error_count_zero(&self, tol_abs: TensorRank0, tol_rel: TensorRank0) -> Option<usize> {
78        if (self.sub_abs(&0.0) < tol_abs || self.sub_rel(&0.0) < tol_rel) && !self.is_nan() {
79            None
80        } else {
81            Some(1)
82        }
83    }
84    fn error_count(
85        &self,
86        other: &Self,
87        tol_abs: TensorRank0,
88        tol_rel: TensorRank0,
89    ) -> Option<usize> {
90        if (self.sub_abs(other) < tol_abs || self.sub_rel(other) < tol_rel)
91            && !self.is_nan()
92            && !other.is_nan()
93        {
94            None
95        } else {
96            Some(1)
97        }
98    }
99    fn full_contraction(&self, tensor_rank_0: &Self) -> TensorRank0 {
100        self * tensor_rank_0
101    }
102    fn is_zero(&self) -> bool {
103        self == &0.0
104    }
105    fn iter(&self) -> impl Iterator<Item = &Self::Item> {
106        from_ref(self).iter()
107    }
108    fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
109        [self].into_iter()
110    }
111    fn len(&self) -> usize {
112        1
113    }
114    fn norm_inf(&self) -> Quantity<Dimensionless> {
115        Quantity::new(self.abs())
116    }
117    fn norm_l1(&self) -> Quantity<Dimensionless> {
118        Quantity::new(self.abs())
119    }
120    fn norm_p_sum(&self, p: TensorRank0) -> TensorRank0 {
121        self.abs().powf(p)
122    }
123    fn size(&self) -> usize {
124        1
125    }
126    fn sub_abs(&self, other: &Self) -> Self {
127        (self - other).abs()
128    }
129    fn sub_rel(&self, other: &Self) -> Self {
130        if other == &0.0 {
131            if self == &0.0 { 0.0 } else { 1.0 }
132        } else {
133            (self / other - 1.0).abs()
134        }
135    }
136}
137
138impl TensorArray for TensorRank0 {
139    type Array = Self;
140    type Item = TensorRank0;
141    fn as_array(&self) -> Self::Array {
142        *self
143    }
144    fn identity() -> Self {
145        1.0
146    }
147    fn zero() -> Self {
148        0.0
149    }
150}
151
152impl From<Vector> for TensorRank0 {
153    fn from(_vector: Vector) -> Self {
154        unimplemented!()
155    }
156}