EllAlgo 1.6.13
Loading...
Searching...
No Matches
ldlt_mgr.hpp
Go to the documentation of this file.
1
6// -*- coding: utf-8 -*-
7#pragma once
8
9#include <cassert> // for assert
10#include <cstddef> // for size_t
11#include <utility> // for pair
12#include <valarray>
13
14#include "../ell_matrix.hpp"
15
33class LDLTMgr {
34 using Vec = std::valarray<double>;
35 using Rng = std::pair<size_t, size_t>;
36
37 public:
38 Rng pos{0U, 0U};
40 size_t _n;
41
42 private:
43 Matrix T;
44
45 public:
51 explicit LDLTMgr(size_t N) : witness_vec(0.0, N), _n{N}, T{N} {}
52
53 LDLTMgr(const LDLTMgr&) = delete;
54 LDLTMgr& operator=(const LDLTMgr&) = delete;
55 LDLTMgr(LDLTMgr&&) = default;
57 ~LDLTMgr() = default;
58
73 template <typename Mat> auto factorize(const Mat& A) -> bool {
74 return this->factor([&A](size_t i, size_t j) { return A(i, j); });
75 }
76
86 template <typename Fn> auto factor(Fn get_matrix_elem) -> bool {
87 this->pos = {0U, 0U};
88 auto const& start = this->pos.first;
89 auto& stop = this->pos.second;
90
91 for (auto i = 0U; i != this->_n; ++i) {
92 auto d = get_matrix_elem(i, start);
93 for (auto j = start; j != i; ++j) {
94 this->T(j, i) = d;
95 this->T(i, j) = d / this->T(j, j); // note: T(j, i) here!
96 auto s = j + 1;
97 d = get_matrix_elem(i, s);
98 for (auto k = start; k != s; ++k) {
99 d -= this->T(i, k) * this->T(k, s);
100 }
101 }
102 this->T(i, i) = d;
103
104 if (d <= 0.0) {
105 stop = i + 1;
106 break;
107 }
108 }
109
110 return this->is_spd();
111 }
112
122 template <typename Fn> auto factor_with_allow_semidefinite(Fn get_matrix_elem) -> bool {
123 this->pos = {0U, 0U};
124 auto& start = this->pos.first;
125 auto& stop = this->pos.second;
126
127 for (auto i = 0U; i != this->_n; ++i) {
128 auto d = get_matrix_elem(i, start);
129 for (auto j = start; j != i; ++j) {
130 this->T(j, i) = d;
131 this->T(i, j) = d / this->T(j, j); // note: T(j, i) here!
132 auto s = j + 1;
133 d = get_matrix_elem(i, s);
134 for (auto k = start; k != s; ++k) {
135 d -= this->T(i, k) * this->T(k, s);
136 }
137 }
138 this->T(i, i) = d;
139
140 if (d < 0.0) {
141 stop = i + 1;
142 break;
143 }
144 if (d == 0.0) {
145 start = i + 1;
146 // restart at i + 1, special as an LMI oracle
147 }
148 }
149 return this->is_spd();
150 }
151
157 constexpr auto is_spd() const noexcept -> bool { return this->pos.second == 0; }
158
169 auto witness() -> double;
170
177 template <typename Arr036> auto set_witness_vec(Arr036& v) const -> void {
178 for (auto i = 0U; i != this->_n; ++i) {
179 v[i] = this->witness_vec[i];
180 }
181 }
182
190 template <typename Mat> auto sym_quad(const Mat& A) const -> double {
191 auto res = double{};
192 const auto& v = this->witness_vec;
193 // const auto& [start, stop] = this->pos;
194 const auto& start = this->pos.first;
195 const auto& stop = this->pos.second;
196 for (auto i = start; i != stop; ++i) {
197 auto s = 0.0;
198 for (auto j = i + 1; j != stop; ++j) {
199 s += A(i, j) * v[j];
200 }
201 res += v[i] * (A(i, i) * v[i] + 2.0 * s);
202 }
203 return res;
204 }
205
216 template <typename Mat> auto sqrt(Mat& M) -> void {
217 assert(this->is_spd());
218
219 for (auto i = 0U; i != this->_n; ++i) {
220 M(i, i) = std::sqrt(this->T(i, i));
221 for (auto j = i + 1; j != this->_n; ++j) {
222 M(i, j) = this->T(j, i) * M(i, i);
223 M(j, i) = 0.0;
224 }
225 }
226 }
227};
LDLT factorization.
Definition ldlt_mgr.hpp:33
auto witness() -> double
witness that certifies $A$ is not symmetric positive definite (spd)
LDLTMgr(LDLTMgr &&)=default
LDLTMgr & operator=(const LDLTMgr &)=delete
auto factorize(const Mat &A) -> bool
Perform LDLT Factorization.
Definition ldlt_mgr.hpp:73
LDLTMgr(const LDLTMgr &)=delete
auto set_witness_vec(Arr036 &v) const -> void
Set the witness vec object.
Definition ldlt_mgr.hpp:177
LDLTMgr(size_t N)
Construct a new ldlt ext object.
Definition ldlt_mgr.hpp:51
auto sqrt(Mat &M) -> void
Return upper triangular matrix $R$ where $A = R^T R$.
Definition ldlt_mgr.hpp:216
LDLTMgr & operator=(LDLTMgr &&)=delete
auto factor_with_allow_semidefinite(Fn get_matrix_elem) -> bool
Perform LDLT Factorization (Lazy evaluation)
Definition ldlt_mgr.hpp:122
Rng pos
the rows where the process starts and stops
Definition ldlt_mgr.hpp:38
constexpr auto is_spd() const noexcept -> bool
Check if the matrix is symmetric positive definite.
Definition ldlt_mgr.hpp:157
auto factor(Fn get_matrix_elem) -> bool
Perform LDLT Factorization (Lazy evaluation)
Definition ldlt_mgr.hpp:86
size_t _n
dimension
Definition ldlt_mgr.hpp:40
Vec witness_vec
witness vector
Definition ldlt_mgr.hpp:39
~LDLTMgr()=default
auto sym_quad(const Mat &A) const -> double
Calculate v'*{A}(pos,pos)*v.
Definition ldlt_mgr.hpp:190
Square matrix with flat std::vector<double> storage.
Definition ell_matrix.hpp:63
auto invalid_value() -> T
Return an invalid/sentinel value for type T.
Definition cutting_plane.hpp:27