283 [[maybe_unused]]
bool spy =
false) {
284 using DenseVector = Eigen::Vector<Scalar, Eigen::Dynamic>;
285 using SparseMatrix = Eigen::SparseMatrix<Scalar>;
286 using SparseVector = Eigen::SparseVector<Scalar>;
289 DenseVector x{m_decision_variables.size()};
290 for (
size_t i = 0; i < m_decision_variables.size(); ++i) {
291 x[i] = m_decision_variables[i].value();
294 if (options.diagnostics) {
295 print_exit_conditions(options);
296 print_problem_analysis();
308#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
309 if (options.diagnostics) {
316 VariableMatrix<Scalar> x_ad{m_decision_variables};
319 Variable f = m_f.value_or(Scalar(0));
321 int num_decision_variables = m_decision_variables.size();
322 int num_equality_constraints = m_equality_constraints.size();
323 int num_inequality_constraints = m_inequality_constraints.size();
327 for (
const auto& callback : m_iteration_callbacks) {
328 iteration_callbacks.emplace_back(callback);
330 for (
const auto& callback : m_persistent_iteration_callbacks) {
331 iteration_callbacks.emplace_back(callback);
336 if (m_equality_constraints.empty() && m_inequality_constraints.empty()) {
337 if (options.diagnostics) {
342 ad_setup_profilers.emplace_back(
"setup");
343 ad_setup_profilers.emplace_back(
"↳ ∇f(x)");
344 ad_setup_profilers.emplace_back(
"↳ ∇²ₓₓL");
346 ad_setup_profilers[0].start();
349 ad_setup_profilers[1].start();
351 ad_setup_profilers[1].stop();
354 ad_setup_profilers[2].start();
355 Hessian<Scalar, Eigen::Lower> H{f, x_ad};
356 ad_setup_profilers[2].stop();
358 ad_setup_profilers[0].stop();
360 if (options.diagnostics) {
364#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
366 std::unique_ptr<Spy<Scalar>> H_spy;
369 H_spy = std::make_unique<Spy<Scalar>>(
370 "H.spy",
"Hessian",
"Decision variables",
"Decision variables",
371 num_decision_variables, num_decision_variables);
372 iteration_callbacks.push_back(
373 [&](
const IterationInfo<Scalar>& info) ->
bool {
380 NewtonMatrixCallbacks<Scalar> matrix_callbacks{
381 num_decision_variables,
382 [&](
const DenseVector& x) -> Scalar {
386 [&](
const DenseVector& x) -> SparseVector {
390 [&](
const DenseVector& x) -> SparseMatrix {
397 newton<Scalar>(matrix_callbacks, iteration_callbacks, options, x);
398 }
else if (m_inequality_constraints.empty()) {
399 if (options.diagnostics) {
403 VariableMatrix<Scalar> c_e_ad{m_equality_constraints};
404 VariableMatrix<Scalar> y_ad(num_equality_constraints);
407 ad_setup_profilers.emplace_back(
"setup");
408 ad_setup_profilers.emplace_back(
"↳ ∇f(x)");
409 ad_setup_profilers.emplace_back(
"↳ ∇²ₓₓL");
410 ad_setup_profilers.emplace_back(
" ↳ ∇²ₓₓL_f");
411 ad_setup_profilers.emplace_back(
" ↳ ∇²ₓₓL_c");
412 ad_setup_profilers.emplace_back(
"↳ ∂cₑ/∂x");
414 ad_setup_profilers[0].start();
417 ad_setup_profilers[1].start();
419 ad_setup_profilers[1].stop();
421 ad_setup_profilers[2].start();
424 ad_setup_profilers[3].start();
425 Hessian<Scalar, Eigen::Lower> H_f{f, x_ad};
426 ad_setup_profilers[3].stop();
429 ad_setup_profilers[4].start();
430 Hessian<Scalar, Eigen::Lower> H_c{-y_ad.T() * c_e_ad, x_ad};
431 ad_setup_profilers[4].stop();
433 ad_setup_profilers[2].stop();
436 ad_setup_profilers[5].start();
437 Jacobian A_e{c_e_ad, x_ad};
438 ad_setup_profilers[5].stop();
440 ad_setup_profilers[0].stop();
442 if (options.diagnostics) {
446#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
448 std::unique_ptr<Spy<Scalar>> H_spy;
449 std::unique_ptr<Spy<Scalar>> A_e_spy;
452 H_spy = std::make_unique<Spy<Scalar>>(
453 "H.spy",
"Hessian",
"Decision variables",
"Decision variables",
454 num_decision_variables, num_decision_variables);
455 A_e_spy = std::make_unique<Spy<Scalar>>(
456 "A_e.spy",
"Equality constraint Jacobian",
"Constraints",
457 "Decision variables", num_equality_constraints,
458 num_decision_variables);
459 iteration_callbacks.push_back(
460 [&](
const IterationInfo<Scalar>& info) ->
bool {
462 A_e_spy->add(info.A_e);
468 SQPMatrixCallbacks<Scalar> matrix_callbacks{
469 num_decision_variables,
470 num_equality_constraints,
471 [&](
const DenseVector& x) -> Scalar {
475 [&](
const DenseVector& x) -> SparseVector {
479 [&](
const DenseVector& x,
const DenseVector& y) -> SparseMatrix {
482 return H_f.value() + H_c.value();
484 [&](
const DenseVector& x,
const DenseVector& y) -> SparseMatrix {
489 [&](
const DenseVector& x) -> DenseVector {
491 return c_e_ad.value();
493 [&](
const DenseVector& x) -> SparseMatrix {
499 status = sqp<Scalar>(matrix_callbacks, iteration_callbacks, options, x);
501 if (options.diagnostics) {
505 VariableMatrix<Scalar> c_e_ad{m_equality_constraints};
506 VariableMatrix<Scalar> c_i_ad{m_inequality_constraints};
507 VariableMatrix<Scalar> y_ad(num_equality_constraints);
508 VariableMatrix<Scalar> z_ad(num_inequality_constraints);
511 ad_setup_profilers.emplace_back(
"setup");
512 ad_setup_profilers.emplace_back(
"↳ ∇f(x)");
513 ad_setup_profilers.emplace_back(
"↳ ∇²ₓₓL");
514 ad_setup_profilers.emplace_back(
" ↳ ∇²ₓₓL_f");
515 ad_setup_profilers.emplace_back(
" ↳ ∇²ₓₓL_c");
516 ad_setup_profilers.emplace_back(
"↳ ∂cₑ/∂x");
517 ad_setup_profilers.emplace_back(
"↳ ∂cᵢ/∂x");
519 ad_setup_profilers[0].start();
522 ad_setup_profilers[1].start();
524 ad_setup_profilers[1].stop();
526 ad_setup_profilers[2].start();
529 ad_setup_profilers[3].start();
530 Hessian<Scalar, Eigen::Lower> H_f{f, x_ad};
531 ad_setup_profilers[3].stop();
534 ad_setup_profilers[4].start();
535 Hessian<Scalar, Eigen::Lower> H_c{-y_ad.T() * c_e_ad - z_ad.T() * c_i_ad,
537 ad_setup_profilers[4].stop();
539 ad_setup_profilers[2].stop();
542 ad_setup_profilers[5].start();
543 Jacobian A_e{c_e_ad, x_ad};
544 ad_setup_profilers[5].stop();
547 ad_setup_profilers[6].start();
548 Jacobian A_i{c_i_ad, x_ad};
549 ad_setup_profilers[6].stop();
551 ad_setup_profilers[0].stop();
553 if (options.diagnostics) {
557#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
559 std::unique_ptr<Spy<Scalar>> H_spy;
560 std::unique_ptr<Spy<Scalar>> A_e_spy;
561 std::unique_ptr<Spy<Scalar>> A_i_spy;
564 H_spy = std::make_unique<Spy<Scalar>>(
565 "H.spy",
"Hessian",
"Decision variables",
"Decision variables",
566 num_decision_variables, num_decision_variables);
567 A_e_spy = std::make_unique<Spy<Scalar>>(
568 "A_e.spy",
"Equality constraint Jacobian",
"Constraints",
569 "Decision variables", num_equality_constraints,
570 num_decision_variables);
571 A_i_spy = std::make_unique<Spy<Scalar>>(
572 "A_i.spy",
"Inequality constraint Jacobian",
"Constraints",
573 "Decision variables", num_inequality_constraints,
574 num_decision_variables);
575 iteration_callbacks.push_back(
576 [&](
const IterationInfo<Scalar>& info) ->
bool {
578 A_e_spy->add(info.A_e);
579 A_i_spy->add(info.A_i);
585 const auto [bound_constraint_mask,
bounds, conflicting_bound_indices] =
588 if (!conflicting_bound_indices.empty()) {
589 if (options.diagnostics) {
591 conflicting_bound_indices);
596#ifdef SLEIPNIR_ENABLE_BOUND_PROJECTION
600 InteriorPointMatrixCallbacks<Scalar> matrix_callbacks{
601 num_decision_variables,
602 num_equality_constraints,
603 num_inequality_constraints,
604 [&](
const DenseVector& x) -> Scalar {
608 [&](
const DenseVector& x) -> SparseVector {
612 [&](
const DenseVector& x,
const DenseVector& y,
613 const DenseVector& z) -> SparseMatrix {
617 return H_f.value() + H_c.value();
619 [&](
const DenseVector& x,
const DenseVector& y,
620 const DenseVector& z) -> SparseMatrix {
626 [&](
const DenseVector& x) -> DenseVector {
628 return c_e_ad.value();
630 [&](
const DenseVector& x) -> SparseMatrix {
634 [&](
const DenseVector& x) -> DenseVector {
636 return c_i_ad.value();
638 [&](
const DenseVector& x) -> SparseMatrix {
646#ifdef SLEIPNIR_ENABLE_BOUND_PROJECTION
647 bound_constraint_mask,
652 if (options.diagnostics) {
657 VariableMatrix<Scalar>{m_decision_variables}.set_value(x);