akreon-linalg
Fixed-size linear algebra and numerical methods in C++26.
Loading...
Searching...
No Matches
symmetric_operator.hpp
Go to the documentation of this file.
1/*
2 * Copyright © 2025-2026 Akreon LLC
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6#pragma once
7
9#include "endomorphism.hpp"
10#include "operator_traits.hpp"
11
12namespace linalg {
13
17template <SquareMatrix Mat, typename Derived>
18struct SymmetricOperator : Endomorphism<Mat, SymmetricOperator<Mat, Derived>> {
24
26 using OperatorBase::N;
27
29 static constexpr std::size_t DIM = (N * (N + 1)) / 2;
30
36 constexpr explicit SymmetricOperator(const Mat& A) : svec(get_svec(A)) {}
37
46 constexpr auto operator()(std::size_t i, std::size_t j) const {
47 const auto x = svec(index(i, j));
48 if (i == j) return x;
49 return x / sqrt2_v<T>;
50 }
51
60 constexpr std::size_t index(std::size_t i, std::size_t j) const {
61 AK_ASSERT((j < N && i < N) &&
62 "SymmetricOperator index expects row/col inside [0, N)");
63 if (i >= j) return i * (i + 1) / 2 + j;
64 return j * (j + 1) / 2 + i;
65 }
66
72 constexpr bool is_pd() const { return type == SymmetricOperatorType::PD; }
73
79 constexpr bool is_nd() const { return type == SymmetricOperatorType::ND; }
80
86 constexpr bool is_psd() const {
89 }
90
96 constexpr bool is_nsd() const {
99 }
100
106 constexpr bool is_ind() const { return type == SymmetricOperatorType::IND; }
107
113 constexpr bool is_valid() const { return type != SymmetricOperatorType::INV; }
114
122 template <typename DiagT>
124 const ScalarT& tol) {
125 std::size_t npos = 0, nneg = 0, nzero = 0;
126
127 auto classify_scalar = [&](const auto& d_real) {
128 if (d_real > tol) ++npos;
129 else if (d_real < -tol) ++nneg;
130 else ++nzero;
131 };
132
133 if constexpr (is_complex_v<DiagT>) {
134 for (const auto& d : diag) classify_scalar(d.real());
135 } else {
136 for (const auto& d : diag) classify_scalar(d);
137 }
138
139 if (nneg == 0 && nzero == 0) type = SymmetricOperatorType::PD;
140 else if (nneg == 0 && nzero > 0) type = SymmetricOperatorType::PSD;
141 else if (npos == 0 && nzero == 0) type = SymmetricOperatorType::ND;
142 else if (npos == 0 && nzero > 0) type = SymmetricOperatorType::NSD;
144 }
145
151 constexpr const Derived& self() const { return static_cast<Derived&>(*this); }
152
154 SymmetricOperatorType type; //< SymmetricOperatorType value
155 Vector<T, DIM> svec; //< Data stored as svec(A): lower triangle with
156 // sqrt(2)-scaled off-diagonals
157};
158
159} // namespace linalg
#define AK_ASSERT(x)
Definition assert.hpp:13
constexpr auto get_svec(const Mat &A)
get svec encoding of a symmetric matrix
SymmetricOperatorType
simple enum to define symmetric matrix types INV = Invalid IND = Indefinite PSD = Positive Semidefini...
constexpr std::size_t mat_rows_v
Registered compile-time row count after cv/ref normalization.
Endomorphism operator CRTP base.
matrix_scalar_t< Mat > T
alias helpers for types
static constexpr std::size_t N
helper to extract N
forward declaration for symmetric operator
constexpr auto operator()(std::size_t i, std::size_t j) const
get element at (i,j) index
constexpr bool is_ind() const
is indefinite
constexpr SymmetricOperator(const Mat &A)
CTOR.
constexpr bool is_nd() const
is nd check
static constexpr std::size_t DIM
helpers to get DIM from mat
SymmetricOperatorType type
member variables
constexpr bool is_pd() const
is pd check
constexpr std::size_t index(std::size_t i, std::size_t j) const
index from (row, col)
constexpr bool is_psd() const
is psd check
constexpr void compute_definiteness(const Vector< DiagT, N > &diag, const ScalarT &tol)
compute definiteness
constexpr bool is_nsd() const
is nsd check
constexpr const Derived & self() const
self
constexpr bool is_valid() const
is valid
Owning, fixed-size vector container.
Definition vector.hpp:36