53 if (
A.rows() !=
A.cols())
54 throw std::invalid_argument(
"eig_sym: matrix must be square");
60 for (
idx i = 0;
i < n; ++
i) V(
i,
i) = 1.0;
63 bool converged =
false;
67 for (
idx p = 0; p < n; ++p)
68 for (
idx q = p+1; q < n; ++q)
71 if (std::sqrt(2.0 *
off) <
tol) { converged =
true;
break; }
73 for (
idx p = 0; p < n-1; ++p) {
74 for (
idx q = p+1; q < n; ++q) {
80 real t = std::copysign(1.0,
tau)
81 / (std::abs(
tau) + std::sqrt(1.0 +
tau*
tau));
82 real c = 1.0 / std::sqrt(1.0 + t*t);
87 Aw(p,q) =
Aw(q,p) = 0.0;
90#ifdef NUMERICS_HAS_OMP
91 #pragma omp parallel for schedule(static) if(backend == Backend::omp)
93 for (
idx r = 0;
r < n; ++
r) {
94 if (
r == p ||
r == q)
continue;
99#ifdef NUMERICS_HAS_OMP
100 #pragma omp parallel for schedule(static) if(backend == Backend::omp)
102 for (
idx r = 0;
r < n; ++
r) {
115 for (
idx i = 0;
i < n-1; ++
i) {
120 std::swap(values[
i], values[
min_j]);
121 for (
idx r = 0;
r < n; ++
r)
126 return {values, V, sweeps, converged};
Dense row-major matrix with optional GPU storage.
Backend
Selects which backend handles a linalg operation.
@ seq
Naive textbook loops – always available.
constexpr T ipow(T x) noexcept
Compute x^N at compile time via repeated squaring.
EigenResult eig_sym(const Matrix &A, real tol=1e-12, idx max_sweeps=100, Backend backend=Backend::seq)
Full eigendecomposition of a real symmetric matrix.
Backend enum for linear algebra operations.
Full eigendecomposition result: A = V * diag(values) * V^T.
Vector values
Eigenvalues in ascending order.
bool converged
Whether off-diagonal norm fell below tol.
idx sweeps
Number of Jacobi sweeps performed.
Matrix vectors
Eigenvectors as columns of an nxn orthogonal matrix.