cyqlone develop
Fast, parallel and vectorized solver for linear systems with optimal control structure.
Loading...
Searching...
No Matches
breakpoint.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cyqlone/config.hpp>
5#include <guanaqo/tag-invoke.hpp>
6#include <span>
7#include <vector>
8#if CYQLONE_QUADRUPLE_SUM_LINE_SEARCH
9#include <stdfloat>
10#endif
11
12namespace CYQLONE_NS(cyqlone::qpalm) {
13
14/// @todo store t and δ|δ| instead of t and δ.
15struct Breakpoint {
16 // t = α/δ <=> α = t δ
17 real_t t, δ;
18 [[gnu::always_inline, nodiscard]] real_t α() const { return t * δ; }
19};
20
21#if CYQLONE_QUADRUPLE_SUM_LINE_SEARCH
22using ABSum_t = std::float128_t;
23#elif CYQLONE_COMPENSATE_SUM_LINE_SEARCH
24using ABSum_t = NeumaierSum<real_t>;
25#else
26using ABSum_t = real_t;
27#endif
28
29struct ABSums {
31 constexpr friend ABSums operator+(const ABSums &lhs, const ABSums &rhs) {
32 return {.a = lhs.a + rhs.a, .b = lhs.b + rhs.b};
33 }
34};
35
37 std::span<Breakpoint> neg_bp, pos_bp;
38};
39
40ABSums partial_sum_negative(PartitionedBreakpoints breakpoints, real_t η = 0, real_t β = 0);
41
46
47/// Compute the break points t[i] using formula (3.6) in the QPALM paper.
48/// @return t, α, δ
49template <class Vec>
50std::span<Breakpoint>
51compute_breakpoints_default(std::vector<Breakpoint> &breakpoints, const Vec &Σ, const Vec &y,
52 const Vec &Ad, const Vec &Ax, const Vec &b_min, const Vec &b_max);
53
54/// Moves any non-finite elements in t to the end of the range, and all negative
55/// elements to the front. Returns the negative and positive partitions.
56PartitionedBreakpoints partition_breakpoints_default(std::span<Breakpoint> breakpoints);
57
59 template <class Backend>
60 using vec_t = typename std::remove_cvref_t<Backend>::ineq_constr_vec_t;
61
62 template <class Backend>
63 // The compute_breakpoints type should opt in to the tag to provide a custom
64 // implementation.
66 typename Backend::Context &, std::vector<Breakpoint> &,
67 const vec_t<Backend> &, const vec_t<Backend> &,
68 const vec_t<Backend> &, const vec_t<Backend> &,
69 const vec_t<Backend> &, const vec_t<Backend> &>)
70 auto operator()(Backend &backend, typename Backend::Context &ctx,
71 std::vector<Breakpoint> &breakpoints, const vec_t<Backend> &Σ,
72 const vec_t<Backend> &y, const vec_t<Backend> &Ad, const vec_t<Backend> &Ax,
73 const vec_t<Backend> &b_min, const vec_t<Backend> &b_max) const
75 compute_breakpoints_fn, Backend &, typename Backend::Context &,
76 std::vector<Breakpoint> &, const vec_t<Backend> &, const vec_t<Backend> &,
77 const vec_t<Backend> &, const vec_t<Backend> &, const vec_t<Backend> &,
78 const vec_t<Backend> &>) {
79 return guanaqo::guanaqo_tag_invoke(*this, backend, ctx, breakpoints, Σ, y, Ad, Ax, b_min,
80 b_max);
81 }
82
83 template <class Backend>
84 // Fallback implementation for unknown backends
86 typename Backend::Context &, std::vector<Breakpoint> &,
87 const vec_t<Backend> &, const vec_t<Backend> &,
88 const vec_t<Backend> &, const vec_t<Backend> &,
89 const vec_t<Backend> &, const vec_t<Backend> &>)
90 auto operator()(Backend &, typename Backend::Context &ctx, std::vector<Breakpoint> &breakpoints,
91 const vec_t<Backend> &Σ, const vec_t<Backend> &y, const vec_t<Backend> &Ad,
92 const vec_t<Backend> &Ax, const vec_t<Backend> &b_min,
93 const vec_t<Backend> &b_max) const {
94 ctx.arrive_and_wait();
95 return ctx.call_broadcast(
96 [&] { return compute_breakpoints_default(breakpoints, Σ, y, Ad, Ax, b_min, b_max); });
97 }
98} inline constexpr compute_breakpoints;
99
101 template <class Backend>
102 using vec_t = typename std::remove_cvref_t<Backend>::ineq_constr_vec_t;
103
104 template <class Backend>
105 // The get_partitioned_breakpoints type should opt in to the tag to provide a custom
106 // implementation.
108 typename Backend::Context &, std::vector<Breakpoint> &,
109 const vec_t<Backend> &, const vec_t<Backend> &,
110 const vec_t<Backend> &, const vec_t<Backend> &,
111 const vec_t<Backend> &, const vec_t<Backend> &>)
112 PartitionedBreakpoints operator()(Backend &backend, typename Backend::Context &ctx,
113 std::vector<Breakpoint> &breakpoints, const vec_t<Backend> &Σ,
114 const vec_t<Backend> &y, const vec_t<Backend> &Ad,
115 const vec_t<Backend> &Ax, const vec_t<Backend> &b_min,
116 const vec_t<Backend> &b_max) const
118 get_partitioned_breakpoints_fn, Backend &, typename Backend::Context &,
119 std::vector<Breakpoint> &, const vec_t<Backend> &, const vec_t<Backend> &,
120 const vec_t<Backend> &, const vec_t<Backend> &, const vec_t<Backend> &,
121 const vec_t<Backend> &>) {
122 return guanaqo::guanaqo_tag_invoke(*this, backend, ctx, breakpoints, Σ, y, Ad, Ax, b_min,
123 b_max);
124 }
125
126 template <class Backend>
127 // Fallback implementation for unknown backends
129 typename Backend::Context &, std::vector<Breakpoint> &,
130 const vec_t<Backend> &, const vec_t<Backend> &,
131 const vec_t<Backend> &, const vec_t<Backend> &,
132 const vec_t<Backend> &, const vec_t<Backend> &>)
133 PartitionedBreakpoints operator()(Backend &backend, typename Backend::Context &ctx,
134 std::vector<Breakpoint> &breakpoints, const vec_t<Backend> &Σ,
135 const vec_t<Backend> &y, const vec_t<Backend> &Ad,
136 const vec_t<Backend> &Ax, const vec_t<Backend> &b_min,
137 const vec_t<Backend> &b_max) const {
138 auto bp = compute_breakpoints(backend, ctx, breakpoints, Σ, y, Ad, Ax, b_min, b_max);
139 // Assume that compute_breakpoints already synchronized
140 return ctx.call_broadcast([&] { return partition_breakpoints_default(bp); });
141 }
142} inline constexpr get_partitioned_breakpoints;
143
145 template <class Backend>
146 using vec_t = typename std::remove_cvref_t<Backend>::ineq_constr_vec_t;
147
148 template <class Backend>
149 // The get_breakpoints type should opt in to the tag to provide a custom
150 // implementation.
151 requires(guanaqo::tag_invocable<get_breakpoints_fn, Backend &, typename Backend::Context &,
152 std::vector<Breakpoint> &, const vec_t<Backend> &,
153 const vec_t<Backend> &, const vec_t<Backend> &,
154 const vec_t<Backend> &, const vec_t<Backend> &,
155 const vec_t<Backend> &>)
156 auto operator()(Backend &backend, typename Backend::Context &ctx,
157 std::vector<Breakpoint> &breakpoints, const vec_t<Backend> &Σ,
158 const vec_t<Backend> &y, const vec_t<Backend> &Ad, const vec_t<Backend> &Ax,
159 const vec_t<Backend> &b_min, const vec_t<Backend> &b_max) const
161 get_breakpoints_fn, Backend &, typename Backend::Context &,
162 std::vector<Breakpoint> &, const vec_t<Backend> &, const vec_t<Backend> &,
163 const vec_t<Backend> &, const vec_t<Backend> &, const vec_t<Backend> &,
164 const vec_t<Backend> &>) {
165 return guanaqo::guanaqo_tag_invoke(*this, backend, ctx, breakpoints, Σ, y, Ad, Ax, b_min,
166 b_max);
167 }
168
169 template <class Backend>
170 // Fallback implementation for unknown backends
171 requires(!guanaqo::tag_invocable<get_breakpoints_fn, Backend &, typename Backend::Context &,
172 std::vector<Breakpoint> &, const vec_t<Backend> &,
173 const vec_t<Backend> &, const vec_t<Backend> &,
174 const vec_t<Backend> &, const vec_t<Backend> &,
175 const vec_t<Backend> &>)
176 BreakpointsResult operator()(Backend &backend, typename Backend::Context &ctx,
177 std::vector<Breakpoint> &breakpoints, const vec_t<Backend> &Σ,
178 const vec_t<Backend> &y, const vec_t<Backend> &Ad,
179 const vec_t<Backend> &Ax, const vec_t<Backend> &b_min,
180 const vec_t<Backend> &b_max) const {
181 auto bp =
182 get_partitioned_breakpoints(backend, ctx, breakpoints, Σ, y, Ad, Ax, b_min, b_max);
183 return {.bp = bp, .ab_neg = partial_sum_negative(bp)};
184 }
185} inline constexpr get_breakpoints;
186
187} // namespace CYQLONE_NS(cyqlone::qpalm)
Kahan-Babuška-Neumaier compensated summation.
Definition neumaier.hpp:16
#define CYQLONE_NS(ns)
Definition config.hpp:10
constexpr bool is_nothrow_tag_invocable_v
struct cyqlone::qpalm::get_partitioned_breakpoints_fn get_partitioned_breakpoints
ABSums partial_sum_negative(PartitionedBreakpoints breakpoints, real_t η=0, real_t β=0)
PartitionedBreakpoints partition_breakpoints_default(std::span< Breakpoint > breakpoints)
Moves any non-finite elements in t to the end of the range, and all negative elements to the front.
Definition breakpoint.cpp:7
struct cyqlone::qpalm::compute_breakpoints_fn compute_breakpoints
PartitionedBreakpoints bp
std::span< Breakpoint > compute_breakpoints_default(std::vector< Breakpoint > &breakpoints, const Vec &Σ, const Vec &y, const Vec &Ad, const Vec &Ax, const Vec &b_min, const Vec &b_max)
Compute the break points t[i] using formula (3.6) in the QPALM paper.
Kahan-Babuška-Neumaier compensated summation.
constexpr friend ABSums operator+(const ABSums &lhs, const ABSums &rhs)
typename std::remove_cvref_t< Backend >::ineq_constr_vec_t vec_t
typename std::remove_cvref_t< Backend >::ineq_constr_vec_t vec_t
typename std::remove_cvref_t< Backend >::ineq_constr_vec_t vec_t