Repository navigation
Description
Is your feature request related to a problem? Please describe.
cuOpt's LP/QP solution exposes dual values 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 says 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_cost() can't cleanly tell a genuine near-miss from an interior variable.
It is also the degeneracy signal: a basic variable at a bound flags a degenerate vertex, so a consumer can mark that dual directional rather than quote a non-unique number as precise. That trust-calibration is what matters most on large, degenerate models, and the prerequisite for any honest sensitivity layer.
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 reconstruct it heuristically from the primal values plus 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 and Python equivalents, returning a public basis-status enum (BASIC / NONBASIC_LOWER / NONBASIC_UPPER / FIXED / FREE, plus NO_BASIS when no basis exists). 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 plus C API, cython bindings, and tests.
Two design points for maintainers:
- Public enum shape. The internal
variable_status_tis{BASIC, NONBASIC_LOWER, NONBASIC_UPPER, NONBASIC_FREE, NONBASIC_FIXED, SUPERBASIC}. The call is whether to expose all of these or fold some (SUPERBASIC, or the FREE/FIXED split) into a leaner public enum. - PDLP semantics. For the PDLP path the accessor should return an explicit NO_BASIS status rather than a heuristic reconstruction. Since PDLP frequently wins the concurrent race, "no basis exists" is the common case, and an honest signal there is most of the feature's value: it tells the consumer these duals are tolerance-accurate approximations, not basis-exact.
Describe alternatives you've considered
- Reconstructing status downstream from the primal solution plus 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).
Additional context
- Companion to the merged skills-doc note on per-problem-type dual support: Note dual/sensitivity support per problem type in formulation skill #1393.
- Basis status is the more fundamental of the two gaps. It pairs with ranging ([FEA] LP sensitivity ranging (RHS + objective-coefficient ranges) #1395): a clean basis certifies the dual as a marginal rate valid within the current RHS range, and ranging supplies that range.
- Prior art: Gurobi
VBasis/CBasis, HiGHSHighsBasis(col_status/row_status). - Discovered via cuOpt × Frontier integration testing (solver-exact duals in a multi-objective decision layer).
Related: the diet LP duals example (dual values + 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).
Activity
Note dual/sensitivity support per problem type in formulation skill (#…
chris-maes commentedon Jun 9, 2026
How would you use the basis information (e.g. BASIC, NONBASIC_LOWER, NONBASIC_UPPER, FIXED, FREE) if cuOpt gave it to you?
cafzal commentedon Jun 10, 2026
@chris-maes, Frontier is my open-source multi-objective toolkit to help decision-makers navigate trade-offs using AI. I integrated cuOpt for the exact LP path, so it already reads your duals. Basis status would sharpen three calls the agent currently infers from the primal solution and bounds:
Action: The lever per option: NONBASIC_LOWER: 'it just missed, improve it.' NONBASIC_UPPER: 'hit a cap so raise it.' FIXED: 'keep off the near-miss list.'
Freedom: Where the choice is free, so a nonbasic variable at ~0 reduced cost is an alternative optimum. This requires a vertex.
Confidence: How far to trust each number, so the agent flags it directional vs. exact.
In this example, the duals already say improve-it / raise-the-cap / where-to-invest; basis status would make that exact at the bounds.
Happy to help scope or user test.