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
21template <typename Scalar>
22bool is_equality_locally_infeasible(
23 const Eigen::SparseMatrix<Scalar>& A_e,
24 const Eigen::Vector<Scalar, Eigen::Dynamic>& c_e) {
25 // The equality constraints are locally infeasible if
26 //
27 // Aₑᵀcₑ → 0
28 // ‖cₑ‖ > ε
29 //
30 // See "Infeasibility detection" in section 6 of [3].
31 return A_e.rows() > 0 && (A_e.transpose() * c_e).norm() < Scalar(1e-6) &&
32 c_e.norm() > Scalar(1e-2);
33}
34
44template <typename Scalar>
45bool is_inequality_locally_infeasible(
46 const Eigen::SparseMatrix<Scalar>& A_i,
47 const Eigen::Vector<Scalar, Eigen::Dynamic>& c_i) {
48 // The inequality constraints are locally infeasible if
49 //
50 // Aᵢᵀcᵢ⁺ → 0
51 // ‖cᵢ⁺‖ > ε
52 //
53 // where cᵢ⁺ = min(cᵢ, 0).
54 //
55 // See "Infeasibility detection" in section 6 of [3].
56 //
57 // cᵢ⁺ is used instead of cᵢ⁻ from the paper to follow the convention that
58 // feasible inequality constraints are ≥ 0.
59 if (A_i.rows() > 0) {
60 Eigen::Vector<Scalar, Eigen::Dynamic> c_i_plus = c_i.cwiseMin(Scalar(0));
61 if ((A_i.transpose() * c_i_plus).norm() < Scalar(1e-6) &&
62 c_i_plus.norm() > Scalar(1e-6)) {
63 return true;
64 }
65 }
66
67 return false;
68}
69
70} // namespace slp