You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe.
cuOpt's LP/QP solution exposes dual values (shadow prices) and reduced costs, but not basis / variable status (basic vs. nonbasic-at-lower-bound vs. nonbasic-at-upper-bound). Basis status is the standard companion to reduced costs in an LP sensitivity report: it tells you which variables are at a bound — where a reduced cost is a meaningful "this would enter / change if its coefficient improved by X" signal — versus basic / interior, where the reduced cost is ~0. Without it, code reading get_reduced_costs() can't cleanly tell a genuine near-miss from an interior variable.
This surfaced building solver-exact sensitivity/explainability on top of cuOpt (a downstream multi-objective decision layer): the at-bound-vs-basic distinction is load-bearing for interpreting reduced costs, and we currently have to reconstruct it heuristically from the primal values + variable bounds.
Describe the solution you'd like
A public accessor on the LP solution — e.g. get_variable_status() / get_constraint_status() (C++), with C API + Python equivalents — returning a public basis-status enum (BASIC / NONBASIC_LOWER / NONBASIC_UPPER / FIXED / FREE). The data already exists internally: the dual-simplex solver computes a full basis (variable_status_t / vstatus, cpp/src/dual_simplex/initial_basis.hpp). So the work is mainly (a) a public enum, (b) plumbing vstatus from the dual-simplex result through to the public optimization_problem_solution, (c) the getter + C API + cython bindings + tests.
Two design questions for maintainers:
Public enum shape — how to present the internal statuses (e.g. whether to expose SUPERBASIC/FIXED or fold them).
PDLP semantics — PDLP is basis-free, so the accessor would return UNKNOWN/unavailable unless the LP was solved by dual simplex (or crossover ran). Define the per-method behavior.
Describe alternatives you've considered
Reconstructing status downstream from the primal solution + bounds (what we do now) — brittle near bounds, and impossible to get right at degenerate points.
Inferring from reduced_cost == 0 — unreliable under degeneracy (basic variables can have zero reduced cost, and vice versa).
Natural predecessor to a sensitivity-ranging request (filed separately) — both build on the same dual-simplex basis and together complete the textbook LP sensitivity report (shadow price + reduced cost + status + ranges).
Discovered via cuOpt × Frontier integration testing (solver-exact duals in a multi-objective decision layer).
Related: the diet LP duals example (shadow prices + reduced costs) — NVIDIA/cuopt-examples#154 — surfaces exactly the reduced costs this status accessor would annotate (which foods are at a bound = near-misses vs basic/interior).
Is your feature request related to a problem? Please describe.
cuOpt's LP/QP solution exposes dual values (shadow prices) and reduced costs, but not basis / variable status (basic vs. nonbasic-at-lower-bound vs. nonbasic-at-upper-bound). Basis status is the standard companion to reduced costs in an LP sensitivity report: it tells you which variables are at a bound — where a reduced cost is a meaningful "this would enter / change if its coefficient improved by X" signal — versus basic / interior, where the reduced cost is ~0. Without it, code reading
get_reduced_costs()can't cleanly tell a genuine near-miss from an interior variable.This surfaced building solver-exact sensitivity/explainability on top of cuOpt (a downstream multi-objective decision layer): the at-bound-vs-basic distinction is load-bearing for interpreting reduced costs, and we currently have to reconstruct it heuristically from the primal values + variable bounds.
Describe the solution you'd like
A public accessor on the LP solution — e.g.
get_variable_status()/get_constraint_status()(C++), with C API + Python equivalents — returning a public basis-status enum (BASIC / NONBASIC_LOWER / NONBASIC_UPPER / FIXED / FREE). The data already exists internally: the dual-simplex solver computes a full basis (variable_status_t/vstatus,cpp/src/dual_simplex/initial_basis.hpp). So the work is mainly (a) a public enum, (b) plumbingvstatusfrom the dual-simplex result through to the publicoptimization_problem_solution, (c) the getter + C API + cython bindings + tests.Two design questions for maintainers:
Describe alternatives you've considered
reduced_cost == 0— unreliable under degeneracy (basic variables can have zero reduced cost, and vice versa).Additional context
VBasis/CBasis, HiGHSHighsBasis(col_status/row_status).Related: the diet LP duals example (shadow prices + reduced costs) — NVIDIA/cuopt-examples#154 — surfaces exactly the reduced costs this status accessor would annotate (which foods are at a bound = near-misses vs basic/interior).