tesseract++ 0.0.1
N-dimensional tensor library for embedded systems
Loading...
Searching...
No Matches
eigen.h
Go to the documentation of this file.
1#ifndef FUSED_ALGORITHMS_EIGEN_JACOBI_H
2#define FUSED_ALGORITHMS_EIGEN_JACOBI_H
3
4#include "config.h"
6#include "matrix_traits.h"
9#include "math/math_utils.h" // math::sqrt, math::abs
10
58namespace matrix_algorithms
59{
60
62
69 template <typename T, my_size_t N>
75
100 template <typename T, my_size_t N>
102 const FusedMatrix<T, N, N> &A,
103 my_size_t max_iters = 100,
104 T tol = T(PRECISION_TOLERANCE))
105 {
106 static_assert(is_floating_point_v<T>,
107 "eigen_jacobi requires a floating-point scalar type");
108
109 if (!A.isSymmetric())
110 {
111 return Unexpected{MatrixStatus::NotSymmetric};
112 }
113
114 // Work matrix (will be diagonalized in place)
116
117 // Eigenvector accumulator (starts as identity)
118 FusedMatrix<T, N, N> V(T(0));
119 V.setIdentity();
120
121 for (my_size_t iter = 0; iter < max_iters; ++iter)
122 {
123 // 1. Find largest off-diagonal element
124 T max_off = T(0);
125 my_size_t p = 0, q = 1;
126
127 for (my_size_t i = 0; i < N; ++i)
128 {
129 for (my_size_t j = i + 1; j < N; ++j)
130 {
131 T val = math::abs(W(i, j));
132
133 if (val > max_off)
134 {
135 max_off = val;
136 p = i;
137 q = j;
138 }
139 }
140 }
141
142 // Check convergence
143 if (max_off <= tol)
144 {
145 EigenResult<T, N> result;
146
147 for (my_size_t i = 0; i < N; ++i)
148 {
149 result.eigenvalues(i) = W(i, i);
150 }
151
152 result.eigenvectors = V;
153 return move(result);
154 }
155
156 // 2. Compute Givens rotation to zero W(p,q)
157 T c, s;
158
159 T diff = W(p, p) - W(q, q);
160
161 if (math::abs(diff) <= tol)
162 {
163 // A(p,p) ≈ A(q,q) → θ = π/4
164 T inv_sqrt2 = T(1) / math::sqrt(T(2));
165 c = inv_sqrt2;
166 s = (W(p, q) >= T(0)) ? inv_sqrt2 : -inv_sqrt2;
167 }
168 else
169 {
170 // τ = (W(p,p) - W(q,q)) / (2·W(p,q))
171 T tau = diff / (T(2) * W(p, q));
172 // Choose smaller root for numerical stability
173 T t;
174
175 if (tau >= T(0))
176 {
177 t = T(1) / (tau + math::sqrt(T(1) + tau * tau));
178 }
179 else
180 {
181 t = T(-1) / (-tau + math::sqrt(T(1) + tau * tau));
182 }
183
184 c = T(1) / math::sqrt(T(1) + t * t);
185 s = t * c;
186 }
187
188 // 3. Apply rotation to W: W' = Jᵀ·W·J
189 // Only rows/columns p and q are affected.
190
191 // Update columns (right multiply by J)
192 for (my_size_t i = 0; i < N; ++i)
193 {
194 if (i == p || i == q)
195 continue;
196
197 T wip = W(i, p);
198 T wiq = W(i, q);
199 W(i, p) = c * wip + s * wiq;
200 W(i, q) = -s * wip + c * wiq;
201 W(p, i) = W(i, p); // maintain symmetry
202 W(q, i) = W(i, q);
203 }
204
205 // Update 2×2 block [pp, pq; qp, qq]
206 T wpp = W(p, p);
207 T wqq = W(q, q);
208 T wpq = W(p, q);
209
210 W(p, p) = c * c * wpp + T(2) * c * s * wpq + s * s * wqq;
211 W(q, q) = s * s * wpp - T(2) * c * s * wpq + c * c * wqq;
212 W(p, q) = T(0); // this is the element we're zeroing
213 W(q, p) = T(0);
214
215 // 4. Accumulate eigenvectors: V = V·J
216 for (my_size_t i = 0; i < N; ++i)
217 {
218 T vip = V(i, p);
219 T viq = V(i, q);
220 V(i, p) = c * vip + s * viq;
221 V(i, q) = -s * vip + c * viq;
222 }
223 }
224
225 // If we get here, we didn't converge
226 return Unexpected{MatrixStatus::NotConverged};
227 }
228
229} // namespace matrix_algorithms
230
231#endif // FUSED_ALGORITHMS_EIGEN_JACOBI_H
A discriminated union holding either a success value or an error.
Definition expected.h:86
Definition fused_matrix.h:12
bool isSymmetric(void) const
Definition fused_matrix.h:292
FusedMatrix & setIdentity(void)
Definition fused_matrix.h:234
Definition fused_vector.h:9
Global configuration for the tesseract tensor library.
#define my_size_t
Size/index type used throughout the library.
Definition config.h:126
#define PRECISION_TOLERANCE
Tolerance for floating-point comparisons (e.g. symmetry checks, Cholesky).
Definition config.h:117
A minimal, STL-free expected/result type for failable operations.
Runtime property descriptors and error codes for matrices.
constexpr T abs(T x) noexcept
Compute the absolute value of a numeric value.
Definition math_utils.h:48
constexpr T sqrt(T x) noexcept
Compute the square root of a floating-point value.
Definition math_utils.h:29
Definition cholesky.h:52
Expected< EigenResult< T, N >, MatrixStatus > eigen_jacobi(const FusedMatrix< T, N, N > &A, my_size_t max_iters=100, T tol=T(PRECISION_TOLERANCE))
Compute eigenvalues and eigenvectors of a symmetric matrix via Jacobi.
Definition eigen.h:101
MatrixStatus
Error codes for matrix decomposition and solver algorithms.
Definition matrix_traits.h:33
constexpr remove_reference_t< T > && move(T &&t) noexcept
Cast to rvalue reference (replacement for std::move).
Definition simple_type_traits.h:178
Tag type for constructing an Expected in the error state.
Definition expected.h:30
Result of eigenvalue decomposition.
Definition eigen.h:71
FusedMatrix< T, N, N > eigenvectors
Columns are eigenvectors (orthogonal).
Definition eigen.h:73
FusedVector< T, N > eigenvalues
Diagonal of D (unsorted).
Definition eigen.h:72