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, HessianBlock, Jacobian, Solution, SquareMatrix, Tensor, TensorArray, Vector};
12use std::{
13 ops::{IndexMut, Sub},
14 slice::from_ref,
15};
16
17pub 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}