alpaqa pantr
Nonconvex constrained optimization
Loading...
Searching...
No Matches
box.hpp
Go to the documentation of this file.
1#pragma once
2
5
6namespace alpaqa {
7
8template <Config Conf = DefaultConfig>
9struct Box {
11
12 Box() : Box{0} {}
14 : lowerbound{vec::Constant(n, -inf<config_t>)}, upperbound{
15 vec::Constant(n, +inf<config_t>)} {}
16
17 static Box NaN(length_t n) {
18 return Box{vec::Constant(n, alpaqa::NaN<config_t>),
19 vec::Constant(n, alpaqa::NaN<config_t>)};
20 }
21 static Box from_lower_upper(vec lower, vec upper) {
22 return Box{std::move(lower), std::move(upper)};
23 }
24
27
28 private:
29 Box(vec lower, vec upper) : lowerbound{std::move(lower)}, upperbound{std::move(upper)} {}
30};
31
32/// Project a vector onto a box.
33/// @f[ \Pi_C(v) @f]
34template <Config Conf>
35inline auto project(const auto &v, ///< [in] The vector to project
36 const Box<Conf> &box ///< [in] The box to project onto
37) {
39 using binary_real_f = real_t (*)(real_t, real_t);
40 return v.binaryExpr(box.lowerbound, binary_real_f(std::fmax))
41 .binaryExpr(box.upperbound, binary_real_f(std::fmin));
42}
43
44/// Get the difference between the given vector and its projection.
45/// @f[ v - \Pi_C(v) @f]
46/// @warning Beware catastrophic cancellation!
47template <Config Conf>
48inline auto //
49projecting_difference(const auto &v, ///< [in] The vector to project
50 const Box<Conf> &box ///< [in] The box to project onto
51) {
52 return v - project(v, box);
53}
54
55/// Get the distance squared between the given vector and its projection.
56/// @f[ \left\| v - \Pi_C(v) \right\|_2^2 @f]
57/// @warning Beware catastrophic cancellation!
58
59template <Config Conf>
60inline auto dist_squared(const auto &v, ///< [in] The vector to project
61 const Box<Conf> &box ///< [in] The box to project onto
62) {
63 return projecting_difference(v, box).squaredNorm();
64}
65
66/// Get the distance squared between the given vector and its projection in the
67/// Σ norm.
68/// @f[ \left\| v - \Pi_C(v) \right\|_\Sigma^2
69/// = \left(v - \Pi_C(v)\right)^\top \Sigma \left(v - \Pi_C(v)\right) @f]
70/// @warning Beware catastrophic cancellation!
71template <Config Conf>
72inline auto dist_squared(const auto &v, ///< [in] The vector to project
73 const Box<Conf> &box, ///< [in] The box to project onto
74 const auto///< [in] Diagonal matrix defining norm
75 ) -> real_t<Conf> {
76 // TODO: Does this allocate?
77 // Does it have dangling references to temporaries?
78 auto d = v - project(v, box);
79 return d.dot(Σ.asDiagonal() * d);
80}
81
82} // namespace alpaqa
#define USING_ALPAQA_CONFIG(Conf)
Definition: config.hpp:42
auto projecting_difference(const auto &v, const Box< Conf > &box)
Get the difference between the given vector and its projection.
Definition: box.hpp:49
typename Conf::real_t real_t
Definition: config.hpp:51
typename Conf::length_t length_t
Definition: config.hpp:62
constexpr const auto inf
Definition: config.hpp:69
typename Conf::vec vec
Definition: config.hpp:52
auto project(const auto &v, const Box< Conf > &box)
Project a vector onto a box.
Definition: box.hpp:35
auto dist_squared(const auto &v, const Box< Conf > &box)
Get the distance squared between the given vector and its projection.
Definition: box.hpp:60
static Box from_lower_upper(vec lower, vec upper)
Definition: box.hpp:21
Box(vec lower, vec upper)
Definition: box.hpp:29
vec upperbound
Definition: box.hpp:26
static Box NaN(length_t n)
Definition: box.hpp:17
vec lowerbound
Definition: box.hpp:25
Box(length_t n)
Definition: box.hpp:13