sleipnirgroup-jormungandr 0.6.7.dev31__tar.gz → 0.6.7.dev44__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sleipnirgroup-jormungandr might be problematic. Click here for more details.
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/CMakeLists.txt +61 -7
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/PKG-INFO +1 -1
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/ipm.hpp +34 -22
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/newton.hpp +3 -2
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/sqp.hpp +12 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/util/bounds.hpp +1 -1
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/util/feasibility_restoration.hpp +38 -11
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/util/filter.hpp +47 -8
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/src/sleipnir/__init__.py +1 -1
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/cart_pole_problem_test.py +4 -2
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/flywheel_ocp_test.py +1 -1
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/flywheel_problem_test.py +1 -1
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/nonlinear_problem_test.py +32 -0
- sleipnirgroup_jormungandr-0.6.7.dev31/include/sleipnir/optimization/solver/util/lagrange_multiplier_estimate.hpp +0 -133
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/LICENSE.txt +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/README.md +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/SleipnirConfig.cmake.in +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/cmake/BuildTypes.cmake +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/cmake/CompilerFlags.cmake +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/cmake/Pybind11Mkdoc.cmake +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/cmake/SubdirList.cmake +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/cmake/arm-none-eabi.cmake +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/autodiff/expression.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/autodiff/expression_graph.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/autodiff/expression_type.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/autodiff/gradient.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/autodiff/hessian.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/autodiff/jacobian.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/autodiff/sleipnir_base.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/autodiff/slice.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/autodiff/variable.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/autodiff/variable_block.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/autodiff/variable_matrix.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/multistart.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/ocp/dynamics_type.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/ocp/timestep_method.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/ocp/transcription_method.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/ocp.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/problem.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/exit_status.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/ipm_matrix_callbacks.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/iteration_info.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/newton_matrix_callbacks.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/options.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/sqp_matrix_callbacks.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/util/all_finite.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/util/append_as_triplets.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/util/dense_kkt_solver.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/util/fraction_to_the_boundary_rule.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/util/inertia.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/util/kkt_error.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/util/kkt_solver.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/util/problem_scaling.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/util/sparse_inf_norms.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/optimization/solver/util/sparse_kkt_solver.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/util/assert.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/util/concepts.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/util/empty.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/util/function_ref.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/util/intrusive_shared_ptr.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/util/pool.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/util/print.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/util/print_diagnostics.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/util/profiler.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/util/scope_exit.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/util/spy.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/include/sleipnir/util/symbol_exports.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/pyproject.toml +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/autodiff/bind_expression_type.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/autodiff/bind_gradient.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/autodiff/bind_hessian.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/autodiff/bind_jacobian.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/autodiff/bind_variable.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/autodiff/bind_variable_block.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/autodiff/bind_variable_matrix.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/binders.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/docstrings.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/for_each_type.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/main.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/optimization/bind_equality_constraints.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/optimization/bind_inequality_constraints.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/optimization/bind_ocp.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/optimization/bind_problem.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/optimization/ocp/bind_dynamics_type.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/optimization/ocp/bind_timestep_method.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/optimization/ocp/bind_transcription_method.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/optimization/solver/bind_exit_status.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/optimization/solver/bind_iteration_info.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/try_cast.hpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/src/sleipnir/autodiff/__init__.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/src/sleipnir/optimization/__init__.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/autodiff/gradient_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/autodiff/hessian_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/autodiff/jacobian_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/autodiff/variable_matrix_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/autodiff/variable_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/arm_on_elevator_problem_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/cart_pole_ocp_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/cart_pole_util.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/constraints_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/decision_variable_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/differential_drive_ocp_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/differential_drive_problem_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/differential_drive_util.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/double_integrator_problem_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/linear_problem_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/multistart_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/near.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/problem_spy_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/quadratic_problem_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/rk4.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/solver/exit_status_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/test/optimization/trivial_problem_test.py +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/src/autodiff/gradient.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/src/autodiff/hessian.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/src/autodiff/jacobian.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/src/autodiff/variable_matrix.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/src/optimization/ocp.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/src/optimization/problem.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/src/optimization/solver/ipm.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/src/optimization/solver/newton.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/src/optimization/solver/sqp.cpp +0 -0
- {sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/src/util/pool.cpp +0 -0
{sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/CMakeLists.txt
RENAMED
|
@@ -206,17 +206,71 @@ if(PROJECT_IS_TOP_LEVEL AND BUILD_TESTING AND NOT CMAKE_CROSSCOMPILING)
|
|
|
206
206
|
list(APPEND CMAKE_MODULE_PATH ${Catch2_SOURCE_DIR}/extras)
|
|
207
207
|
include(Catch)
|
|
208
208
|
|
|
209
|
-
# Build
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
209
|
+
# Build autodiff explicit instantiations shared by autodiff and
|
|
210
|
+
# optimization tests
|
|
211
|
+
file(
|
|
212
|
+
GLOB_RECURSE sleipnir_autodiff_explicit_double_src
|
|
213
|
+
test/src/autodiff/*_explicit_double.cpp
|
|
214
|
+
)
|
|
215
|
+
add_library(
|
|
216
|
+
sleipnir_autodiff_explicit_double
|
|
217
|
+
OBJECT
|
|
218
|
+
${sleipnir_autodiff_explicit_double_src}
|
|
219
|
+
)
|
|
220
|
+
compiler_flags(sleipnir_autodiff_explicit_double)
|
|
221
|
+
target_include_directories(
|
|
222
|
+
sleipnir_autodiff_explicit_double
|
|
223
|
+
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/test/include
|
|
224
|
+
)
|
|
225
|
+
target_link_libraries(sleipnir_autodiff_explicit_double PUBLIC Sleipnir)
|
|
226
|
+
|
|
227
|
+
# Build Sleipnir autodiff tests
|
|
228
|
+
file(GLOB_RECURSE sleipnir_autodiff_test_src test/src/autodiff/*_test.cpp)
|
|
229
|
+
add_executable(sleipnir_autodiff_test ${sleipnir_autodiff_test_src})
|
|
230
|
+
compiler_flags(sleipnir_autodiff_test)
|
|
231
|
+
target_include_directories(
|
|
232
|
+
sleipnir_autodiff_test
|
|
233
|
+
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/test/include
|
|
234
|
+
)
|
|
235
|
+
target_link_libraries(
|
|
236
|
+
sleipnir_autodiff_test
|
|
237
|
+
PUBLIC Sleipnir sleipnir_autodiff_explicit_double Catch2::Catch2WithMain
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
# Build Sleipnir optimization tests
|
|
241
|
+
file(
|
|
242
|
+
GLOB_RECURSE sleipnir_optimization_test_src
|
|
243
|
+
test/src/optimization/*_explicit_double.cpp
|
|
244
|
+
test/src/optimization/*_test.cpp
|
|
245
|
+
)
|
|
246
|
+
add_executable(sleipnir_optimization_test ${sleipnir_optimization_test_src})
|
|
247
|
+
compiler_flags(sleipnir_optimization_test)
|
|
213
248
|
target_include_directories(
|
|
214
|
-
|
|
249
|
+
sleipnir_optimization_test
|
|
215
250
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/test/include
|
|
216
251
|
)
|
|
217
|
-
target_link_libraries(
|
|
252
|
+
target_link_libraries(
|
|
253
|
+
sleipnir_optimization_test
|
|
254
|
+
PUBLIC Sleipnir sleipnir_autodiff_explicit_double Catch2::Catch2WithMain
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
# Build Sleipnir util tests
|
|
258
|
+
file(GLOB_RECURSE sleipnir_util_test_src test/src/util/*_test.cpp)
|
|
259
|
+
add_executable(sleipnir_util_test ${sleipnir_util_test_src})
|
|
260
|
+
compiler_flags(sleipnir_util_test)
|
|
261
|
+
target_include_directories(
|
|
262
|
+
sleipnir_util_test
|
|
263
|
+
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/test/include
|
|
264
|
+
)
|
|
265
|
+
target_link_libraries(
|
|
266
|
+
sleipnir_util_test
|
|
267
|
+
PUBLIC Sleipnir Catch2::Catch2WithMain
|
|
268
|
+
)
|
|
269
|
+
|
|
218
270
|
if(NOT CMAKE_TOOLCHAIN_FILE)
|
|
219
|
-
catch_discover_tests(
|
|
271
|
+
catch_discover_tests(sleipnir_autodiff_test)
|
|
272
|
+
catch_discover_tests(sleipnir_optimization_test)
|
|
273
|
+
catch_discover_tests(sleipnir_util_test)
|
|
220
274
|
endif()
|
|
221
275
|
endif()
|
|
222
276
|
|
|
@@ -353,6 +353,8 @@ ExitStatus ipm(const IPMMatrixCallbacks<Scalar>& matrix_callbacks,
|
|
|
353
353
|
|
|
354
354
|
int full_step_rejected_counter = 0;
|
|
355
355
|
|
|
356
|
+
StallDetector<Scalar> stall_detector;
|
|
357
|
+
|
|
356
358
|
// Error
|
|
357
359
|
Scalar E_0 = unscaled_kkt_error<Scalar, KKTErrorType::INF_NORM_SCALED>(
|
|
358
360
|
matrices.scaling, g, A_e, c_e, A_i, c_i, s, y, z, Scalar(0));
|
|
@@ -504,7 +506,7 @@ ExitStatus ipm(const IPMMatrixCallbacks<Scalar>& matrix_callbacks,
|
|
|
504
506
|
} else {
|
|
505
507
|
trial_s = s + α * step.p_s;
|
|
506
508
|
}
|
|
507
|
-
trial_y = y + α
|
|
509
|
+
trial_y = y + α * step.p_y;
|
|
508
510
|
trial_z = z + α_z * step.p_z;
|
|
509
511
|
|
|
510
512
|
trial_f = matrices.f(trial_x);
|
|
@@ -608,7 +610,7 @@ ExitStatus ipm(const IPMMatrixCallbacks<Scalar>& matrix_callbacks,
|
|
|
608
610
|
|
|
609
611
|
trial_x = x + α_soc * soc_step.p_x;
|
|
610
612
|
trial_s = s + α_soc * soc_step.p_s;
|
|
611
|
-
trial_y = y + α
|
|
613
|
+
trial_y = y + α_soc * soc_step.p_y;
|
|
612
614
|
trial_z = z + α_z_soc * soc_step.p_z;
|
|
613
615
|
|
|
614
616
|
trial_f = matrices.f(trial_x);
|
|
@@ -677,7 +679,7 @@ ExitStatus ipm(const IPMMatrixCallbacks<Scalar>& matrix_callbacks,
|
|
|
677
679
|
|
|
678
680
|
trial_x = x + α_max * step.p_x;
|
|
679
681
|
trial_s = s + α_max * step.p_s;
|
|
680
|
-
trial_y = y + α
|
|
682
|
+
trial_y = y + α_max * step.p_y;
|
|
681
683
|
trial_z = z + α_z * step.p_z;
|
|
682
684
|
|
|
683
685
|
trial_f = matrices.f(trial_x);
|
|
@@ -691,6 +693,7 @@ ExitStatus ipm(const IPMMatrixCallbacks<Scalar>& matrix_callbacks,
|
|
|
691
693
|
// If the step using αᵐᵃˣ reduced the KKT error, accept it anyway
|
|
692
694
|
if (next_kkt_error <= Scalar(0.999) * current_kkt_error) {
|
|
693
695
|
// Accept step
|
|
696
|
+
α = α_max;
|
|
694
697
|
break;
|
|
695
698
|
}
|
|
696
699
|
|
|
@@ -701,6 +704,15 @@ ExitStatus ipm(const IPMMatrixCallbacks<Scalar>& matrix_callbacks,
|
|
|
701
704
|
|
|
702
705
|
line_search_profiler.stop();
|
|
703
706
|
|
|
707
|
+
// If solver stalled, invoke feasibility restoration
|
|
708
|
+
if (!call_feasibility_restoration && !in_feasibility_restoration) {
|
|
709
|
+
FilterEntry trial_entry{trial_f, trial_s, trial_c_e, trial_c_i, μ};
|
|
710
|
+
if (stall_detector.update(current_entry, trial_entry, α,
|
|
711
|
+
filter.min_constraint_violation)) {
|
|
712
|
+
call_feasibility_restoration = true;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
|
|
704
716
|
if (call_feasibility_restoration) {
|
|
705
717
|
ScopedProfiler feasibility_restoration_profiler{
|
|
706
718
|
feasibility_restoration_prof};
|
|
@@ -765,30 +777,30 @@ ExitStatus ipm(const IPMMatrixCallbacks<Scalar>& matrix_callbacks,
|
|
|
765
777
|
y = trial_y;
|
|
766
778
|
z = trial_z;
|
|
767
779
|
|
|
768
|
-
// A requirement for the convergence proof is that the primal-dual barrier
|
|
769
|
-
// term Hessian Σₖ₊₁ does not deviate arbitrarily much from the primal
|
|
770
|
-
// barrier term Hessian μSₖ₊₁⁻².
|
|
771
|
-
//
|
|
772
|
-
// Σₖ₊₁ = μSₖ₊₁⁻²
|
|
773
|
-
// Sₖ₊₁⁻¹Zₖ₊₁ = μSₖ₊₁⁻²
|
|
774
|
-
// Zₖ₊₁ = μSₖ₊₁⁻¹
|
|
775
|
-
//
|
|
776
|
-
// We ensure this by resetting
|
|
777
|
-
//
|
|
778
|
-
// zₖ₊₁ = clamp(zₖ₊₁, 1/κ_Σ μ/sₖ₊₁, κ_Σ μ/sₖ₊₁)
|
|
779
|
-
//
|
|
780
|
-
// for some fixed κ_Σ ≥ 1 after each step. See equation (16) of [2].
|
|
781
|
-
for (int row = 0; row < z.rows(); ++row) {
|
|
782
|
-
constexpr Scalar κ_Σ(1e10);
|
|
783
|
-
z[row] =
|
|
784
|
-
std::clamp(z[row], Scalar(1) / κ_Σ * μ / s[row], κ_Σ * μ / s[row]);
|
|
785
|
-
}
|
|
786
|
-
|
|
787
780
|
f = trial_f;
|
|
788
781
|
c_e = trial_c_e;
|
|
789
782
|
c_i = trial_c_i;
|
|
790
783
|
}
|
|
791
784
|
|
|
785
|
+
// A requirement for the convergence proof is that the primal-dual barrier
|
|
786
|
+
// term Hessian Σₖ₊₁ does not deviate arbitrarily much from the primal
|
|
787
|
+
// barrier term Hessian μSₖ₊₁⁻².
|
|
788
|
+
//
|
|
789
|
+
// Σₖ₊₁ = μSₖ₊₁⁻²
|
|
790
|
+
// Sₖ₊₁⁻¹Zₖ₊₁ = μSₖ₊₁⁻²
|
|
791
|
+
// Zₖ₊₁ = μSₖ₊₁⁻¹
|
|
792
|
+
//
|
|
793
|
+
// We ensure this by resetting
|
|
794
|
+
//
|
|
795
|
+
// zₖ₊₁ = clamp(zₖ₊₁, 1/κ_Σ μ/sₖ₊₁, κ_Σ μ/sₖ₊₁)
|
|
796
|
+
//
|
|
797
|
+
// for some fixed κ_Σ ≥ 1 after each step. See equation (16) of [2].
|
|
798
|
+
for (int row = 0; row < z.rows(); ++row) {
|
|
799
|
+
constexpr Scalar κ_Σ(1e10);
|
|
800
|
+
z[row] =
|
|
801
|
+
std::clamp(z[row], Scalar(1) / κ_Σ * μ / s[row], κ_Σ * μ / s[row]);
|
|
802
|
+
}
|
|
803
|
+
|
|
792
804
|
// Update autodiff for Jacobians and Hessian
|
|
793
805
|
A_e = matrices.A_e(x);
|
|
794
806
|
A_i = matrices.A_i(x);
|
|
@@ -232,14 +232,15 @@ ExitStatus newton(
|
|
|
232
232
|
|
|
233
233
|
trial_x = x + α_max * p_x;
|
|
234
234
|
|
|
235
|
+
trial_f = matrices.f(trial_x);
|
|
236
|
+
|
|
235
237
|
Scalar next_kkt_error =
|
|
236
238
|
kkt_error<Scalar, KKTErrorType::ONE_NORM>(matrices.g(trial_x));
|
|
237
239
|
|
|
238
240
|
// If the step using αᵐᵃˣ reduced the KKT error, accept it anyway
|
|
239
241
|
if (next_kkt_error <= Scalar(0.999) * current_kkt_error) {
|
|
240
|
-
trial_f = matrices.f(trial_x);
|
|
241
|
-
|
|
242
242
|
// Accept step
|
|
243
|
+
α = α_max;
|
|
243
244
|
break;
|
|
244
245
|
}
|
|
245
246
|
|
|
@@ -236,6 +236,8 @@ ExitStatus sqp(const SQPMatrixCallbacks<Scalar>& matrix_callbacks,
|
|
|
236
236
|
|
|
237
237
|
int full_step_rejected_counter = 0;
|
|
238
238
|
|
|
239
|
+
StallDetector<Scalar> stall_detector;
|
|
240
|
+
|
|
239
241
|
// Error
|
|
240
242
|
Scalar E_0 = unscaled_kkt_error<Scalar, KKTErrorType::INF_NORM_SCALED>(
|
|
241
243
|
matrices.scaling, g, A_e, c_e, y);
|
|
@@ -488,6 +490,7 @@ ExitStatus sqp(const SQPMatrixCallbacks<Scalar>& matrix_callbacks,
|
|
|
488
490
|
// If the step using αᵐᵃˣ reduced the KKT error, accept it anyway
|
|
489
491
|
if (next_kkt_error <= Scalar(0.999) * current_kkt_error) {
|
|
490
492
|
// Accept step
|
|
493
|
+
α = α_max;
|
|
491
494
|
break;
|
|
492
495
|
}
|
|
493
496
|
|
|
@@ -498,6 +501,15 @@ ExitStatus sqp(const SQPMatrixCallbacks<Scalar>& matrix_callbacks,
|
|
|
498
501
|
|
|
499
502
|
line_search_profiler.stop();
|
|
500
503
|
|
|
504
|
+
// If solver stalled, invoke feasibility restoration
|
|
505
|
+
if (!call_feasibility_restoration) {
|
|
506
|
+
FilterEntry trial_entry{trial_f, trial_c_e};
|
|
507
|
+
if (stall_detector.update(current_entry, trial_entry, α,
|
|
508
|
+
filter.min_constraint_violation)) {
|
|
509
|
+
call_feasibility_restoration = true;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
501
513
|
if (call_feasibility_restoration) {
|
|
502
514
|
ScopedProfiler feasibility_restoration_profiler{
|
|
503
515
|
feasibility_restoration_prof};
|
|
@@ -225,7 +225,7 @@ void project_onto_bounds(
|
|
|
225
225
|
// We assume that bound infeasibility is handled elsewhere.
|
|
226
226
|
slp_assert(lower <= upper);
|
|
227
227
|
|
|
228
|
-
// See
|
|
228
|
+
// See section 3.6 of [2]
|
|
229
229
|
if (isfinite(lower) && isfinite(upper)) {
|
|
230
230
|
auto p_L = std::min(κ_1 * std::max(Scalar(1), abs(lower)),
|
|
231
231
|
κ_2 * (upper - lower));
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
#include "sleipnir/optimization/solver/options.hpp"
|
|
20
20
|
#include "sleipnir/optimization/solver/sqp_matrix_callbacks.hpp"
|
|
21
21
|
#include "sleipnir/optimization/solver/util/append_as_triplets.hpp"
|
|
22
|
-
#include "sleipnir/optimization/solver/util/lagrange_multiplier_estimate.hpp"
|
|
23
22
|
#include "sleipnir/optimization/solver/util/problem_scaling.hpp"
|
|
24
23
|
#include "sleipnir/util/print_diagnostics.hpp"
|
|
25
24
|
|
|
@@ -317,7 +316,9 @@ ExitStatus feasibility_restoration(
|
|
|
317
316
|
auto g = matrices.g(x);
|
|
318
317
|
auto A_e = matrices.A_e(x);
|
|
319
318
|
|
|
320
|
-
|
|
319
|
+
// Reset the equality constraint duals since feasibility restoration didn't
|
|
320
|
+
// account for the cost function
|
|
321
|
+
y.setZero();
|
|
321
322
|
|
|
322
323
|
return ExitStatus::SUCCESS;
|
|
323
324
|
} else if (status == ExitStatus::SUCCESS) {
|
|
@@ -634,17 +635,39 @@ ExitStatus feasibility_restoration(
|
|
|
634
635
|
fr_x, fr_s, fr_y, fr_z, fr_μ, iterations);
|
|
635
636
|
|
|
636
637
|
x = fr_x.segment(0, x.rows());
|
|
637
|
-
s = fr_s.segment(0, s.rows());
|
|
638
638
|
|
|
639
639
|
if (status == ExitStatus::CALLBACK_REQUESTED_STOP) {
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
640
|
+
const DenseVector s_old = s;
|
|
641
|
+
|
|
642
|
+
// Re-center the slacks on the original constraints cᵢ(x) if they're
|
|
643
|
+
// sufficiently feasible, and on 1 otherwise.
|
|
644
|
+
//
|
|
645
|
+
// We can't use the slacks of cᵢ(x) − pᵢ + nᵢ ≥ 0 because feasibility
|
|
646
|
+
// restoration's barrier parameter fr_μ drives them toward 0 independently
|
|
647
|
+
// of the original problem's barrier parameter μ. Slacks much smaller than μ
|
|
648
|
+
// make Σ = S⁻¹Z and μS⁻¹e very large, which causes very large dual steps
|
|
649
|
+
// after returning.
|
|
650
|
+
const DenseVector c_i = matrices.c_i(x);
|
|
651
|
+
s = (c_i.array() >= Scalar(1e-2)).select(c_i, Scalar(1));
|
|
652
|
+
|
|
653
|
+
// Reset the equality constraint duals since feasibility restoration didn't
|
|
654
|
+
// account for the cost function
|
|
655
|
+
y.setZero();
|
|
656
|
+
|
|
657
|
+
// Update the inequality constraint duals with a Newton step for
|
|
658
|
+
// complementarity, taking the change in slacks during the restoration
|
|
659
|
+
// phase as the primal step.
|
|
660
|
+
//
|
|
661
|
+
// pᶻ = μS⁻¹e − z − Σpˢ
|
|
662
|
+
//
|
|
663
|
+
// If the result isn't strictly positive or is too large, reset all of them
|
|
664
|
+
// to 1.
|
|
665
|
+
const DenseVector Σ = z.cwiseQuotient(s_old);
|
|
666
|
+
const DenseVector p_s = s - s_old;
|
|
667
|
+
z += μ * s_old.cwiseInverse() - z - Σ.cwiseProduct(p_s);
|
|
668
|
+
if ((z.array() <= Scalar(0)).any() || (z.array() > Scalar(1e3)).any()) {
|
|
669
|
+
z.setOnes();
|
|
670
|
+
}
|
|
648
671
|
|
|
649
672
|
return ExitStatus::SUCCESS;
|
|
650
673
|
} else if (status == ExitStatus::SUCCESS) {
|
|
@@ -654,6 +677,9 @@ ExitStatus feasibility_restoration(
|
|
|
654
677
|
// infeasibility anywhere else risks false positives (e.g., a
|
|
655
678
|
// point-in-time test can reject iterates the solver would otherwise
|
|
656
679
|
// escape). See section 3.3, p. 14 of [2].
|
|
680
|
+
|
|
681
|
+
s = fr_s.segment(0, s.rows());
|
|
682
|
+
|
|
657
683
|
DenseVector c_e = matrices.c_e(x);
|
|
658
684
|
if (matrices.scaling.c_e.size() > 0) {
|
|
659
685
|
c_e = matrices.scaling.c_e.cwiseInverse().cwiseProduct(c_e);
|
|
@@ -688,6 +714,7 @@ ExitStatus feasibility_restoration(
|
|
|
688
714
|
|
|
689
715
|
return ExitStatus::FEASIBILITY_RESTORATION_FAILED;
|
|
690
716
|
} else {
|
|
717
|
+
s = fr_s.segment(0, s.rows());
|
|
691
718
|
return ExitStatus::FEASIBILITY_RESTORATION_FAILED;
|
|
692
719
|
}
|
|
693
720
|
}
|
|
@@ -130,15 +130,11 @@ class Filter {
|
|
|
130
130
|
trial_entry.cost <= current_entry.cost + η_ϕ * α * D_ϕ;
|
|
131
131
|
|
|
132
132
|
// Sufficient decrease condition
|
|
133
|
-
//
|
|
134
|
-
// See equation (2.13) of [3].
|
|
135
|
-
Scalar ϕ = pow(α, Scalar(1.5));
|
|
136
133
|
bool sufficient_decrease =
|
|
137
134
|
trial_entry.cost <=
|
|
138
|
-
current_entry.cost -
|
|
139
|
-
ϕ * γ_cost * current_entry.constraint_violation ||
|
|
135
|
+
current_entry.cost - γ_cost * current_entry.constraint_violation ||
|
|
140
136
|
trial_entry.constraint_violation <=
|
|
141
|
-
(Scalar(1) -
|
|
137
|
+
(Scalar(1) - γ_constraint) * current_entry.constraint_violation;
|
|
142
138
|
|
|
143
139
|
// If constraint violation is below threshold and switching condition is
|
|
144
140
|
// true, check Armijo condition for step rejection. Otherwise, check
|
|
@@ -164,8 +160,8 @@ class Filter {
|
|
|
164
160
|
// condition are false
|
|
165
161
|
if (!switching_condition || !armijo_condition) {
|
|
166
162
|
add(FilterEntry{
|
|
167
|
-
current_entry.cost -
|
|
168
|
-
(Scalar(1) -
|
|
163
|
+
current_entry.cost - γ_cost * current_entry.constraint_violation,
|
|
164
|
+
(Scalar(1) - γ_constraint) * current_entry.constraint_violation});
|
|
169
165
|
}
|
|
170
166
|
|
|
171
167
|
return true;
|
|
@@ -211,4 +207,47 @@ class Filter {
|
|
|
211
207
|
}
|
|
212
208
|
};
|
|
213
209
|
|
|
210
|
+
/// Detects a solver stall.
|
|
211
|
+
///
|
|
212
|
+
/// @tparam Scalar Scalar type.
|
|
213
|
+
template <typename Scalar>
|
|
214
|
+
class StallDetector {
|
|
215
|
+
public:
|
|
216
|
+
/// Returns true if the solver stalled.
|
|
217
|
+
///
|
|
218
|
+
/// @param current_entry The entry corresponding to the current iterate.
|
|
219
|
+
/// @param trial_entry The entry corresponding to the accepted trial iterate.
|
|
220
|
+
/// @param α The accepted step size.
|
|
221
|
+
/// @param min_constraint_violation The minimum constraint violation from the
|
|
222
|
+
/// filter.
|
|
223
|
+
/// @return True if the solver stalled.
|
|
224
|
+
bool update(const FilterEntry<Scalar>& current_entry,
|
|
225
|
+
const FilterEntry<Scalar>& trial_entry, Scalar α,
|
|
226
|
+
Scalar min_constraint_violation) {
|
|
227
|
+
// If step is tiny, current iterate is infeasible, and accepted trial
|
|
228
|
+
// iterate made insufficient progress toward feasibility, increment stalled
|
|
229
|
+
// step counter
|
|
230
|
+
if (α < Scalar(1e-3) &&
|
|
231
|
+
current_entry.constraint_violation > min_constraint_violation &&
|
|
232
|
+
trial_entry.constraint_violation >
|
|
233
|
+
Scalar(0.99) * current_entry.constraint_violation) {
|
|
234
|
+
++m_stalled_step_counter;
|
|
235
|
+
|
|
236
|
+
// If there were too many consecutive tiny steps, report a stall
|
|
237
|
+
if (m_stalled_step_counter >= 5) {
|
|
238
|
+
m_stalled_step_counter = 0;
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
} else {
|
|
242
|
+
// A break in stalled steps resets the counter
|
|
243
|
+
m_stalled_step_counter = 0;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
private:
|
|
250
|
+
int m_stalled_step_counter = 0;
|
|
251
|
+
};
|
|
252
|
+
|
|
214
253
|
} // namespace slp
|
|
@@ -15,9 +15,11 @@ def lerp(a, b, t):
|
|
|
15
15
|
return a + t * (b - a)
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
# dt = 0.25 s is sensitive to small solver changes, so a failure here may just
|
|
19
|
+
# mean the iterates found a different basin rather than a regression.
|
|
20
|
+
@pytest.mark.parametrize("dt", [0.05, 0.125, 0.25])
|
|
21
|
+
def test_cart_pole_problem(dt):
|
|
19
22
|
TOTAL_TIME = 5.0 # s
|
|
20
|
-
dt = 0.05 # s
|
|
21
23
|
N = int(TOTAL_TIME / dt)
|
|
22
24
|
|
|
23
25
|
u_max = 20.0 # N
|
|
@@ -96,7 +96,7 @@ def flywheel_test(
|
|
|
96
96
|
# steady-states.
|
|
97
97
|
assert problem.U().value(0, k) == pytest.approx(u, abs=2.0)
|
|
98
98
|
else:
|
|
99
|
-
assert problem.U().value(0, k) == pytest.approx(u, abs=
|
|
99
|
+
assert problem.U().value(0, k) == pytest.approx(u, abs=2e-4)
|
|
100
100
|
|
|
101
101
|
# Project state forward
|
|
102
102
|
x = A_discrete * x + B_discrete * u
|
|
@@ -83,7 +83,7 @@ def test_flywheel_problem():
|
|
|
83
83
|
assert U.value(0, k) >= u_ss
|
|
84
84
|
assert U.value(0, k) <= 12.0
|
|
85
85
|
else:
|
|
86
|
-
assert U.value(0, k) == pytest.approx(u, abs=
|
|
86
|
+
assert U.value(0, k) == pytest.approx(u, abs=2e-4)
|
|
87
87
|
|
|
88
88
|
# Project state forward
|
|
89
89
|
x = A * x + B * u
|
|
@@ -160,3 +160,35 @@ def test_wachter_and_biegler_line_search_failure():
|
|
|
160
160
|
assert x.value() == pytest.approx(-1.0, abs=1e-6)
|
|
161
161
|
assert s1.value() == pytest.approx(0.0, abs=1e-6)
|
|
162
162
|
assert s2.value() == pytest.approx(0.0, abs=3e-5)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def test_hock_schittkowski_13():
|
|
166
|
+
# Problem 13 of [1] (see
|
|
167
|
+
# https://vanderbei.princeton.edu/ampl/nlmodels/cute/hs013.mod) has
|
|
168
|
+
# constraint gradients that are linearly dependent at the solution.
|
|
169
|
+
#
|
|
170
|
+
# [1] Hock, W. and Schittkowski, K. "Test Examples for Nonlinear Programming
|
|
171
|
+
# Codes", Springer, 1981.
|
|
172
|
+
|
|
173
|
+
problem = Problem()
|
|
174
|
+
|
|
175
|
+
x, y = problem.decision_variable(2)
|
|
176
|
+
x.set_value(-2)
|
|
177
|
+
y.set_value(-2)
|
|
178
|
+
|
|
179
|
+
problem.minimize((x - 2) ** 2 + y**2)
|
|
180
|
+
|
|
181
|
+
problem.subject_to((1 - x) ** 3 >= y)
|
|
182
|
+
problem.subject_to(x >= 0)
|
|
183
|
+
problem.subject_to(y >= 0)
|
|
184
|
+
|
|
185
|
+
assert problem.cost_function_type() == ExpressionType.QUADRATIC
|
|
186
|
+
assert problem.equality_constraint_type() == ExpressionType.NONE
|
|
187
|
+
assert problem.inequality_constraint_type() == ExpressionType.NONLINEAR
|
|
188
|
+
|
|
189
|
+
assert problem.solve(diagnostics=True) == ExitStatus.SUCCESS
|
|
190
|
+
|
|
191
|
+
# The solution has no finite Lagrange multipliers, so the iterates only
|
|
192
|
+
# approach it to within the square root of the tolerance
|
|
193
|
+
assert x.value() == pytest.approx(1.0, abs=1e-4)
|
|
194
|
+
assert y.value() == pytest.approx(0.0, abs=1e-4)
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Sleipnir contributors
|
|
2
|
-
|
|
3
|
-
#pragma once
|
|
4
|
-
|
|
5
|
-
#include <algorithm>
|
|
6
|
-
#include <utility>
|
|
7
|
-
|
|
8
|
-
#include <Eigen/Core>
|
|
9
|
-
#include <Eigen/SparseCholesky>
|
|
10
|
-
#include <Eigen/SparseCore>
|
|
11
|
-
#include <gch/small_vector.hpp>
|
|
12
|
-
|
|
13
|
-
#include "sleipnir/optimization/solver/util/append_as_triplets.hpp"
|
|
14
|
-
|
|
15
|
-
namespace slp {
|
|
16
|
-
|
|
17
|
-
/// Lagrange multiplier estimates.
|
|
18
|
-
///
|
|
19
|
-
/// @tparam Scalar Scalar type.
|
|
20
|
-
template <typename Scalar>
|
|
21
|
-
struct LagrangeMultiplierEstimate {
|
|
22
|
-
/// Equality constraint dual estimate.
|
|
23
|
-
Eigen::Vector<Scalar, Eigen::Dynamic> y;
|
|
24
|
-
/// Inequality constraint dual estimate.
|
|
25
|
-
Eigen::Vector<Scalar, Eigen::Dynamic> z;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
/// Estimates Lagrange multipliers for SQP.
|
|
29
|
-
///
|
|
30
|
-
/// @tparam Scalar Scalar type.
|
|
31
|
-
/// @param g Cost function gradient ∇f.
|
|
32
|
-
/// @param A_e Equality constraint Jacobian Aₑ(x).
|
|
33
|
-
template <typename Scalar>
|
|
34
|
-
Eigen::Vector<Scalar, Eigen::Dynamic> lagrange_multiplier_estimate(
|
|
35
|
-
const Eigen::SparseVector<Scalar>& g,
|
|
36
|
-
const Eigen::SparseMatrix<Scalar>& A_e) {
|
|
37
|
-
// Lagrange multiplier estimates
|
|
38
|
-
//
|
|
39
|
-
// ∇f − Aₑᵀy = 0
|
|
40
|
-
// Aₑᵀy = ∇f
|
|
41
|
-
// y = (AₑAₑᵀ)⁻¹Aₑ∇f
|
|
42
|
-
return Eigen::SimplicialLDLT<Eigen::SparseMatrix<Scalar>>{A_e *
|
|
43
|
-
A_e.transpose()}
|
|
44
|
-
.solve(A_e * g);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/// Estimates Lagrange multipliers for interior-point method.
|
|
48
|
-
///
|
|
49
|
-
/// @tparam Scalar Scalar type.
|
|
50
|
-
/// @param g Cost function gradient ∇f.
|
|
51
|
-
/// @param A_e Equality constraint Jacobian Aₑ(x).
|
|
52
|
-
/// @param A_i Inequality constraint Jacobian Aᵢ(x).
|
|
53
|
-
/// @param s Inequality constraint slack variables.
|
|
54
|
-
/// @param μ Barrier parameter.
|
|
55
|
-
template <typename Scalar>
|
|
56
|
-
LagrangeMultiplierEstimate<Scalar> lagrange_multiplier_estimate(
|
|
57
|
-
const Eigen::SparseVector<Scalar>& g,
|
|
58
|
-
const Eigen::SparseMatrix<Scalar>& A_e,
|
|
59
|
-
const Eigen::SparseMatrix<Scalar>& A_i,
|
|
60
|
-
const Eigen::Vector<Scalar, Eigen::Dynamic>& s, Scalar μ) {
|
|
61
|
-
using DenseVector = Eigen::Vector<Scalar, Eigen::Dynamic>;
|
|
62
|
-
using SparseMatrix = Eigen::SparseMatrix<Scalar>;
|
|
63
|
-
|
|
64
|
-
// Lagrange multiplier estimates
|
|
65
|
-
//
|
|
66
|
-
// ∇f − Aₑᵀy − Aᵢᵀz = 0
|
|
67
|
-
// Sz − μe = 0
|
|
68
|
-
//
|
|
69
|
-
// Aₑᵀy + Aᵢᵀz = ∇f
|
|
70
|
-
// −Sz = −μe
|
|
71
|
-
//
|
|
72
|
-
// [Aₑᵀ Aᵢᵀ][y] = [ ∇f]
|
|
73
|
-
// [ 0 −S ][z] [−μe]
|
|
74
|
-
//
|
|
75
|
-
// [Aₑ 0]ᵀ[y] = [ ∇f]
|
|
76
|
-
// [Aᵢ −S] [z] [−μe]
|
|
77
|
-
//
|
|
78
|
-
// Let  = [Aₑ 0]
|
|
79
|
-
// [Aᵢ −S]
|
|
80
|
-
//
|
|
81
|
-
// Âᵀ[y] = [ ∇f]
|
|
82
|
-
// [z] [−μe]
|
|
83
|
-
//
|
|
84
|
-
// [y] = (ÂÂᵀ)⁻¹Â[ ∇f]
|
|
85
|
-
// [z] [−μe]
|
|
86
|
-
|
|
87
|
-
gch::small_vector<Eigen::Triplet<Scalar>> triplets;
|
|
88
|
-
|
|
89
|
-
// Â = [Aₑ 0]
|
|
90
|
-
// [Aᵢ −S]
|
|
91
|
-
triplets.reserve(A_e.nonZeros() + A_i.nonZeros() + s.rows());
|
|
92
|
-
append_as_triplets(triplets, 0, 0, {A_e, A_i});
|
|
93
|
-
append_diagonal_as_triplets(triplets, A_e.rows(), A_i.cols(), (-s).eval());
|
|
94
|
-
SparseMatrix A_hat{A_e.rows() + A_i.rows(), A_e.cols() + s.rows()};
|
|
95
|
-
A_hat.setFromSortedTriplets(triplets.begin(), triplets.end());
|
|
96
|
-
|
|
97
|
-
// lhs = ÂÂᵀ
|
|
98
|
-
SparseMatrix lhs = A_hat * A_hat.transpose();
|
|
99
|
-
|
|
100
|
-
// rhs = Â[ ∇f]
|
|
101
|
-
// [−μe]
|
|
102
|
-
DenseVector rhs_temp{g.rows() + s.rows()};
|
|
103
|
-
rhs_temp.segment(0, g.rows()) = g;
|
|
104
|
-
rhs_temp.segment(g.rows(), s.rows()).setConstant(-μ);
|
|
105
|
-
DenseVector rhs = A_hat * rhs_temp;
|
|
106
|
-
|
|
107
|
-
Eigen::SimplicialLDLT<SparseMatrix> yz_estimator{lhs};
|
|
108
|
-
DenseVector sol = yz_estimator.solve(rhs);
|
|
109
|
-
DenseVector y = sol.segment(0, A_e.rows());
|
|
110
|
-
DenseVector z = sol.segment(A_e.rows(), s.rows());
|
|
111
|
-
|
|
112
|
-
// A requirement for the convergence proof is that the primal-dual barrier
|
|
113
|
-
// term Hessian Σₖ₊₁ does not deviate arbitrarily much from the primal barrier
|
|
114
|
-
// term Hessian μSₖ₊₁⁻².
|
|
115
|
-
//
|
|
116
|
-
// Σₖ₊₁ = μSₖ₊₁⁻²
|
|
117
|
-
// Sₖ₊₁⁻¹Zₖ₊₁ = μSₖ₊₁⁻²
|
|
118
|
-
// Zₖ₊₁ = μSₖ₊₁⁻¹
|
|
119
|
-
//
|
|
120
|
-
// We ensure this by resetting
|
|
121
|
-
//
|
|
122
|
-
// zₖ₊₁ = clamp(zₖ₊₁, 1/κ_Σ μ/sₖ₊₁, κ_Σ μ/sₖ₊₁)
|
|
123
|
-
//
|
|
124
|
-
// for some fixed κ_Σ ≥ 1 after each step. See equation (16) of [2].
|
|
125
|
-
for (int row = 0; row < z.rows(); ++row) {
|
|
126
|
-
constexpr Scalar κ_Σ(1e10);
|
|
127
|
-
z[row] = std::clamp(z[row], Scalar(1) / κ_Σ * μ / s[row], κ_Σ * μ / s[row]);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return {std::move(y), std::move(z)};
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
} // namespace slp
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/pyproject.toml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/python/cpp/main.cpp
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sleipnirgroup_jormungandr-0.6.7.dev31 → sleipnirgroup_jormungandr-0.6.7.dev44}/src/util/pool.cpp
RENAMED
|
File without changes
|