Nonconvex constrained optimization
Loading...
Searching...
No Matches
cutest-loader.cpp
Go to the documentation of this file.
2
6#include <guanaqo/dl-flags.hpp>
7#include <guanaqo/dl.hpp>
8
9#include <cassert>
10#include <filesystem>
11#include <iostream>
12#include <memory>
13#include <stdexcept>
14#include <string>
15#include <string_view>
16
17#include "cutest-functions.hpp"
18
19using namespace std::string_literals;
20
21namespace {
22void throw_error(std::string_view s, int code) {
24 std::string(s), static_cast<alpaqa::cutest::Status>(code));
25}
26void throw_if_error(std::string_view s, int code) {
27 if (code)
28 throw_error(s, code);
29}
30void log_if_error(std::string_view s, int code) {
31 if (code)
32 std::cerr << s << " (" << code << ")\n";
33}
34template <class F>
35auto checked(F &&func, std::string_view msg) {
36 return [msg, func{std::forward<F>(func)}]<class... Args>(
37 Args &&...args) mutable {
39 std::forward<F>(func)(&status, std::forward<Args>(args)...);
40 throw_if_error(msg, status);
41 };
42}
43} // namespace
44
45namespace alpaqa {
46
48 public:
49 USING_ALPAQA_CONFIG(CUTEstProblem::config_t);
51
52 private:
53 using cleanup_t = std::shared_ptr<void>;
54 template <class F>
55 cleanup_t cleanup(F &&func) {
56 return cleanup_t{nullptr,
57 [func{std::forward<F>(func)}](void *) { func(); }};
58 }
59
62
63 template <class F>
64 auto load() -> F::signature_t * {
65 return F::load(so_handle.get());
66 }
67
68 template <class F, class... Args>
69 decltype(auto) call(Args &&...args) {
70 return load<F>()(std::forward<Args>(args)...);
71 }
72
73 cleanup_t load_outsdif(const char *outsdif_fname) {
74 std::filesystem::path p = outsdif_fname;
75 if (!std::filesystem::is_regular_file(p))
76 throw std::invalid_argument("CUTEstLoader: OUTSDIF path does not "
77 "exist or is not a regular file: \"" +
78 std::string(outsdif_fname) + '"');
79 integer status;
80 auto fptr_close = load<cutest::fortran_close>();
81 call<cutest::fortran_open>(&funit, outsdif_fname, &status);
82 throw_if_error("Failed to open "s + outsdif_fname, status);
83 return cleanup([funit{this->funit}, fptr_close] {
84 integer status;
85 fptr_close(&funit, &status);
86 log_if_error("Failed to close OUTSDIF.d file", status);
87 });
88 }
89
91 auto fptr_cterminate = load<cutest::cterminate>();
92 return cleanup([fptr_cterminate] {
93 integer status;
94 fptr_cterminate(&status);
95 log_if_error("Failed to call cutest_cterminate", status);
96 });
97 }
98
99 public:
100 CUTEstLoader(const char *so_fname, const char *outsdif_fname,
101 DynamicLoadFlags dl_flags) {
102 namespace fs = std::filesystem;
103 auto path = fs::path(so_fname);
104 if (fs::is_directory(path))
105 path /= "PROBLEM.so";
106 // Open the shared library
107 so_handle = guanaqo::load_lib(path.c_str(), dl_flags);
108
109 // Open the OUTSDIF.d file
110 if (outsdif_fname && *outsdif_fname)
111 path = outsdif_fname;
112 else
113 path.replace_filename("OUTSDIF.d");
114 cleanup_outsdif = load_outsdif(path.c_str());
115
116 // Get the dimensions of the problem
117 integer status;
118 call<cutest::cdimen>(&status, &funit, &nvar, &ncon);
119 throw_if_error("Failed to call cutest_cdimen", status);
120 }
121
139
140 void setup_problem(rvec x0, rvec y0, Box &C, Box &D) {
141 assert(x0.size() == static_cast<length_t>(nvar));
142 assert(C.lower.size() == static_cast<length_t>(nvar));
143 assert(C.upper.size() == static_cast<length_t>(nvar));
144 assert(y0.size() == static_cast<length_t>(ncon));
145 assert(D.lower.size() == static_cast<length_t>(ncon));
146 assert(D.upper.size() == static_cast<length_t>(ncon));
147
148 // Variables returned and required by csetup
149 equatn.resize(static_cast<length_t>(ncon));
150 linear.resize(static_cast<length_t>(ncon));
151 integer e_order = 0; // no specific order of equality constraints
152 integer l_order = 0; // no specific order of linear constraints
153 integer v_order = 0; // no specific order of linear variables
154 integer status;
155
156 // Initialize the problem
158 x0.data(), C.lower.data(), C.upper.data(),
159 y0.data(), D.lower.data(), D.upper.data(),
160 equatn.data(), linear.data(), &e_order, &l_order,
161 &v_order);
162 throw_if_error("Failed to call cutest_csetup", status);
164
165 // Allocate workspaces
166 work.resize(std::max(nvar, ncon));
167 work2.resize(std::max(nvar, ncon));
168 // Convert bounds
169 std::ranges::replace(C.lower, -cutest::inf, -inf<config_t>);
170 std::ranges::replace(C.upper, +cutest::inf, +inf<config_t>);
171 std::ranges::replace(D.lower, -cutest::inf, -inf<config_t>);
172 std::ranges::replace(D.upper, +cutest::inf, +inf<config_t>);
173 // Load problem functions and gradients
174 funcs = {
175 .cfn = load<cutest::cfn>(),
176 .cofg = load<cutest::cofg>(),
177 .ccfg = load<cutest::ccfg>(),
178 .clfg = load<cutest::clfg>(),
179 .cjprod = load<cutest::cjprod>(),
180 .ccifg = load<cutest::ccifg>(),
181 .cigr = load<cutest::cigr>(),
182 .cdimsj = load<cutest::cdimsj>(),
183 .csjp = load<cutest::csjp>(),
184 .ccfsg = load<cutest::ccfsg>(),
185 .cdh = load<cutest::cdh>(),
186 .cdimsh = load<cutest::cdimsh>(),
187 .cshp = load<cutest::cshp>(),
188 .csh = load<cutest::csh>(),
189 .chprod = load<cutest::chprod>(),
190 };
191 }
192
193 std::string get_name() {
194 std::string name(cutest::fstring_len, ' ');
195 integer status;
196 call<cutest::probname>(&status, name.data());
197 throw_if_error("Failed to call CUTEST_probname", status);
198 if (auto last = name.find_last_not_of(' '); last != name.npos)
199 name.resize(last + 1);
200 return name;
201 }
202
203 void get_report(double *calls, double *time) {
204 integer status;
205 if (ncon > 0) {
206 call<cutest::creport>(&status, calls, time);
207 throw_if_error("Failed to call CUTEST_creport", status);
208 } else {
209 call<cutest::ureport>(&status, calls, time);
210 throw_if_error("Failed to call CUTEST_ureport", status);
211 }
212 }
213
214 // Order of cleanup is important!
215 std::shared_ptr<void> so_handle; ///< dlopen handle to shared library
216 cleanup_t cleanup_outsdif; ///< Responsible for closing the OUTSDIF.d file
217 cleanup_t cutest_terminate; ///< Responsible for calling CUTEST_xterminate
218
219 integer funit = 42; ///< Fortran Unit Number for OUTSDIF.d file
220 integer iout = 6; ///< Fortran Unit Number for standard output
221 integer io_buffer = 11; ///< Fortran Unit Number for internal IO
222
223 integer nvar; ///< Number of decision variabls
224 integer ncon; ///< Number of constraints
225 ConstrFuncs funcs; /// Pointers to loaded problem functions
226
227 using logical_vec = Eigen::VectorX<logical>;
228 logical_vec equatn; ///< whether the constraint is an equality
229 logical_vec linear; ///< whether the constraint is linear
230 mutable vec work, work2; ///< work vectors
231};
232
233CUTEstProblem::CUTEstProblem(const char *so_fname, const char *outsdif_fname,
234 bool sparse, DynamicLoadFlags flags)
235 : BoxConstrProblem<config_t>{0, 0}, sparse{sparse} {
236 impl = std::make_unique<CUTEstLoader>(so_fname, outsdif_fname, flags);
237 resize(static_cast<length_t>(impl->nvar),
238 static_cast<length_t>(impl->ncon));
239 x0.resize(num_variables);
240 y0.resize(num_constraints);
241 impl->setup_problem(x0, y0, variable_bounds, general_bounds);
242 name = impl->get_name();
243}
244
247CUTEstProblem::CUTEstProblem(CUTEstProblem &&) noexcept = default;
248CUTEstProblem &CUTEstProblem::operator=(CUTEstProblem &&) noexcept = default;
249CUTEstProblem::~CUTEstProblem() = default;
250
252 double calls[7]; // NOLINT(*-c-arrays)
253 double time[2]; // NOLINT(*-c-arrays)
254 impl->get_report(calls, time);
255 const bool constr = impl->ncon > 0;
256 return {
257 .calls{
258 .objective = static_cast<unsigned>(calls[0]),
259 .objective_grad = static_cast<unsigned>(calls[1]),
260 .objective_hess = static_cast<unsigned>(calls[2]),
261 .hessian_times_vector = static_cast<unsigned>(calls[3]),
262 .constraints = constr ? static_cast<unsigned>(calls[4]) : 0,
263 .constraints_grad = constr ? static_cast<unsigned>(calls[5]) : 0,
264 .constraints_hess = constr ? static_cast<unsigned>(calls[6]) : 0,
265 },
266 .time_setup = time[0],
267 .time = time[1],
268 };
269}
270
272 assert(x.size() == static_cast<length_t>(impl->nvar));
273 real_t f;
275 checked(impl->funcs.cofg, "eval_objective: CUTEST_cofg")(
276 &impl->nvar, x.data(), &f, nullptr, &grad);
277 return f;
278}
280 assert(x.size() == static_cast<length_t>(impl->nvar));
281 assert(grad_fx.size() == static_cast<length_t>(impl->nvar));
282 real_t f;
284 checked(impl->funcs.cofg, "eval_objective_gradient: CUTEST_cofg")(
285 &impl->nvar, x.data(), &f, grad_fx.data(), &grad);
286}
288 assert(x.size() == static_cast<length_t>(impl->nvar));
289 assert(gx.size() == static_cast<length_t>(impl->ncon));
290 if (impl->ncon == 0)
291 return;
293 cutest::integer zero = 0;
294 checked(impl->funcs.ccfg, "eval_constraints: CUTEST_ccfg")(
295 &impl->nvar, &impl->ncon, x.data(), gx.data(), &jtrans, &zero, &zero,
296 nullptr, &grad);
297}
299 rvec grad_gxy) const {
300 if (impl->ncon == 0) {
301 grad_gxy.setZero();
302 return;
303 }
304 assert(x.size() == static_cast<length_t>(impl->nvar));
305 assert(y.size() == static_cast<length_t>(impl->ncon));
306 assert(grad_gxy.size() == static_cast<length_t>(impl->nvar));
307 auto lvector = static_cast<cutest::integer>(y.size()),
308 lresult = static_cast<cutest::integer>(grad_gxy.size());
310 checked(impl->funcs.cjprod,
311 "eval_constraints_gradient_product: CUTEST_cjprod")(
312 &impl->nvar, &impl->ncon, &gotj, &jtrans, x.data(), y.data(), &lvector,
313 grad_gxy.data(), &lresult);
314}
315
317 // Compute the nonzero values
318 assert(x.size() == static_cast<length_t>(impl->nvar));
319 if (impl->ncon == 0)
320 return;
321 // Sparse Jacobian
322 if (sparse) {
323 assert(nnz_J >= 0);
324 assert(J_values.size() == static_cast<length_t>(nnz_J));
325 assert(storage_jac_g.rows.size() == static_cast<length_t>(nnz_J));
326 assert(storage_jac_g.cols.size() == static_cast<length_t>(nnz_J));
327 const cutest::integer nnz = nnz_J;
329 checked(impl->funcs.ccfsg, "eval_constraints_jacobian: CUTEST_ccfsg")(
330 &impl->nvar, &impl->ncon, x.data(), impl->work.data(), &nnz_J, &nnz,
331 J_values.data(), storage_jac_g.cols.data(),
332 storage_jac_g.rows.data(), &grad);
333 }
334 // Dense Jacobian
335 else {
336 assert(J_values.size() == static_cast<length_t>(impl->nvar) *
337 static_cast<length_t>(impl->ncon));
339 checked(impl->funcs.ccfg, "eval_constraints_jacobian: CUTEST_ccfg")(
340 &impl->nvar, &impl->ncon, x.data(), impl->work.data(), &jtrans,
341 &impl->ncon, &impl->nvar, J_values.data(), &grad);
342 }
343}
345 if (!sparse || impl->ncon == 0)
346 return sparsity::Dense{
347 .rows = num_constraints,
348 .cols = num_variables,
349 .symmetry = sparsity::Symmetry::Unsymmetric,
350 };
351 if (nnz_J < 0) {
352 checked(impl->funcs.cdimsj,
353 "get_constraints_jacobian_sparsity: CUTEST_cdimsj")(&nnz_J);
354 nnz_J -= impl->nvar;
355 assert(nnz_J >= 0);
356 storage_jac_g.cols.resize(nnz_J);
357 storage_jac_g.rows.resize(nnz_J);
358 const cutest::integer nnz = nnz_J;
359 checked(impl->funcs.csjp, "eval_constraints_jacobian: CUTEST_csjp")(
360 &nnz_J, &nnz, storage_jac_g.cols.data(), storage_jac_g.rows.data());
361 }
362 using SparseCOO = sparsity::SparseCOO<int>;
363 return SparseCOO{
364 .rows = num_constraints,
365 .cols = num_variables,
366 .symmetry = sparsity::Symmetry::Unsymmetric,
367 .row_indices = as_span(storage_jac_g.rows),
368 .col_indices = as_span(storage_jac_g.cols),
369 .order = SparseCOO::Unsorted,
370 .first_index = 1, // Fortran-style indices
371 };
372}
374 assert(x.size() == static_cast<length_t>(impl->nvar));
375 assert(grad_gi.size() == static_cast<length_t>(impl->nvar));
376 if (impl->ncon == 0) {
377 grad_gi.setZero();
378 return;
379 }
380 auto iprob = static_cast<cutest::integer>(i + 1); // index zero is objective
381 checked(impl->funcs.cigr, "eval_grad_gi: CUTEST_cigr")(
382 &impl->nvar, &iprob, x.data(), grad_gi.data());
383}
385 real_t scale, crvec v,
386 rvec Hv) const {
387 assert(x.size() == static_cast<length_t>(impl->nvar));
388 assert(y.size() == static_cast<length_t>(impl->ncon));
389 assert(v.size() == static_cast<length_t>(impl->nvar));
390 assert(Hv.size() == static_cast<length_t>(impl->nvar));
391 const auto *mult = y.data();
392 if (scale != 1) {
393 impl->work = y * (real_t(1) / scale);
394 mult = impl->work.data();
395 }
397 checked(impl->funcs.chprod,
398 "eval_lagrangian_hessian_product: CUTEST_chprod")(
399 &impl->nvar, &impl->ncon, &goth, x.data(), mult,
400 const_cast<real_t *>(v.data()), Hv.data());
401 if (scale != 1)
402 Hv *= scale;
403}
405 crvec x, crvec y, crvec Σ, real_t scale, crvec v, rvec Hv) const {
406 assert(x.size() == static_cast<length_t>(impl->nvar));
407 assert(y.size() == static_cast<length_t>(impl->ncon));
408 assert(Σ.size() == static_cast<length_t>(impl->ncon));
409 assert(v.size() == static_cast<length_t>(impl->nvar));
410 assert(Hv.size() == static_cast<length_t>(impl->nvar));
411 auto &&ζ = impl->work.topRows(impl->ncon);
412 auto &&ŷ = impl->work2.topRows(impl->ncon);
413 // ζ = g(x) + Σ⁻¹y
414 eval_constraints(x, ζ);
415 ζ += y.cwiseQuotient(Σ);
416 // d = ζ - Π(ζ, D)
418 // ŷ = Σ d
419 ŷ.array() *= Σ.array();
420 // Hv = ∇²ℒ(x, ŷ) v
421 eval_lagrangian_hessian_product(x, ŷ, scale, v, Hv);
422 // Find active constraints
423 const auto &D = general_bounds;
424 for (index_t i = 0; i < impl->ncon; ++i)
425 ζ(i) = (ζ(i) <= D.lower(i)) || (D.upper(i) <= ζ(i)) ? Σ(i) : real_t(0);
426 // Jg(x) v
427 auto &&Jv = impl->work2.topRows(impl->ncon);
428 auto lvector = static_cast<cutest::integer>(v.size()),
429 lresult = static_cast<cutest::integer>(Jv.size());
431 checked(impl->funcs.cjprod,
432 "eval_augmented_lagrangian_hessian_product: CUTEST_cjprod-1")(
433 &impl->nvar, &impl->ncon, &gotj, &jtrans, x.data(), v.data(), &lvector,
434 Jv.data(), &lresult);
435 // Σ Jg v
436 Jv.array() *= ζ.array();
437 // Jgᵀ Σ Jg v
438 std::swap(lvector, lresult);
439 gotj = jtrans = cutest::True;
440 auto &&JΣJv = impl->work.topRows(impl->nvar);
441 checked(impl->funcs.cjprod,
442 "eval_augmented_lagrangian_hessian_product: CUTEST_cjprod-2")(
443 &impl->nvar, &impl->ncon, &gotj, &jtrans, x.data(), Jv.data(), &lvector,
444 JΣJv.data(), &lresult);
445 Hv += JΣJv;
446}
448 rvec H_values) const {
449 // Compute the nonzero values
450 assert(x.size() == static_cast<length_t>(impl->nvar));
451 assert(y.size() == static_cast<length_t>(impl->ncon));
452 const auto *mult = y.data();
453 if (scale != 1) {
454 impl->work = y * (real_t(1) / scale);
455 mult = impl->work.data();
456 }
457 // Sparse Hessian
458 if (sparse) {
459 assert(nnz_H >= 0);
460 assert(H_values.size() == static_cast<length_t>(nnz_H));
461 assert(storage_hess_L.rows.size() == static_cast<length_t>(nnz_H));
462 assert(storage_hess_L.cols.size() == static_cast<length_t>(nnz_H));
463 const cutest::integer nnz = nnz_H;
464 checked(impl->funcs.csh, "eval_lagrangian_hessian: CUTEST_csh")(
465 &impl->nvar, &impl->ncon, x.data(), y.data(), &nnz_H, &nnz,
466 H_values.data(), storage_hess_L.rows.data(),
467 storage_hess_L.cols.data());
468 }
469 // Dense Hessian
470 else {
471 assert(H_values.size() == static_cast<length_t>(impl->nvar) *
472 static_cast<length_t>(impl->nvar));
473 checked(impl->funcs.cdh, "eval_lagrangian_hessian: CUTEST_cdh")(
474 &impl->nvar, &impl->ncon, x.data(), mult, &impl->nvar,
475 H_values.data());
476 }
477 if (scale != 1)
478 H_values *= scale;
479}
481 if (!sparse)
482 return sparsity::Dense{
483 .rows = num_variables,
484 .cols = num_variables,
485 .symmetry = sparsity::Symmetry::Upper,
486 };
487 if (nnz_H < 0) {
488 checked(impl->funcs.cdimsh,
489 "get_lagrangian_hessian_sparsity: CUTEST_cdimsh")(&nnz_H);
490 assert(nnz_H >= 0);
491 storage_hess_L.rows.resize(nnz_H);
492 storage_hess_L.cols.resize(nnz_H);
493 const cutest::integer nnz = nnz_H;
494 checked(impl->funcs.cshp, "eval_lagrangian_hessian: CUTEST_cshp")(
495 &impl->nvar, &nnz_H, &nnz, storage_hess_L.rows.data(),
496 storage_hess_L.cols.data());
497 }
498 using SparseCOO = sparsity::SparseCOO<int>;
499 return SparseCOO{
500 .rows = num_variables,
501 .cols = num_variables,
502 .symmetry = sparsity::Symmetry::Upper,
503 .row_indices = as_span(storage_hess_L.rows),
504 .col_indices = as_span(storage_hess_L.cols),
505 .order = SparseCOO::Unsorted,
506 .first_index = 1, // Fortran-style indices
507 };
508}
510 -> real_t {
511 assert(x.size() == static_cast<length_t>(impl->nvar));
512 assert(grad_fx.size() == static_cast<length_t>(impl->nvar));
513 real_t f;
515 checked(impl->funcs.cofg, "eval_objective_and_gradient: CUTEST_cofg")(
516 &impl->nvar, x.data(), &f, grad_fx.data(), &grad);
517 return f;
518}
520 -> real_t {
521 assert(x.size() == static_cast<length_t>(impl->nvar));
522 assert(g.size() == static_cast<length_t>(impl->ncon));
523 real_t f;
524 checked(impl->funcs.cfn, "eval_objective_and_constraints: CUTEST_cfn")(
525 &impl->nvar, &impl->ncon, x.data(), &f, g.data());
526 return f;
527}
529 rvec) const {
530 assert(x.size() == static_cast<length_t>(impl->nvar));
531 assert(y.size() == static_cast<length_t>(impl->ncon));
532 assert(grad_L.size() == static_cast<length_t>(impl->nvar));
533 real_t L;
535 checked(impl->funcs.clfg, "eval_objective_and_constraints: CUTEST_clfg")(
536 &impl->nvar, &impl->ncon, x.data(), y.data(), &L, grad_L.data(), &grad);
537}
538
539std::ostream &CUTEstProblem::format_report(std::ostream &os,
540 const Report &r) const {
541 os << "CUTEst problem: " << name << "\r\n\n"
542 << "Number of variables: " << num_variables << "\r\n"
543 << "Number of constraints: " << num_constraints << "\r\n\n"
544 << "Objective function evaluations: " //
545 << r.calls.objective << "\r\n"
546 << "Objective function gradient evaluations: " //
547 << r.calls.objective_grad << "\r\n"
548 << "Objective function Hessian evaluations: " //
549 << r.calls.objective_hess << "\r\n"
550 << "Hessian times vector products: " //
551 << r.calls.objective_hess << "\r\n\n";
552 if (num_constraints > 0) {
553 os << "Constraint function evaluations: " //
554 << r.calls.constraints << "\r\n"
555 << "Constraint function gradients evaluations: " //
556 << r.calls.constraints_grad << "\r\n"
557 << "Constraint function Hessian evaluations: " //
558 << r.calls.constraints_hess << "\r\n\n";
559 }
560 return os << "Setup time: " << r.time_setup << "s\r\n"
561 << "Time since setup: " << r.time << "s";
562}
563
564} // namespace alpaqa
BoxConstrProblem(length_t num_variables, length_t num_constraints)
void eval_projecting_difference_constraints(crvec z, rvec p) const
cleanup_t cutest_terminate
Responsible for calling CUTEST_xterminate.
cutest::ccifg::signature_t * ccifg
cutest::cigr::signature_t * cigr
cutest::cfn::signature_t * cfn
integer ncon
Number of constraints.
cutest::logical logical
cutest::ccfsg::signature_t * ccfsg
std::shared_ptr< void > cleanup_t
cutest::csjp::signature_t * csjp
cleanup_t cleanup_outsdif
Responsible for closing the OUTSDIF.d file.
cutest::cdimsh::signature_t * cdimsh
CUTEstLoader(const char *so_fname, const char *outsdif_fname, DynamicLoadFlags dl_flags)
integer iout
Fortran Unit Number for standard output.
cutest::cdimsj::signature_t * cdimsj
integer funit
Fortran Unit Number for OUTSDIF.d file.
decltype(auto) call(Args &&...args)
cutest::csh::signature_t * csh
cutest::clfg::signature_t * clfg
cleanup_t load_outsdif(const char *outsdif_fname)
cutest::cofg::signature_t * cofg
cleanup_t cleanup(F &&func)
integer nvar
Number of decision variabls.
std::shared_ptr< void > so_handle
dlopen handle to shared library
cutest::integer integer
cutest::cjprod::signature_t * cjprod
alpaqa::Box< config_t > Box
cutest::cdh::signature_t * cdh
Eigen::VectorX< logical > logical_vec
Pointers to loaded problem functions.
cutest::chprod::signature_t * chprod
void setup_problem(rvec x0, rvec y0, Box &C, Box &D)
logical_vec equatn
whether the constraint is an equality
vec work2
work vectors
cutest::cshp::signature_t * cshp
auto load() -> F::signature_t *
void get_report(double *calls, double *time)
cutest::ccfg::signature_t * ccfg
logical_vec linear
whether the constraint is linear
integer io_buffer
Fortran Unit Number for internal IO.
Wrapper for CUTEst problems loaded from an external shared library.
void eval_constraints(crvec x, rvec gx) const
Sparsity get_lagrangian_hessian_sparsity() const
void eval_grad_gi(crvec x, index_t i, rvec grad_gi) const
void eval_lagrangian_hessian_product(crvec x, crvec y, real_t scale, crvec v, rvec Hv) const
Calls calls
Function call counters.
void eval_lagrangian_hessian(crvec x, crvec y, real_t scale, rvec H_values) const
unsigned constraints_grad
Number of calls to the constraint gradients.
real_t eval_objective_and_gradient(crvec x, rvec grad_fx) const
double time_setup
CPU time (in seconds) for CUTEST_csetup.
Report get_report() const
CUTEstProblem(const char *so_fname, const char *outsdif_fname=nullptr, bool sparse=false, DynamicLoadFlags dl_flags={})
Load a CUTEst problem from the given shared library and OUTSDIF.d file.
unsigned objective
Number of calls to the objective function.
struct alpaqa::CUTEstProblem::SparseStorage storage_hess_L
void eval_constraints_jacobian(crvec x, rvec J_values) const
real_t eval_objective(crvec x) const
void eval_augmented_lagrangian_hessian_product(crvec x, crvec y, crvec Σ, real_t scale, crvec v, rvec Hv) const
unsigned constraints
Number of calls to the constraint functions.
void eval_lagrangian_gradient(crvec x, crvec y, rvec grad_L, rvec work_n) const
std::string name
Problem name.
Sparsity get_constraints_jacobian_sparsity() const
real_t eval_objective_and_constraints(crvec x, rvec g) const
double time
CPU time (in seconds) since the end of CUTEST_csetup.
void eval_objective_gradient(crvec x, rvec grad_fx) const
unsigned objective_hess
Number of calls to the objective Hessian.
struct alpaqa::CUTEstProblem::SparseStorage storage_jac_g
std::ostream & format_report(std::ostream &os, const Report &r) const
void eval_constraints_gradient_product(crvec x, crvec y, rvec grad_gxy) const
guanaqo::copyable_unique_ptr< class CUTEstLoader > impl
unsigned constraints_hess
Number of calls to the constraint Hessians.
CUTEstProblem & operator=(const CUTEstProblem &)
unsigned objective_grad
Number of calls to the objective gradient.
The report generated by CUTEst.
#define USING_ALPAQA_CONFIG(Conf)
Definition config.hpp:77
constexpr logical True
constexpr logical False
constexpr size_t fstring_len
constexpr doublereal inf
auto as_span(Eigen::DenseBase< Derived > &v)
Convert an Eigen vector view to a std::span.
Definition span.hpp:21
typename Conf::real_t real_t
Definition config.hpp:86
typename Conf::index_t index_t
Definition config.hpp:104
typename Conf::length_t length_t
Definition config.hpp:103
constexpr const auto inf
Definition config.hpp:112
typename Conf::rvec rvec
Definition config.hpp:91
typename Conf::crvec crvec
Definition config.hpp:92
typename Conf::vec vec
Definition config.hpp:88
auto checked(F &&func, std::string_view msg)
void throw_error(std::string_view s, int code)
void throw_if_error(std::string_view s, int code)
void log_if_error(std::string_view s, int code)
void(integer *status, const integer *n, const integer *m, const doublereal *x, doublereal *f, doublereal *c) signature_t