conspire/math/tensor/rank_0/
mod.rs1#[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
14pub 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}