Sleipnir C++ API
Loading...
Searching...
No Matches
is_locally_infeasible.hpp
1// Copyright (c) Sleipnir contributors
2
3#pragma once
4
5#include <Eigen/Core>
6#include <Eigen/SparseCore>
7
8// See docs/algorithms.md#Works_cited for citation definitions
9
10namespace slp {
11
17template <typename Scalar>
18bool is_equality_locally_infeasible(
19 const Eigen::SparseMatrix<Scalar>& A_e,
20 const Eigen::Vector<Scalar, Eigen::Dynamic>& c_e) {
21 // The equality constraints are locally infeasible if
22 //
23 // Aₑᵀcₑ → 0
24 // ‖cₑ‖ > ε
25 //
26 // See "Infeasibility detection" in section 6 of [3].
27 return A_e.rows() > 0 && (A_e.transpose() * c_e).norm() < Scalar(1e-6) &&
28 c_e.norm() > Scalar(1e-2);
29}
30
36template <typename Scalar>
37bool is_inequality_locally_infeasible(
38 const Eigen::SparseMatrix<Scalar>& A_i,
39 const Eigen::Vector<Scalar, Eigen::Dynamic>& c_i) {
40 // The inequality constraints are locally infeasible if
41 //
42 // Aᵢᵀcᵢ⁺ → 0
43 // ‖cᵢ⁺‖ > ε
44 //
45 // where cᵢ⁺ = min(cᵢ, 0).
46 //
47 // See "Infeasibility detection" in section 6 of [3].
48 //
49 // cᵢ⁺ is used instead of cᵢ⁻ from the paper to follow the convention that
50 // feasible inequality constraints are ≥ 0.
51 if (A_i.rows() > 0) {
52 Eigen::Vector<Scalar, Eigen::Dynamic> c_i_plus = c_i.cwiseMin(Scalar(0));
53 if ((A_i.transpose() * c_i_plus).norm() < Scalar(1e-6) &&
54 c_i_plus.norm() > Scalar(1e-6)) {
55 return true;
56 }
57 }
58
59 return false;
60}
61
62} // namespace slp