116int main(
int argc,
const char *argv[])
try {
118 SetConsoleOutputCP(CP_UTF8);
127 std::span args{argv,
static_cast<size_t>(argc)};
131 std::ostream &os = std::cout;
137 os <<
"Loading problem " << prob_path << std::endl;
138 auto problem = load_problem(prob_type, prob_path, opts);
139 os <<
"Loaded problem " << problem.path.stem().string() <<
" from "
140 << problem.path <<
"\nnvar: " << problem.problem.get_num_variables()
141 <<
"\nncon: " << problem.problem.get_num_constraints()
142 <<
"\nProvided functions:\n";
147 auto has_opt = [&opts](std::string_view o) {
148 auto o_it = std::ranges::find(opts.
options(), o);
149 if (o_it == opts.
options().end())
151 auto index =
static_cast<size_t>(o_it - opts.
options().begin());
152 ++opts.
used()[index];
156 .print_full = has_opt(
"--full-print"),
157 .hessians = !has_opt(
"--no-hessians"),
158 .scale_perturbations = 1e-2,
163 auto seed =
static_cast<unsigned int>(std::time(
nullptr));
164 set_params(seed,
"--seed", opts);
168 auto used = opts.
used();
169 auto unused_opt = std::ranges::find(used, 0);
170 auto unused_idx =
static_cast<size_t>(unused_opt - used.begin());
171 if (unused_opt != used.end())
172 throw std::invalid_argument(
"Unused option: " +
173 std::string(opts.
options()[unused_idx]));
178}
catch (std::exception &e) {
179 std::cerr <<
"Error: " << guanaqo::demangled_typename(
typeid(e)) <<
":\n "
180 << e.what() << std::endl;
275 auto &te_problem = lproblem.
problem;
280 auto n = te_problem.get_num_variables(),
281 m = te_problem.get_num_constraints();
283 std::srand(
static_cast<unsigned int>(std::time(
nullptr)));
284 vec Σ = 1.5 * vec::Random(m).array() + 2;
286 vec x = x0 + sc * vec::Random(n);
287 vec v = 5e-6 * sc * vec::Random(n);
291 auto print_compare = [&log, &opts](
const auto &other,
const auto &ref) {
293 (ref - other).reshaped().template lpNorm<Eigen::Infinity>();
295 abs_err / ref.reshaped().template lpNorm<Eigen::Infinity>();
296 log <<
" abs error = " << alpaqa::float_to_str(abs_err) <<
'\n';
297 log <<
" rel error = " << alpaqa::float_to_str(rel_err) <<
'\n';
303 auto print_compare_scal = [&log, &opts](
const auto &fd,
const auto &ad) {
304 auto abs_err = std::abs(fd - ad);
305 auto rel_err = abs_err / std::abs(fd);
306 log <<
" abs error = " << alpaqa::float_to_str(abs_err) <<
'\n';
307 log <<
" rel error = " << alpaqa::float_to_str(rel_err) <<
'\n';
309 log <<
" (1) = " << alpaqa::float_to_str(fd) <<
'\n';
310 log <<
" (2) = " << alpaqa::float_to_str(ad) <<
'\n' << std::endl;
314 auto f = [&](crvec x) {
return te_problem.eval_objective(x); };
315 log <<
"Gradient verification: ∇f(x) (grad_f compared to finite "
316 "differences of f)\n";
319 te_problem.eval_objective_gradient(x, grad_f);
320 print_compare(grad_f, fd_grad_f);
322 if (te_problem.provides_eval_objective_and_gradient()) {
323 log <<
"Gradient verification: ∇f(x) (f_grad_f compared to grad_f)\n";
325 auto f2 = te_problem.eval_objective_and_gradient(x, f_grad_f);
326 print_compare(f_grad_f, grad_f);
327 log <<
"Function verification: f(x) (f_grad_f compared to f)\n";
328 print_compare_scal(f2, fx);
331 log <<
"Gradient verification: ∇L(x) (grad_L compared to finite "
332 "differences of f + yᵀg)\n";
333 auto L = [&](crvec x) {
334 te_problem.eval_constraints(x, gx);
335 return te_problem.eval_objective(x) + gx.dot(y);
339 te_problem.eval_lagrangian_gradient(x, y, grad_L, wn);
340 print_compare(grad_L, fd_grad_L);
342 log <<
"Gradient verification: ∇ψ(x) (grad_ψ compared to finite "
343 "differences of ψ)\n";
344 auto ψ = [&](crvec x) {
345 return te_problem.eval_augmented_lagrangian(x, y, Σ, wm);
349 te_problem.eval_augmented_lagrangian_gradient(x, y, Σ, grad_ψ, wn, wm);
350 print_compare(grad_ψ, fd_grad_ψ);
352 log <<
"Gradient verification: ∇ψ(x) (grad_ψ compared to reference "
353 "implementation based on g, ∇f, ∇g)\n";
354 vec grad_ψ_default(n);
356 te_problem, x, y, Σ, grad_ψ_default, wn, wm);
357 print_compare(grad_ψ, grad_ψ_default);
358 log <<
"Function verification: ψ(x) (ψ compared to reference "
359 "implementation based on f, g)\n";
360 print_compare_scal(ψx, ψ_default);
362 if (te_problem.provides_eval_augmented_lagrangian_and_gradient()) {
363 log <<
"Gradient verification: ∇ψ(x) (grad_ψ compared to ψ_grad_ψ)\n";
365 real_t ψ2 = te_problem.eval_augmented_lagrangian_and_gradient(
366 x, y, Σ, ψ_grad_ψ, wn, wm);
367 print_compare(grad_ψ, ψ_grad_ψ);
368 log <<
"Function verification: ψ(x) (ψ compared to ψ_grad_ψ)\n";
369 print_compare_scal(ψx, ψ2);
372 if (te_problem.provides_eval_lagrangian_hessian_product()) {
373 log <<
"Hessian product verification: ∇²L(x) (hess_L_prod compared to "
374 "finite differences of grad_L)\n";
377 te_problem.eval_lagrangian_gradient(xv, y, grad_Lv, wn);
378 vec fd_hess_Lv = grad_Lv - grad_L;
380 te_problem.eval_lagrangian_hessian_product(x, y, 1, v, hess_Lv);
381 print_compare(hess_Lv, fd_hess_Lv);
384 if (te_problem.provides_eval_augmented_lagrangian_hessian_product()) {
385 log <<
"Hessian product verification: ∇²ψ(x) (hess_ψ_prod compared to "
386 "finite differences of grad_ψ)\n";
389 te_problem.eval_augmented_lagrangian_gradient(xv, y, Σ, grad_ψv, wn,
391 vec fd_hess_ψv = grad_ψv - grad_ψ;
393 te_problem.eval_augmented_lagrangian_hessian_product(x, y, Σ, 1, v,
395 print_compare(hess_ψv, fd_hess_ψv);
398 if (opts.
hessians && te_problem.provides_eval_lagrangian_hessian()) {
399 log <<
"Hessian verification: ∇²L(x) (hess_L compared to finite "
400 "differences of grad_L)\n";
401 auto sp = te_problem.get_lagrangian_hessian_sparsity();
403 auto eval_h = [&](rvec v) {
404 te_problem.eval_lagrangian_hessian(x, y, 1., v);
406 auto hess_L = cvt.
eval(eval_h);
408 [&](crvec x, rvec g) {
409 te_problem.eval_lagrangian_gradient(x, y, g, wn);
412 print_compare(hess_L, fd_hess_L);
416 te_problem.provides_eval_augmented_lagrangian_hessian()) {
417 log <<
"Hessian verification: ∇²ψ(x) (hess_ψ compared to finite "
418 "differences of grad_ψ)\\n";
419 auto sp = te_problem.get_augmented_lagrangian_hessian_sparsity();
421 auto eval_h = [&](rvec v) {
422 te_problem.eval_augmented_lagrangian_hessian(x, y, Σ, 1., v);
424 auto hess_ψ = cvt.
eval(eval_h);
426 [&](crvec x, rvec g) {
427 te_problem.eval_augmented_lagrangian_gradient(x, y, Σ, g, wn,
431 print_compare(hess_ψ, fd_hess_ψ);