Sleipnir C++ API
Loading...
Searching...
No Matches
filter.hpp
1// Copyright (c) Sleipnir contributors
2
3#pragma once
4
5#include <algorithm>
6#include <cmath>
7#include <limits>
8#include <utility>
9
10#include <Eigen/Core>
11#include <gch/small_vector.hpp>
12
13// See docs/algorithms.md#Works_cited for citation definitions.
14
15namespace slp {
16
20template <typename Scalar>
23 using DenseVector = Eigen::Vector<Scalar, Eigen::Dynamic>;
24
26 Scalar cost{0};
27
30
31 constexpr FilterEntry() = default;
32
39
43 explicit FilterEntry(Scalar f) : FilterEntry{f, Scalar(0)} {}
44
49 FilterEntry(Scalar f, const DenseVector& c_e)
50 : FilterEntry{f, c_e.template lpNorm<1>()} {}
51
59 FilterEntry(Scalar f, DenseVector& s, const DenseVector& c_e,
60 const DenseVector& c_i, Scalar μ)
61 : FilterEntry{f - μ * s.array().log().sum(),
62 c_e.template lpNorm<1>() + (c_i - s).template lpNorm<1>()} {
63 }
64
69 constexpr bool dominated_by(const FilterEntry<Scalar>& entry) const {
70 return entry.cost <= cost &&
71 entry.constraint_violation <= constraint_violation;
72 }
73};
74
80template <typename Scalar>
81class Filter {
82 public:
84 static constexpr Scalar min_constraint_violation{1e-4};
85
88
91 // Initial filter entry rejects constraint violations above max
92 m_filter.emplace_back(std::numeric_limits<Scalar>::infinity(),
94 }
95
97 void reset() {
98 m_filter.clear();
99
100 // Initial filter entry rejects constraint violations above max
101 m_filter.emplace_back(std::numeric_limits<Scalar>::infinity(),
103 }
104
109 // Remove dominated entries
110 erase_if(m_filter,
111 [&](const auto& elem) { return elem.dominated_by(entry); });
112
113 m_filter.push_back(entry);
114 }
115
120 // Remove dominated entries
121 erase_if(m_filter,
122 [&](const auto& elem) { return elem.dominated_by(entry); });
123
124 m_filter.push_back(entry);
125 }
126
132 bool try_add(const FilterEntry<Scalar>& entry, Scalar α) {
133 if (is_acceptable(entry, α)) {
134 add(entry);
135 return true;
136 } else {
137 return false;
138 }
139 }
140
147 if (is_acceptable(entry, α)) {
148 add(std::move(entry));
149 return true;
150 } else {
151 return false;
152 }
153 }
154
161 using std::isfinite;
162 using std::pow;
163
164 if (!isfinite(entry.cost) || !isfinite(entry.constraint_violation)) {
165 return false;
166 }
167
168 // If current filter entry is better than all prior ones in some respect,
169 // accept it.
170 //
171 // See equation (2.13) of [4].
172 Scalar ϕ = pow(α, Scalar(1.5));
173 if (entry.constraint_violation <= min_constraint_violation) {
174 // Accept only optimality improvement when constraint violation is low
175 return std::ranges::all_of(m_filter, [&](const auto& elem) {
176 return entry.cost <= elem.cost - ϕ * γ_cost * elem.constraint_violation;
177 });
178 } else {
179 // Accept either optimality or constraint violation improvement
180 return std::ranges::all_of(m_filter, [&](const auto& elem) {
181 return entry.cost <=
182 elem.cost - ϕ * γ_cost * elem.constraint_violation ||
183 entry.constraint_violation <=
184 (Scalar(1) - ϕ * γ_constraint) * elem.constraint_violation;
185 });
186 }
187 }
188
192 const FilterEntry<Scalar>& back() const { return m_filter.back(); }
193
194 private:
195 static constexpr Scalar γ_cost{1e-8};
196 static constexpr Scalar γ_constraint{1e-5};
197
198 gch::small_vector<FilterEntry<Scalar>> m_filter;
199};
200
201} // namespace slp
Definition filter.hpp:81
void add(const FilterEntry< Scalar > &entry)
Definition filter.hpp:108
const FilterEntry< Scalar > & back() const
Definition filter.hpp:192
bool is_acceptable(const FilterEntry< Scalar > &entry, Scalar α)
Definition filter.hpp:160
Filter()
Constructs an empty filter.
Definition filter.hpp:90
bool try_add(const FilterEntry< Scalar > &entry, Scalar α)
Definition filter.hpp:132
static constexpr Scalar min_constraint_violation
The minimum constraint violation.
Definition filter.hpp:84
bool try_add(FilterEntry< Scalar > &&entry, Scalar α)
Definition filter.hpp:146
Scalar max_constraint_violation
The maximum constraint violation.
Definition filter.hpp:87
void reset()
Resets the filter.
Definition filter.hpp:97
void add(FilterEntry< Scalar > &&entry)
Definition filter.hpp:119
Definition intrusive_shared_ptr.hpp:27
Definition filter.hpp:21
FilterEntry(Scalar f)
Definition filter.hpp:43
Scalar cost
The cost function's value.
Definition filter.hpp:26
FilterEntry(Scalar f, DenseVector &s, const DenseVector &c_e, const DenseVector &c_i, Scalar μ)
Definition filter.hpp:59
constexpr bool dominated_by(const FilterEntry< Scalar > &entry) const
Definition filter.hpp:69
Eigen::Vector< Scalar, Eigen::Dynamic > DenseVector
Type alias for dense vector.
Definition filter.hpp:23
Scalar constraint_violation
The constraint violation.
Definition filter.hpp:29
constexpr FilterEntry(Scalar cost, Scalar constraint_violation)
Definition filter.hpp:37
FilterEntry(Scalar f, const DenseVector &c_e)
Definition filter.hpp:49