Skip to content

Hessian oracle#3153

Open
jajhall wants to merge 59 commits into
latestfrom
hessian-oracle
Open

Hessian oracle#3153
jajhall wants to merge 59 commits into
latestfrom
hessian-oracle

Conversation

@jajhall

@jajhall jajhall commented Jul 17, 2026

Copy link
Copy Markdown
Member

This allows the QP active set solve (QpAsm) and HiPO to operate using an oracle for the Hessian $$Q$$.

  • For HiPO, the oracle is used to generate the explicit Hessian
  • For QpAsm, the oracle will provide all data required during the course of the algorithm.

This oracle must be able to compute $$Qx$$, but there is greater efficiency if it can supply a column of the Hessian.

Also incorporates a method for users to check that their Hessian oracle is correct

C API methods have been written, and tested in check/testCAPI.c

Review of QpAsm identified the dense Cholesky code in highs/qpsolver/feasibility_bounded.hpp as being wholly incorrect, requiring a complete re-write.

Documentation is in C API header file, and check/TestQpOracle.cpp. Formal documentation will follow

Julian Hall added 30 commits June 26, 2026 23:43
@jajhall jajhall self-assigned this Jul 17, 2026
@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.01942% with 111 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.18%. Comparing base (8985537) to head (706eb3d).
⚠️ Report is 80 commits behind head on latest.

Files with missing lines Patch % Lines
highs/model/HighsHessian.cpp 79.86% 59 Missing ⚠️
highs/lp_data/Highs.cpp 83.45% 22 Missing ⚠️
check/TestCAPI.c 91.39% 8 Missing ⚠️
highs/qpsolver/matrix.hpp 96.12% 6 Missing ⚠️
check/TestQpOracle.cpp 98.71% 5 Missing ⚠️
highs/io/HMPSIO.cpp 66.66% 3 Missing ⚠️
highs/lp_data/HighsInterface.cpp 60.00% 2 Missing ⚠️
highs/qpsolver/feasibility_bounded.hpp 96.82% 2 Missing ⚠️
highs/qpsolver/scaling.cpp 0.00% 2 Missing ⚠️
highs/lp_data/HighsOptions.h 75.00% 1 Missing ⚠️
... and 1 more
Additional details and impacted files
@@            Coverage Diff             @@
##           latest    #3153      +/-   ##
==========================================
- Coverage   73.19%   73.18%   -0.02%     
==========================================
  Files         430      432       +2     
  Lines      104154   105459    +1305     
  Branches    16738    16982     +244     
==========================================
+ Hits        76239    77180     +941     
- Misses      27639    28003     +364     
  Partials      276      276              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jajhall
jajhall marked this pull request as ready for review July 18, 2026 23:54
@jajhall jajhall added Enhancement New feature or request QP labels Jul 18, 2026
@jajhall
jajhall requested a review from filikat July 18, 2026 23:55
pdlp_cupdlpc_restart_method(0),
pdlp_step_size_strategy(0),
pdlp_optimality_tolerance(0.0),
test_qp_oracle(false),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this options supposed to be here? Or is it just for development?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the unit tests I wanted to have it on and off, but I'll change it to a const bool internally. Thanks

HighsCHessianFunctionType oracleCall,
void* oracle_data) {
auto status =
static_cast<Highs*>(highs)->passHessian(dim, oracleCall, oracle_data);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you are passing the HighsCHessianFunctionType as second argument to passHessian (hence casting to HighsHessianFunctionType), while there is an unused fourth argument which takes exactly HighsCHessianFunctionType.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, I think std::function can be constructed from a C-style function pointer if the signatures are exactly the same, so this may be totally fine and the fourth argument of passHessian may actually not be needed at all.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I just followed what was done for the call-backs, but then the C-style function pointer had to be retrofitted.

@filikat filikat Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see, then it's fine if it's consistent with the rest of the callbacks.

Comment thread highs/lp_data/HStruct.h
void clear();
bool isValid() const { return hasProductCall(); }
bool hasProductCall() const;
void formFromOracle();

@filikat filikat Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formFromOracle is unused, as you are doing it as part of HighsHessian and not HessianOracle

@filikat

filikat commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Looks great, apart from minor things and documentation to be added later.
I didn't check the changes in qpsolver though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement New feature or request QP

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants