9#include <Eigen/Cholesky>
12#include "sleipnir/optimization/solver/util/inertia.hpp"
21template <
typename Scalar>
36 : m_num_decision_variables{num_decision_variables},
37 m_num_equality_constraints{num_equality_constraints} {}
48 : m_num_decision_variables{num_decision_variables},
49 m_num_equality_constraints{num_equality_constraints},
55 Eigen::ComputationInfo
info()
const {
return m_info; }
65 m_info = m_solver.compute(m_lhs).info();
66 if (m_info == Eigen::Success && inertia() == ideal_inertia) {
76 constexpr Scalar δ_min(1e-10);
80 constexpr Scalar γ_max(1e-8);
83 constexpr Scalar γ_initial(1e-10);
93 Scalar δ = m_prev_δ == Scalar(0) ? Scalar(1e-4)
94 : std::max(m_prev_δ / Scalar(2), δ_min);
101 m_lhs = lhs + regularization(δ, γ);
102 m_info = m_solver.compute(m_lhs).info();
104 if (m_info == Eigen::Success) {
105 Inertia inertia = this->inertia();
107 if (inertia == ideal_inertia) {
112 }
else if (inertia.
zero > 0) {
113 if (γ == Scalar(0)) {
121 γ = std::min(γ * Scalar(10), γ_max);
138 γ = std::min(γ * Scalar(10), γ_max);
144 γ = γ == Scalar(0) ? γ_initial : std::min(γ * Scalar(10), γ_max);
149 if (δ > Scalar(1e20) || γ > Scalar(1e20)) {
150 m_info = Eigen::NumericalIssue;
162 template <
typename Rhs>
169 constexpr int max_refinement_steps = 3;
170 for (
int i = 0; i < max_refinement_steps; ++i) {
171 DenseVector r = rhs - m_lhs.template selfadjointView<Eigen::Lower>() * x;
172 if (r.norm() <= Scalar(1e-12) * rhs.norm()) {
175 x += m_solver.solve(r);
185 template <
typename Rhs>
187 return solve(rhs.toDense());
201 using Solver = Eigen::BunchKaufman<DenseMatrix>;
208 Eigen::ComputationInfo m_info = Eigen::Success;
211 int m_num_decision_variables = 0;
214 int m_num_equality_constraints = 0;
217 Scalar m_γ_min{1e-10};
220 Inertia ideal_inertia{m_num_decision_variables, m_num_equality_constraints,
237 Inertia inertia()
const {
241 constexpr Scalar ε = std::numeric_limits<Scalar>::epsilon();
243 const auto D = m_solver.vectorD();
244 const auto& D_sub = m_solver.subDiagonal();
247 auto count = [&](Scalar λ) {
257 for (
int k = 0; k < D.size(); ++k) {
258 if (k + 1 < D.size() && D_sub[k] != Scalar(0)) {
261 const Scalar a = D[k];
262 const Scalar b = D_sub[k];
263 const Scalar c = D[k + 1];
264 const Scalar mid = (a + c) / Scalar(2);
265 const Scalar r = hypot((a - c) / Scalar(2), abs(b));
285 DenseMatrix regularization(Scalar δ, Scalar γ)
const {
286 DenseVector vec{m_num_decision_variables + m_num_equality_constraints};
287 vec.segment(0, m_num_decision_variables).setConstant(δ);
288 vec.segment(m_num_decision_variables, m_num_equality_constraints)
291 return vec.asDiagonal().toDenseMatrix();
Definition dense_kkt_solver.hpp:22
Scalar constraint_jacobian_regularization() const
Definition dense_kkt_solver.hpp:198
DenseKKTSolver(int num_decision_variables, int num_equality_constraints, Scalar γ_min)
Definition dense_kkt_solver.hpp:46
Scalar hessian_regularization() const
Definition dense_kkt_solver.hpp:193
Eigen::ComputationInfo info() const
Definition dense_kkt_solver.hpp:55
DenseKKTSolver(int num_decision_variables, int num_equality_constraints)
Definition dense_kkt_solver.hpp:35
Eigen::VectorX< Scalar > DenseVector
Type alias for dense vector.
Definition dense_kkt_solver.hpp:27
Eigen::MatrixX< Scalar > DenseMatrix
Type alias for dense matrix.
Definition dense_kkt_solver.hpp:25
DenseVector solve(const Eigen::SparseMatrixBase< Rhs > &rhs) const
Definition dense_kkt_solver.hpp:186
DenseVector solve(const Eigen::MatrixBase< Rhs > &rhs) const
Definition dense_kkt_solver.hpp:163
DenseKKTSolver & compute(const DenseMatrix &lhs)
Definition dense_kkt_solver.hpp:61
Definition inertia.hpp:11
int zero
The number of zero eigenvalues.
Definition inertia.hpp:18
int positive
The number of positive eigenvalues.
Definition inertia.hpp:14
int negative
The number of negative eigenvalues.
Definition inertia.hpp:16