alpaqa cmake-targets
Nonconvex constrained optimization
Loading...
Searching...
No Matches
params.cpp
Go to the documentation of this file.
2
7#include <fstream>
8
10
22#include <alpaqa/outer/alm.hpp>
23#if ALPAQA_WITH_OCP
25#endif
26
27namespace alpaqa::params {
28
29template <>
32 if (s.value == "0" || s.value == "false")
33 b = false;
34 else if (s.value == "1" || s.value == "true")
35 b = true;
36 else
37 throw std::invalid_argument(
38 "Invalid value '" + std::string(s.value) +
39 "' for type 'bool' in '" + std::string(s.full_key) +
40 "',\n "
41 "possible values are: '0', '1', 'true', 'false'");
42}
43
44template <>
45void ALPAQA_EXPORT set_param(std::string_view &v, ParamString s) {
47 v = s.value;
48}
49
50template <>
51void ALPAQA_EXPORT set_param(std::string &v, ParamString s) {
53 v = s.value;
54}
55
56template <class T>
57 requires((std::floating_point<T> || std::integral<T>) &&
58 !std::is_enum_v<T> && !std::is_same_v<T, bool>)
59void set_param(T &f, ParamString s) {
61 const auto *val_end = s.value.data() + s.value.size();
62 auto res = util::from_chars(s.value.data(), val_end, f);
63 if (res.ec != std::errc())
64 throw std::invalid_argument(
65 "Invalid value '" + std::string(s.value) + "' for type '" +
66 demangled_typename(typeid(T)) + "' in '" + std::string(s.full_key) +
67 "': " + std::make_error_code(res.ec).message());
68 if (res.ptr != val_end)
69 throw std::invalid_argument(
70 "Invalid suffix '" + std::string(res.ptr, val_end) +
71 "' for type '" + demangled_typename(typeid(T)) + "' in '" +
72 std::string(s.full_key) + "'");
73}
74
75#ifdef ALPAQA_WITH_QUAD_PRECISION
76template <>
77void ALPAQA_EXPORT set_param(__float128 &f, ParamString s) {
78 long double ld;
79 set_param(ld, s);
80 f = static_cast<__float128>(ld);
81}
82#endif
83
84template <>
86 v.resize(std::count(s.value.begin(), s.value.end(), ',') + 1);
87 std::string_view value, remainder = s.value;
88 for (auto &e : v) {
89 std::tie(value, remainder) = split_key(remainder, ',');
90 set_param(e, {.full_key = s.full_key, .key = "", .value = value});
91 }
92}
93
94template <>
97 if (s.value.starts_with('@')) {
98 std::string fpath{s.value.substr(1)};
99 std::ifstream f(fpath);
100 if (!f)
101 throw std::invalid_argument("Unable to open file '" + fpath +
102 "' in '" + std::string(s.full_key) +
103 '\'');
104 try {
105 auto r = alpaqa::csv::read_row_std_vector<real_t<config_t>>(f);
106 auto r_size = static_cast<length_t<config_t>>(r.size());
107 if (v.expected_size >= 0 && r_size != v.expected_size)
108 throw std::invalid_argument(
109 "Incorrect size in '" + std::string(s.full_key) +
110 "' (expected " + std::to_string(v.expected_size) +
111 ", but got " + std::to_string(r.size()) + ')');
112 v.value.emplace(cmvec<config_t>{r.data(), r_size});
113 } catch (alpaqa::csv::read_error &e) {
114 throw std::invalid_argument(
115 "Unable to read from file '" + fpath + "' in '" +
116 std::string(s.full_key) +
117 "': alpaqa::csv::read_error: " + e.what());
118 }
119 } else {
120 alpaqa::params::set_param(v.value.emplace(), s);
121 if (v.expected_size >= 0 && v.value->size() != v.expected_size)
122 throw std::invalid_argument(
123 "Incorrect size in '" + std::string(s.full_key) +
124 "' (expected " + std::to_string(v.expected_size) +
125 ", but got " + std::to_string(v.value->size()) + ')');
126 }
127}
128
129template <class T>
130inline constexpr bool is_duration = false;
131template <class Rep, class Period>
132inline constexpr bool is_duration<std::chrono::duration<Rep, Period>> = true;
133
134template <class Duration>
135 requires is_duration<Duration>
138 try {
139 util::parse_duration(t = {}, s.value);
140 } catch (util::invalid_duration_value &e) {
141 throw invalid_param(
142 "Invalid value '" + std::string(s.value) + "' for type '" +
143 demangled_typename(typeid(Duration)) + "': error at '" +
144 std::string(std::string_view(s.value.data(), e.result.ptr)));
145 } catch (util::invalid_duration_units &e) {
146 throw invalid_param("Invalid units '" + std::string(e.units) +
147 "' for type '" +
148 demangled_typename(typeid(Duration)) + "' in '" +
149 std::string(s.value) + "'");
150 }
151}
152
153template <>
155 if (s.value == "BasedOnExternalStepSize")
157 else if (s.value == "BasedOnCurvature")
159 else
160 throw std::invalid_argument("Invalid value '" + std::string(s.value) +
161 "' for type 'LBFGSStepSize' in '" +
162 std::string(s.full_key) + "'");
163}
164
165template <>
167 if (s.value == "ApproxKKT")
169 else if (s.value == "ApproxKKT2")
171 else if (s.value == "ProjGradNorm")
173 else if (s.value == "ProjGradNorm2")
175 else if (s.value == "ProjGradUnitNorm")
177 else if (s.value == "ProjGradUnitNorm2")
179 else if (s.value == "FPRNorm")
181 else if (s.value == "FPRNorm2")
183 else if (s.value == "Ipopt")
185 else if (s.value == "LBFGSBpp")
187 else
188 throw std::invalid_argument("Invalid value '" + std::string(s.value) +
189 "' for type 'PANOCStopCrit' in '" +
190 std::string(s.full_key) + "'");
191}
192
194
195template <class... Ts>
197
198#define ALPAQA_SET_PARAM_INST(...) \
199 template void ALPAQA_EXPORT set_param( \
200 util::possible_alias_t<__VA_ARGS__> &, ParamString)
201
204ALPAQA_SET_PARAM_INST(long double, double, float);
205
214
215// Here, we would like to instantiate alpaqa::params::set_param for all standard
216// integer types, but the issue is that they might not be distinct types:
217// For example, on some platforms, int32_t might be a weak alias to int, whereas
218// on other platforms, it could be a distinct type.
219// To resolve this issue, we use some metaprogramming to ensure distinct
220// instantiations with unique dummy types.
221#define ALPAQA_SET_PARAM_INST_INT(...) \
222 ALPAQA_SET_PARAM_INST(__VA_ARGS__, int8_t, uint8_t, int16_t, uint16_t, \
223 int32_t, int64_t, uint32_t, uint64_t)
224
228ALPAQA_SET_PARAM_INST_INT(long long, long, int, short);
229ALPAQA_SET_PARAM_INST_INT(ptrdiff_t, long long, long, int, short);
231ALPAQA_SET_PARAM_INST_INT(unsigned int, unsigned short);
232ALPAQA_SET_PARAM_INST_INT(unsigned long, unsigned int, unsigned short);
233ALPAQA_SET_PARAM_INST_INT(unsigned long long, unsigned long, unsigned int,
234 unsigned short);
235ALPAQA_SET_PARAM_INST_INT(size_t, unsigned long long, unsigned long,
236 unsigned int, unsigned short);
237
238ALPAQA_SET_PARAM_INST(std::chrono::nanoseconds);
239ALPAQA_SET_PARAM_INST(std::chrono::microseconds);
240ALPAQA_SET_PARAM_INST(std::chrono::milliseconds);
241ALPAQA_SET_PARAM_INST(std::chrono::seconds);
242ALPAQA_SET_PARAM_INST(std::chrono::minutes);
243ALPAQA_SET_PARAM_INST(std::chrono::hours);
244
259#if ALPAQA_WITH_OCP
261#endif
262
263} // namespace alpaqa::params
std::string demangled_typename(const std::type_info &t)
Get the pretty name of the given type as a string.
Parameters for the Augmented Lagrangian solver.
Definition alm.hpp:21
Parameters for the AndersonAccel class.
Definition anderson.hpp:15
Parameters for the AndersonDirection class.
Definition anderson.hpp:12
Tuning parameters for the FISTA algorithm.
Definition fista.hpp:25
Parameters for the LBFGSDirection class.
Definition lbfgs.hpp:12
Parameters for the LBFGS class.
Definition lbfgs.hpp:42
Parameters for the NewtonTRDirection class.
Definition newton-tr.hpp:17
Tuning parameters for the PANOC algorithm.
Definition panoc-ocp.hpp:17
Tuning parameters for the PANOC algorithm.
Definition panoc.hpp:25
Tuning parameters for the PANTR algorithm.
Definition pantr.hpp:23
Parameters for SteihaugCG.
Parameters for the StructuredNewtonDirection class.
Parameters for the StructuredNewtonDirection class.
Tuning parameters for the ZeroFPR algorithm.
Definition zerofpr.hpp:24
constexpr bool is_duration
Definition json.cpp:33
std::string_view full_key
Full key string, used for diagnostics.
Definition params.hpp:18
auto split_key(std::string_view full, char tok='.')
Split the string full on the first occurrence of tok.
Definition params.hpp:32
std::string_view value
The value of the parameter to store.
Definition params.hpp:22
void set_param(T &t, const json &j)
Update/overwrite the first argument based on the JSON object j.
Definition json.tpp:24
Represents a parameter value encoded as a string in the format abc.def.key=value.
Definition params.hpp:16
Unused unique type tag for template specializations that were rejected because some types were not di...
void parse_duration(std::chrono::duration< Rep, Period > &t, std::string_view s)
Adds the sum of the durations in the string s to the duration t.
std::from_chars_result from_chars(const char *first, const char *last, T &value, std::chars_format fmt=std::chars_format::general)
@ LBFGSBpp
The stopping criterion used by LBFGS++, see https://lbfgspp.statr.me/doc/classLBFGSpp_1_1LBFGSBParam....
@ ProjGradUnitNorm
∞-norm of the projected gradient with unit step size:
@ ProjGradNorm
∞-norm of the projected gradient with step size γ:
@ Ipopt
The stopping criterion used by Ipopt, see https://link.springer.com/article/10.1007/s10107-004-0559-y...
@ FPRNorm2
2-norm of fixed point residual:
@ ProjGradNorm2
2-norm of the projected gradient with step size γ:
@ ApproxKKT
Find an ε-approximate KKT point in the ∞-norm:
@ FPRNorm
∞-norm of fixed point residual:
@ ApproxKKT2
Find an ε-approximate KKT point in the 2-norm:
@ ProjGradUnitNorm2
2-norm of the projected gradient with unit step size:
typename Conf::length_t length_t
Definition config.hpp:76
typename Conf::cmvec cmvec
Definition config.hpp:68
constexpr const auto inf
Definition config.hpp:85
typename Conf::vec vec
Definition config.hpp:66
LBFGSStepSize
Which method to use to select the L-BFGS step size.
Definition lbfgs.hpp:26
@ BasedOnCurvature
Initial inverse Hessian approximation is set to .
@ BasedOnExternalStepSize
Initial inverse Hessian approximation is set to , where is the forward-backward splitting step size.
#define ALPAQA_SET_PARAM_INST(...)
Definition params.cpp:198
#define ALPAQA_SET_PARAM_INST_INT(...)
Definition params.cpp:221
Parameters for the StructuredLBFGSDirection class.
Custom parameter parsing exception.
Definition params.hpp:26