This repository was archived by the owner on Sep 26, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 13
Add BFGS #92
Merged
Merged
Add BFGS #92
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
9fb2df4
add BfgsStrategy
fabinsch 4b09385
add unittests for BfgsStrategy
fabinsch 164f216
Apply suggestions from code review
fabinsch a182219
fix coding style BFGS
fabinsch fd78410
poc: integrate BFGS and solve ur5-ik
fabinsch fec7be8
update changelog
fabinsch 5a518e2
apply pre-commit
fabinsch 5999518
example: minimal loop
fabinsch e2b795f
remove unique ptr for bfgs
fabinsch 4e77657
switch case instead of if else
fabinsch 3d1f612
apply suggestions
fabinsch 40479af
hessian as input to `update` method
fabinsch fcc08db
Update CHANGELOG.md
fabinsch 2378b9a
add comments to test
fabinsch 072638a
update copyright as suggested
fabinsch 5404399
remove hessian matrix from `BFGSStrategy`
fabinsch 13291f2
replace templated specialization struct by `if constexpr`
fabinsch b28e377
Update bfgs-strategy.hpp
fabinsch File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| /// @file | ||
| /// @copyright Copyright (C) 2024-2025 INRIA | ||
| #pragma once | ||
| #include "proxsuite-nlp/fwd.hpp" | ||
|
|
||
| namespace proxsuite { | ||
| namespace nlp { | ||
|
|
||
| enum BFGSType { Hessian, InverseHessian }; | ||
|
|
||
| template <typename Scalar, BFGSType BFGS_TYPE = BFGSType::InverseHessian> | ||
| class BFGSStrategy { | ||
| PROXSUITE_NLP_DYNAMIC_TYPEDEFS(Scalar); | ||
|
|
||
| public: | ||
| BFGSStrategy() | ||
| : is_init(false), is_psd(false), x_prev(), g_prev(), s(), y(), | ||
| xx_transpose(), xy_transpose(), V(), VMinv(), VMinvVt(), | ||
| is_valid(false) {} | ||
|
|
||
| explicit BFGSStrategy(const int num_vars) | ||
| : is_init(false), is_psd(true), x_prev(VectorXs::Zero(num_vars)), | ||
| g_prev(VectorXs::Zero(num_vars)), s(VectorXs::Zero(num_vars)), | ||
| y(VectorXs::Zero(num_vars)), | ||
| xx_transpose(MatrixXs::Zero(num_vars, num_vars)), | ||
| xy_transpose(MatrixXs::Zero(num_vars, num_vars)), | ||
| V(MatrixXs::Zero(num_vars, num_vars)), | ||
| VMinv(MatrixXs::Zero(num_vars, num_vars)), | ||
| VMinvVt(MatrixXs::Zero(num_vars, num_vars)), is_valid(true) { | ||
| x_prev = VectorXs::Zero(num_vars); | ||
| g_prev = VectorXs::Zero(num_vars); | ||
| } | ||
|
|
||
| void init(const ConstVectorRef &x0, const ConstVectorRef &g0) { | ||
| if (!is_valid) { | ||
| throw std::runtime_error("Cannot initialize an invalid BFGSStrategy. Use " | ||
| "the constructor with num_vars first."); | ||
| } | ||
|
|
||
| x_prev = x0; | ||
| g_prev = g0; | ||
| is_init = true; | ||
| } | ||
|
|
||
| void update(const ConstVectorRef &x, const ConstVectorRef &g, | ||
| MatrixXs &hessian) { | ||
| if (!is_init) { | ||
| init(x, g); | ||
| return; | ||
| } | ||
| PROXSUITE_NLP_NOMALLOC_BEGIN; | ||
| s = x - x_prev; | ||
| y = g - g_prev; | ||
| const Scalar sy = s.dot(y); | ||
|
|
||
| if (sy > 0) { | ||
| if constexpr (BFGS_TYPE == BFGSType::InverseHessian) { | ||
| // Nocedal and Wright, Numerical Optimization, 2nd ed., p. 140, eqn 6.17 | ||
| // (BFGS update) | ||
| xx_transpose.noalias() = s * s.transpose(); | ||
| xy_transpose.noalias() = s * y.transpose(); | ||
| } else if constexpr (BFGS_TYPE == BFGSType::Hessian) { | ||
| // Nocedal and Wright, Numerical Optimization, 2nd ed., p. 139, eqn 6.13 | ||
| // (DFP update) | ||
| xx_transpose.noalias() = y * y.transpose(); | ||
| xy_transpose.noalias() = y * s.transpose(); | ||
| } | ||
|
|
||
fabinsch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| V.noalias() = MatrixXs::Identity(s.size(), s.size()) - xy_transpose / sy; | ||
| VMinv.noalias() = V * hessian; | ||
| VMinvVt.noalias() = VMinv * V.transpose(); | ||
| hessian.noalias() = VMinvVt + xx_transpose / sy; | ||
| is_psd = true; | ||
| } else { | ||
| is_psd = false; | ||
| PROXSUITE_NLP_WARN("Skipping BFGS update as s^Ty <= 0"); | ||
| } | ||
| x_prev = x; | ||
| g_prev = g; | ||
| PROXSUITE_NLP_NOMALLOC_END; | ||
| } | ||
| bool isValid() const { return is_valid; } | ||
|
|
||
| public: | ||
| bool is_init; | ||
| bool is_psd; | ||
|
|
||
| private: | ||
| VectorXs x_prev; // previous iterate | ||
| VectorXs g_prev; // previous gradient | ||
| VectorXs s; // delta iterate | ||
| VectorXs y; // delta gradient | ||
| // temporary variables to avoid dynamic memory allocation | ||
| MatrixXs xx_transpose; | ||
| MatrixXs xy_transpose; | ||
| MatrixXs V; | ||
| MatrixXs VMinv; | ||
| MatrixXs VMinvVt; | ||
| bool is_valid; | ||
| }; | ||
|
|
||
| } // namespace nlp | ||
| } // namespace proxsuite | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| /// @file | ||
| /// @copyright Copyright (C) 2024-2025 INRIA | ||
| #pragma once | ||
|
|
||
| #include <fmt/ostream.h> | ||
| #include <fmt/ranges.h> | ||
|
|
||
| namespace fmt { | ||
| template <> struct formatter<proxsuite::nlp::HessianApprox> { | ||
| template <typename ParseContext> constexpr auto parse(ParseContext &ctx) { | ||
| return ctx.begin(); | ||
| } | ||
|
|
||
| template <typename FormatContext> | ||
| auto format(const proxsuite::nlp::HessianApprox &hessian_approx, | ||
| FormatContext &ctx) const { | ||
| std::string name; | ||
| switch (hessian_approx) { | ||
| case proxsuite::nlp::HessianApprox::EXACT: | ||
| name = "EXACT"; | ||
| break; | ||
| case proxsuite::nlp::HessianApprox::GAUSS_NEWTON: | ||
| name = "GAUSS_NEWTON"; | ||
| break; | ||
| case proxsuite::nlp::HessianApprox::BFGS: | ||
| name = "BFGS"; | ||
| break; | ||
| case proxsuite::nlp::HessianApprox::IDENTITY: | ||
| name = "IDENTITY"; | ||
| break; | ||
| } | ||
| return format_to(ctx.out(), "{}", name); | ||
| } | ||
| }; | ||
| } // namespace fmt |
fabinsch marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.