41 Eigen::ComputationInfo
info()
const {
return m_info; }
54 m_is_sparse =
lhs.nonZeros() < 0.25 *
lhs.size();
56 m_info = m_is_sparse ? compute_sparse(
lhs).info()
57 : m_dense_solver.compute(
lhs).info();
61 if (m_info == Eigen::Success) {
63 :
Inertia{m_dense_solver.vectorD()};
76 Scalar
δ = m_prev_δ == Scalar(0) ? Scalar(1
e-4) : m_prev_δ / Scalar(2);
85 m_info = compute_sparse(
lhs + regularization(
δ,
γ)).info();
86 if (m_info == Eigen::Success) {
90 m_info = m_dense_solver.compute(
lhs + regularization(
δ,
γ)).info();
91 if (m_info == Eigen::Success) {
96 if (m_info == Eigen::Success) {
124 if (
δ > Scalar(1
e20) ||
γ > Scalar(1
e20)) {
125 m_info = Eigen::NumericalIssue;
137 template <
typename Rhs>
138 Eigen::Vector<Scalar, Eigen::Dynamic>
solve(
139 const Eigen::MatrixBase<Rhs>&
rhs) {
141 return m_sparse_solver.solve(
rhs);
143 return m_dense_solver.solve(
rhs);
153 template <
typename Rhs>
154 Eigen::Vector<Scalar, Eigen::Dynamic>
solve(
155 const Eigen::SparseMatrixBase<Rhs>&
rhs) {
157 return m_sparse_solver.solve(
rhs);
159 return m_dense_solver.solve(
rhs.toDense());
171 using SparseSolver = Eigen::SimplicialLDLT<Eigen::SparseMatrix<Scalar>>;
173 Eigen::LDLT<Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>>;
175 SparseSolver m_sparse_solver;
176 DenseSolver m_dense_solver;
177 bool m_is_sparse =
true;
179 Eigen::ComputationInfo m_info = Eigen::Success;
182 int m_num_decision_variables = 0;
185 int m_num_equality_constraints = 0;
188 Inertia ideal_inertia{m_num_decision_variables, m_num_equality_constraints,
195 int m_non_zeros = -1;
203 SparseSolver& compute_sparse(
const Eigen::SparseMatrix<Scalar>& lhs) {
205 int non_zeros = lhs.nonZeros();
206 if (m_non_zeros != non_zeros) {
207 m_sparse_solver.analyzePattern(lhs);
208 m_non_zeros = non_zeros;
211 m_sparse_solver.factorize(lhs);
213 return m_sparse_solver;
223 Eigen::SparseMatrix<Scalar> regularization(Scalar δ, Scalar γ) {
224 Eigen::Vector<Scalar, Eigen::Dynamic> vec{m_num_decision_variables +
225 m_num_equality_constraints};
226 vec.segment(0, m_num_decision_variables).setConstant(δ);
227 vec.segment(m_num_decision_variables, m_num_equality_constraints)
230 return Eigen::SparseMatrix<Scalar>{vec.asDiagonal()};