Skip to content

Fix update() API for box-constrained dense QPs - #479

Merged
jorisv merged 15 commits into
Simple-Robotics:develfrom
pierfabre:fix-update-box-constrained-qp
Oct 16, 2026
Merged

jorisv merged 15 commits into
Simple-Robotics:develfrom
pierfabre:fix-update-box-constrained-qp

Conversation

@pierfabre

Copy link
Copy Markdown
Member

Changes

  • Allow updating an initialized box-constrained QP without providing l_box/u_box (the existing box constraints are preserved).
  • Continue to reject lazy update() -> init() for box-constrained QPs when no box constraints are provided.
  • Expose l_box and u_box in the Python dense QP model.
  • Fix the Python non-box init() binding signature so that H and g are optional, consistently with the box-constrained init(), preventing unexpected dispatch behavior.
  • Update the C++ and Python update_dense_qp examples to demonstrate:
    • keeping existing box constraints during an update;
    • updating the box constraints explicitly.

Motivation

Previously, the non-box update() path threw when called on an initialized box-constrained QP. This made it necessary to pass the box constraints at each update, even when they had not changed.

Before:

qp = proxsuite.proxqp.dense.QP(n, n_eq, n_in, True)
qp.init(H, g, A, b, C, l, u, l_box, u_box)

H_new, g_new, A_new, b_new, C_new, l_new, u_new = ...
# l_box/u_box unchanged

# qp.update(H_new, g_new, A_new, b_new, C_new, l_new, u_new)  # Would throw

qp.update(H_new, g_new, A_new, b_new, C_new, l_new, u_new, l_box, u_box)  # Forced to do this

Now:

qp = proxsuite.proxqp.dense.QP(n, n_eq, n_in, True)
qp.init(H, g, A, b, C, l, u, l_box, u_box)

H_new, g_new, A_new, b_new, C_new, l_new, u_new = ...
# l_box/u_box unchanged

qp.update(H_new, g_new, A_new, b_new, C_new, l_new, u_new)  # No longer throws

Question

Since l_box/u_box are initialized to -infinite_bound/+infinite_bound in the dense model constructor when box_constraints == true, could we also accept omitted l_box/u_box in init() and simply keep these default values, rather than throwing? Thanks!

Comment thread include/proxsuite/proxqp/dense/wrapper.hpp Outdated
Comment thread include/proxsuite/proxqp/dense/wrapper.hpp
@Lucas-Haubert

Copy link
Copy Markdown
Contributor

Hi @jorisv @pierfabre,

I agree with these ideas, and I propose the following changes, none of which break the API:

  1. Remove the throw in the lazy-init branch of the non-box update() (wrapper.hpp L738). Because it is redundant as Joris said, but also required for point 2).

  2. Remove the throw at the beginning of the non-box init() (wrapper.hpp L367). Together with point 1), this makes both init() and update() accept omitted l_box / u_box.

  3. Reduce code duplication between overloads. After 1) and 2), the non-box overloads of init() and update() behave exactly like the box overloads called with l_box = u_box = nullopt. The non-box overloads can therefore simply forward to the box ones.

  4. Fix a bug in box init() (wrapper.hpp L563), replacing l_box.reset() by u_box.reset().

Then, some extra tasks:

  1. Add unit tests that cover points 1) and 2).

  2. Add a CHANGELOG.md entry.

@pierfabre
pierfabre force-pushed the fix-update-box-constrained-qp branch from 6d92d55 to ec2ce42 Compare October 12, 2026 09:36
@pierfabre

Copy link
Copy Markdown
Member Author

Hey @Lucas-Haubert, @jorisv thanks for your comments, I applied them.
While at it, I also removed the duplicated l_box/u_box size checks in box init() and forwarded the omitted manual_minimal_H_eigenvalue in the lazy-init branch of box update().
One thing is still missing before merge though, the boxes are inactive in the new tests for now. With active boxes, the tests hit the bug fixed by #477. They pass with active boxes once the #477 fix is applied, so I'll update them as soon as #477 is merged.

@jorisv

jorisv commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

@pierfabre #477 is merged

@pierfabre
pierfabre force-pushed the fix-update-box-constrained-qp branch from 1b737c6 to 456394f Compare October 14, 2026 14:32
@pierfabre

Copy link
Copy Markdown
Member Author

@jorisv done!

jorisv
jorisv previously approved these changes Oct 15, 2026
@jorisv

jorisv commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

@pierfabre You must add yourself in the credit section

@jorisv
jorisv merged commit 9baa1b2 into Simple-Robotics:devel Oct 16, 2026
70 of 75 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants