conspire/math/tensor/rank_0/
mod.rs

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