-
Notifications
You must be signed in to change notification settings - Fork 208
Dual recovery for quadratic constaints in barrier method #1427
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -525,6 +525,9 @@ run_barrier(dual_simplex::user_problem_t<i_t, f_t>& user_problem, | |
| auto status = dual_simplex::solve_linear_program_with_barrier<i_t, f_t>( | ||
| user_problem, barrier_settings, timer.get_tic_start(), solution); | ||
|
|
||
| if (!user_problem.qc_dual_recovery.empty()) { | ||
| detail::project_barrier_qcqp_duals_to_model(user_problem, solution); | ||
| } | ||
|
Comment on lines
+528
to
+530
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Keep QC multipliers out of the blanket maximize sign flip.
Please either negate only the linear-row prefix during maximize post-processing, or apply the QC projection after that sign normalization step so the recovered suffix keeps its documented sign convention. 🤖 Prompt for AI AgentsSource: Coding guidelines |
||
| detail::project_barrier_solution_to_model_variables(user_problem, solution); | ||
|
|
||
| CUOPT_LOG_CONDITIONAL_INFO( | ||
|
|
@@ -1844,17 +1847,9 @@ optimization_problem_solution_t<i_t, f_t> solve_qcqp( | |
| method_t::Barrier); | ||
|
|
||
| if (has_qc) { | ||
| CUOPT_LOG_INFO("Dual variables for problems with quadratic constraints not returned."); | ||
| const f_t nan_val = std::numeric_limits<f_t>::quiet_NaN(); | ||
| auto stream = op_problem.get_handle_ptr()->get_stream(); | ||
| thrust::fill(rmm::exec_policy(stream), | ||
| solution.get_dual_solution().begin(), | ||
| solution.get_dual_solution().end(), | ||
| nan_val); | ||
| thrust::fill(rmm::exec_policy(stream), | ||
| solution.get_reduced_cost().begin(), | ||
| solution.get_reduced_cost().end(), | ||
| nan_val); | ||
| CUOPT_LOG_INFO( | ||
| "Quadratic-constraint dual multipliers recovered from barrier SOC solution " | ||
| "(linear rows + one entry per QCMATRIX row)."); | ||
| } | ||
|
|
||
| if (settings.sol_file != "") { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The apex check is absolute, so small-scale active cones recover a zero dual.
Any cone block with
||x||_inf <= 1e-6is treated as apex-degenerate andqc_multiplier_from_lorentz_soc_kktreturns0. That is scale dependent: a valid active cone atO(1e-9)is not the apex, but this path still zeroes the recovered QC multiplier. The recovery needs a relative/scale-aware degeneracy test, plus a near-zero denominator guard onx_head, instead of a fixed absolute cutoff.As per coding guidelines, "flag/verify degenerate apex handling and any near-zero/epsilon comparisons used to decide uniqueness of SOC multipliers" and "guard division by zero or near-zero without epsilon check."
🤖 Prompt for AI Agents
Source: Coding guidelines