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, HessianBlock, Jacobian, Solution, SquareMatrix, Tensor, TensorArray, Vector};
12use std::{
13    ops::{IndexMut, Sub},
14    slice::from_ref,
15};
16
17/// A tensor of rank 0 (a scalar).
18pub type TensorRank0 = f64;
19
20impl FiniteDifference for TensorRank0 {
21    fn error_fd(&self, comparator: &Self, epsilon: TensorRank0) -> Option<(bool, usize)> {
22        if ((self / comparator - 1.0).abs() >= epsilon && (self - comparator).abs() >= epsilon)
23            || self.is_nan()
24            || comparator.is_nan()
25        {
26            Some((true, 1))
27        } else {
28            None
29        }
30    }
31}
32
33impl Solution for TensorRank0 {
34    fn decrement_from(&mut self, _other: &Vector) {
35        unimplemented!()
36    }
37    fn decrement_from_chained(&mut self, _other: &mut Vector, _vector: &Vector) {
38        unimplemented!()
39    }
40}
41
42impl Jacobian for TensorRank0 {
43    fn fill_into(&self, _vector: &mut Vector) {
44        unimplemented!()
45    }
46    fn fill_into_chained(self, _other: Vector, _vector: &mut Vector) {
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 Sub<&Vector> for TensorRank0 {
59    type Output = Self;
60    fn sub(self, _vector: &Vector) -> Self::Output {
61        unimplemented!()
62    }
63}
64
65impl Hessian for TensorRank0 {
66    fn quadratic_form(&self, vector: &Vector) -> TensorRank0 {
67        self * vector[0] * vector[0]
68    }
69    fn entry(&self, _row: usize, _column: usize) -> TensorRank0 {
70        unimplemented!()
71    }
72    fn fill_into(self, _square_matrix: &mut SquareMatrix) {
73        unimplemented!()
74    }
75}
76
77impl HessianBlock for TensorRank0 {
78    fn entry(&self, _row: usize, _column: usize) -> TensorRank0 {
79        *self
80    }
81    fn height(&self) -> usize {
82        1
83    }
84    fn width(&self) -> usize {
85        1
86    }
87    fn fill_into_block<M>(&self, matrix: &mut M, row: usize, column: usize)
88    where
89        M: IndexMut<usize, Output = Vector>,
90    {
91        matrix[row][column] = *self
92    }
93}
94
95impl Tensor for TensorRank0 {
96    type Item = TensorRank0;
97    type Unit = Dimensionless;
98    fn error_count_zero(&self, tol_abs: TensorRank0, tol_rel: TensorRank0) -> Option<usize> {
99        if (self.sub_abs(&0.0) < tol_abs || self.sub_rel(&0.0) < tol_rel) && !self.is_nan() {
100            None
101        } else {
102            Some(1)
103        }
104    }
105    fn error_count(
106        &self,
107        other: &Self,
108        tol_abs: TensorRank0,
109        tol_rel: TensorRank0,
110    ) -> Option<usize> {
111        if (self.sub_abs(other) < tol_abs || self.sub_rel(other) < tol_rel)
112            && !self.is_nan()
113            && !other.is_nan()
114        {
115            None
116        } else {
117            Some(1)
118        }
119    }
120    fn full_contraction(&self, tensor_rank_0: &Self) -> TensorRank0 {
121        self.algebraic_mul(*tensor_rank_0)
122    }
123    fn is_zero(&self) -> bool {
124        self == &0.0
125    }
126    fn iter(&self) -> impl Iterator<Item = &Self::Item> {
127        from_ref(self).iter()
128    }
129    fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Item> {
130        [self].into_iter()
131    }
132    fn len(&self) -> usize {
133        1
134    }
135    fn norm_inf(&self) -> Quantity<Dimensionless> {
136        Quantity::new(self.abs())
137    }
138    fn norm_l1(&self) -> Quantity<Dimensionless> {
139        Quantity::new(self.abs())
140    }
141    fn norm_p_sum(&self, p: TensorRank0) -> TensorRank0 {
142        self.abs().powf(p)
143    }
144    fn size(&self) -> usize {
145        1
146    }
147    fn sub_abs(&self, other: &Self) -> Self {
148        (self - other).abs()
149    }
150    fn sub_rel(&self, other: &Self) -> Self {
151        if other == &0.0 {
152            if self == &0.0 { 0.0 } else { 1.0 }
153        } else {
154            (self / other - 1.0).abs()
155        }
156    }
157}
158
159impl TensorArray for TensorRank0 {
160    type Array = Self;
161    type Item = TensorRank0;
162    fn as_array(&self) -> Self::Array {
163        *self
164    }
165    fn identity() -> Self {
166        1.0
167    }
168    fn zero() -> Self {
169        0.0
170    }
171}
172
173impl From<Vector> for TensorRank0 {
174    fn from(_vector: Vector) -> Self {
175        unimplemented!()
176    }
177}