LinearInterface class
#include <gtopt/linear_interface.hpp>
Constructors, destructors, conversion operators
- LinearInterface(const LinearInterface&) deleted explicit
- Copy constructor disabled.
- LinearInterface(LinearInterface&&) defaulted
- Move constructor.
- LinearInterface(std::string_view solver_name, const FlatLinearProblem& flat_lp, const std::string& plog_file = {})
- Constructs interface, loads a problem, with solver by name.
- LinearInterface(std::string_view solver_name = {}, const std::string& plog_file = {}) explicit
- Constructs interface with a solver backend by name.
- LinearInterface(std::unique_ptr<SolverBackend> backend, std::string plog_file = {}) explicit
- Constructs interface with a pre-created backend.
- ~LinearInterface() defaulted
Public functions
- auto add_col(const std::string& name) -> ColIndex
- Adds a new column (variable) to the problem.
- auto add_col(const std::string& name, double collb, double colub) -> ColIndex
- Adds a new column (variable) with bounds to the problem.
- auto add_free_col(const std::string& name) -> ColIndex
- Adds a new unbounded column (free variable) to the problem.
- auto add_row(const SparseRow& row, double eps = 0.0) -> RowIndex
- Adds a new constraint row to the problem.
-
auto base_numrows() const -> constexpr size_
t noexcept - Get the saved base row count.
- auto clone() const -> LinearInterface
- Creates a deep copy of this LinearInterface via the backend's clone() method.
- auto delete_rows(std::span<const int> indices) -> void
- Deletes rows by index from the constraint matrix.
- auto get_algorithm() const -> LPAlgo
- Currently configured LP algorithm.
- auto get_coeff(RowIndex row, ColIndex column) const -> double
- Gets a coefficient value from the constraint matrix.
- auto get_col_cost() const -> ScaledView noexcept
- Gets physical reduced costs (LP / col_scale).
- auto get_col_cost_raw() const -> auto
- Gets raw LP reduced costs (no descaling).
- auto get_col_low() const -> auto
- Gets the lower bounds for all variable columns.
- auto get_col_scale(ColIndex index) const -> constexpr double noexcept
- Gets the physical-to-LP scale factor for a single column.
- auto get_col_scales() const -> constexpr const auto& noexcept
- Gets all column scale factors.
- auto get_col_sol() const -> ScaledView noexcept
- Gets physical solution values (LP × col_scale).
- auto get_col_sol_raw() const -> auto
- Gets raw LP solution values (no descaling).
- auto get_col_upp() const -> auto
- Gets the upper bounds for all variable columns.
- auto get_kappa() const -> double
- Gets the condition number of the basis matrix (if available)
- auto get_log_file() const -> constexpr const auto&
- auto get_log_level() const -> int
- Current solver log verbosity level (0 = off).
-
auto get_numcols() const -> size_
t - Gets the number of variable columns in the problem.
-
auto get_numrows() const -> size_
t - Gets the number of constraint rows in the problem.
- auto get_obj_coeff() const -> auto
- auto get_obj_value() const -> double
- auto get_presolve() const -> bool
- Whether presolve is currently enabled.
- auto get_prob_name() const -> std::string
- auto get_row_dual() const -> ScaledView noexcept
- Gets physical dual values (shadow prices).
- auto get_row_dual_raw() const -> auto
- Gets raw solver dual values (no descaling).
- auto get_row_low() const -> auto
- Gets the lower bounds for all constraint rows.
- auto get_row_scale(RowIndex index) const -> constexpr double noexcept
- Gets the row equilibration scale factor for a single row.
- auto get_row_scales() const -> constexpr const auto& noexcept
- Gets all row equilibration scale factors.
- auto get_row_upp() const -> auto
- Gets the upper bounds for all constraint rows.
- auto get_status() const -> int
- Gets the solver-specific status code.
- auto get_threads() const -> int
- Currently configured thread count (0 = solver default).
- auto infinity() const -> double noexcept
- Solver's representation of +infinity for variable bounds.
- auto initial_solve(const SolverOptions& solver_options = {}) -> std::expected<int, Error>
- Performs initial solve of the problem from scratch.
- auto is_continuous(ColIndex index) const -> bool
- Checks if a variable is continuous.
- auto is_dual_infeasible() const -> bool
- Checks if the problem is dual infeasible.
- auto is_integer(ColIndex index) const -> bool
- Checks if a variable is integer.
- auto is_neg_inf(double value) const -> bool noexcept
- True if
valuerepresents negative infinity for the active solver. - auto is_optimal() const -> bool
- Checks if the solution is optimal.
- auto is_pos_inf(double value) const -> bool noexcept
- True if
valuerepresents positive infinity for the active solver. - auto is_prim_infeasible() const -> bool
- Checks if the problem is primal infeasible.
- auto load_flat(const FlatLinearProblem& flat_lp) -> void
- Loads a flattened linear problem into the solver.
- auto lp_names_level() const -> constexpr int noexcept
- Gets the current LP name uniqueness-check level.
- auto normalize_bound(double value) const -> double noexcept
- auto operator=(const LinearInterface&) -> LinearInterface& deleted
- Copy assignment disabled.
- auto operator=(LinearInterface&&) -> LinearInterface& defaulted
- Move assignment.
-
auto reset_from(const LinearInterface& source,
size_
t base_rows) -> void - Reset this LP to a base state by copying column bounds from
sourceand deleting any rows beyondbase_rows. - auto resolve(const SolverOptions& solver_options = {}) -> std::expected<int, Error>
- Resolves the problem with updated data using warm start.
- auto save_base_numrows() -> void noexcept
- Save the current row count as the "base" model size.
- auto set_binary(ColIndex index) -> void
- Sets a variable to be binary (0-1 integer)
- auto set_coeff(RowIndex row, ColIndex column, double value) -> void
- Sets (modifies) a coefficient in the constraint matrix.
- auto set_col(ColIndex index, double value) -> void
- auto set_col_low(ColIndex index, double value) -> void
- auto set_col_sol(std::span<const double> sol) -> void
- auto set_col_upp(ColIndex index, double value) -> void
- auto set_continuous(ColIndex index) -> void
- Sets a variable to be continuous (floating-point)
- auto set_integer(ColIndex index) -> void
- Sets a variable to be integer.
- auto set_log_file(const std::string& plog_file) -> void
- auto set_lp_names_level(int level) -> void noexcept
- Sets the LP name uniqueness-check level.
- auto set_obj_coeff(ColIndex index, double value) -> void
- auto set_prob_name(const std::string& pname) -> void
- auto set_rhs(RowIndex row, double rhs) -> void
- auto set_row_dual(std::span<const double> dual) -> void
- auto set_row_low(RowIndex index, double value) -> void
- auto set_row_upp(RowIndex index, double value) -> void
- auto set_time_limit(double time_limit) -> void
- Sets a time limit for the solver.
- auto set_warm_start_solution(std::span<const double> col_sol, std::span<const double> row_dual) -> void
- Apply a saved solution as warm-start hint for the next resolve.
- auto solver_id() const -> std::string
- Solver identifier: "name/version" (e.g. "highs/1.13.1").
- auto solver_name() const -> std::string_view noexcept
- Solver backend name (e.g. "clp", "cplex", "highs").
- auto solver_version() const -> std::string
- Solver library version string (e.g. "1.17.3").
- auto supports_set_coeff() const -> bool noexcept
- Checks whether the solver supports in-place coefficient updates.
- auto write_lp(const std::string& filename) const -> std::expected<void, Error>
- Writes the problem to an LP format file.
Name-to-index maps (col: level >= 0, row: level >= 1)
-
using name_index_map_t = std::unordered_map<std::string, int32_
t> - Row (constraint) name → row index map.
-
auto row_name_map() const -> constexpr const name_
index_ map_ t& noexcept -
auto col_name_map() const -> constexpr const name_
index_ map_ t& noexcept - auto col_index_to_name() const -> constexpr const auto& noexcept
- auto row_index_to_name() const -> constexpr const auto& noexcept
Warm column solution (hot-start state)
- auto warm_col_sol() const -> constexpr const auto& noexcept
- Return the warm column solution vector (empty if no state loaded).
- auto set_warm_col_sol(StrongIndexVector<ColIndex, double> sol) -> void noexcept
- Set the warm column solution from a loaded state file.
LP coefficient statistics (populated during load_flat from
FlatLinearProblem::stats_* fields, which are computed in LinearProblem::flatten when LpMatrixOptions::compute_stats is true).
-
auto lp_stats_nnz() const -> constexpr size_
t noexcept -
auto lp_stats_zeroed() const -> constexpr size_
t noexcept - auto lp_stats_max_abs() const -> constexpr double noexcept
- auto lp_stats_min_abs() const -> constexpr double noexcept
-
auto lp_stats_max_col() const -> constexpr FlatLinearProblem::
index_t noexcept -
auto lp_stats_min_col() const -> constexpr FlatLinearProblem::
index_t noexcept - auto lp_stats_max_col_name() const -> constexpr const std::string& noexcept
- auto lp_stats_min_col_name() const -> constexpr const std::string& noexcept
- auto lp_row_type_stats() const -> constexpr const auto& noexcept
Function documentation
gtopt:: LinearInterface:: LinearInterface(std::string_view solver_name,
const FlatLinearProblem& flat_lp,
const std::string& plog_file = {})
Constructs interface, loads a problem, with solver by name.
| Parameters | |
|---|---|
| solver_name | Solver identifier |
| flat_lp | Flattened linear problem to load |
| plog_file | Path to log file for solver output |
gtopt:: LinearInterface:: LinearInterface(std::string_view solver_name = {},
const std::string& plog_file = {}) explicit
Constructs interface with a solver backend by name.
| Parameters | |
|---|---|
| solver_name | Solver identifier ("clp", "cbc", "cplex", "highs") |
| plog_file | Path to log file for solver output |
gtopt:: LinearInterface:: LinearInterface(std::unique_ptr<SolverBackend> backend,
std::string plog_file = {}) explicit
Constructs interface with a pre-created backend.
| Parameters | |
|---|---|
| backend | Pre-configured solver backend |
| plog_file | Path to log file for solver output |
ColIndex gtopt:: LinearInterface:: add_free_col(const std::string& name)
Adds a new unbounded column (free variable) to the problem.
| Parameters | |
|---|---|
| name | The name of the column |
| Returns | The index of the newly added column |
RowIndex gtopt:: LinearInterface:: add_row(const SparseRow& row,
double eps = 0.0)
Adds a new constraint row to the problem.
| Parameters | |
|---|---|
| row | The sparse row representation of the constraint |
| eps | Epsilon value for coefficient filtering (values below this are ignored) |
| Returns | The index of the newly added row |
constexpr size_ t gtopt:: LinearInterface:: base_numrows() const noexcept
Get the saved base row count.
| Returns | Base row count (0 if save_base_numrows was never called) |
|---|
LinearInterface gtopt:: LinearInterface:: clone() const
Creates a deep copy of this LinearInterface via the backend's clone() method.
| Returns | A new LinearInterface wrapping the cloned solver. |
|---|
The clone preserves the full LP state (variables, constraints, bounds, objective, warm-start basis). Modifications to the clone do not affect the original — use this for tentative solves such as the SDDP elastic filter, where the original LP must remain unmodified.
void gtopt:: LinearInterface:: delete_rows(std::span<const int> indices)
Deletes rows by index from the constraint matrix.
| Parameters | |
|---|---|
| indices | Row indices to delete (must be sorted ascending) |
ScaledView gtopt:: LinearInterface:: get_col_cost() const noexcept
Gets physical reduced costs (LP / col_scale).
| Returns | ScaledView over solver reduced-cost memory |
|---|
Returns a zero-copy lazy view: each access computes LP_rc / col_scale on the fly.
auto gtopt:: LinearInterface:: get_col_cost_raw() const
Gets raw LP reduced costs (no descaling).
| Returns | Span view of raw LP reduced costs |
|---|
auto gtopt:: LinearInterface:: get_col_low() const
Gets the lower bounds for all variable columns.
| Returns | Span view of column lower bounds |
|---|
constexpr double gtopt:: LinearInterface:: get_col_scale(ColIndex index) const noexcept
Gets the physical-to-LP scale factor for a single column.
| Parameters | |
|---|---|
| index | Column index |
| Returns | Scale factor (1.0 if col_scales is empty or not populated) |
physical_value = LP_value × scale. A scale of 1.0 means no scaling (LP variable == physical value). Scale factors are populated during load_flat() from FlatLinearProblem::col_scales.
constexpr const auto& gtopt:: LinearInterface:: get_col_scales() const noexcept
Gets all column scale factors.
| Returns | Const reference to the column scale vector (empty if not populated) |
|---|
ScaledView gtopt:: LinearInterface:: get_col_sol() const noexcept
Gets physical solution values (LP × col_scale).
| Returns | ScaledView over solver solution memory |
|---|
Returns a zero-copy lazy view: each access computes LP_value × col_scale on the fly. When col_scales are empty, returns raw values unchanged.
auto gtopt:: LinearInterface:: get_col_sol_raw() const
Gets raw LP solution values (no descaling).
| Returns | Span view of raw LP solution values |
|---|
Returns solver values as-is, in LP units. Use this for SDDP state propagation, cut generation, and any internal LP algebra that operates in scaled coordinates.
auto gtopt:: LinearInterface:: get_col_upp() const
Gets the upper bounds for all variable columns.
| Returns | Span view of column upper bounds |
|---|
size_ t gtopt:: LinearInterface:: get_numcols() const
Gets the number of variable columns in the problem.
| Returns | Number of columns |
|---|
size_ t gtopt:: LinearInterface:: get_numrows() const
Gets the number of constraint rows in the problem.
| Returns | Number of rows |
|---|
ScaledView gtopt:: LinearInterface:: get_row_dual() const noexcept
Gets physical dual values (shadow prices).
| Returns | Zero-copy lazy view: dual_LP / row_scale per element. |
|---|
When row equilibration is active, the raw solver duals are divided by the per-row scale factor to recover physical units. Row equilibration divides each row by s = max|coeff|, so the LP dual is π_LP = s × π_phys, hence π_phys = π_LP / s.
auto gtopt:: LinearInterface:: get_row_dual_raw() const
Gets raw solver dual values (no descaling).
| Returns | Span view of raw solver dual values |
|---|
Returns solver duals as-is. Use this for internal LP algebra that operates in solver coordinates (e.g. cut coefficient computation where row equilibration is accounted for separately).
auto gtopt:: LinearInterface:: get_row_low() const
Gets the lower bounds for all constraint rows.
| Returns | Span view of row lower bounds |
|---|
constexpr double gtopt:: LinearInterface:: get_row_scale(RowIndex index) const noexcept
Gets the row equilibration scale factor for a single row.
| Parameters | |
|---|---|
| index | Row index |
| Returns | Scale factor (1.0 if row_scales is empty or not populated) |
Row equilibration divides each row by s = max|coeff|, so the LP dual is π_LP = s × π_phys. get_row_scale() returns s.
constexpr const auto& gtopt:: LinearInterface:: get_row_scales() const noexcept
Gets all row equilibration scale factors.
| Returns | Const reference to the row scale vector (empty if not populated) |
|---|
auto gtopt:: LinearInterface:: get_row_upp() const
Gets the upper bounds for all constraint rows.
| Returns | Span view of row upper bounds |
|---|
int gtopt:: LinearInterface:: get_status() const
Gets the solver-specific status code.
| Returns | Status code (interpretation depends on solver) |
|---|
std::expected<int, Error> gtopt:: LinearInterface:: initial_solve(const SolverOptions& solver_options = {})
Performs initial solve of the problem from scratch.
| Parameters | |
|---|---|
| solver_options | Options controlling the solve process |
| Returns | Expected with solver status code (0 = optimal) or error |
bool gtopt:: LinearInterface:: is_continuous(ColIndex index) const
Checks if a variable is continuous.
| Parameters | |
|---|---|
| index | Column index to check |
| Returns | True if continuous, false otherwise |
bool gtopt:: LinearInterface:: is_dual_infeasible() const
Checks if the problem is dual infeasible.
| Returns | True if dual infeasible, false otherwise |
|---|
bool gtopt:: LinearInterface:: is_integer(ColIndex index) const
Checks if a variable is integer.
| Parameters | |
|---|---|
| index | Column index to check |
| Returns | True if integer, false otherwise |
bool gtopt:: LinearInterface:: is_optimal() const
Checks if the solution is optimal.
| Returns | True if optimal solution found, false otherwise |
|---|
bool gtopt:: LinearInterface:: is_prim_infeasible() const
Checks if the problem is primal infeasible.
| Returns | True if primal infeasible, false otherwise |
|---|
void gtopt:: LinearInterface:: load_flat(const FlatLinearProblem& flat_lp)
Loads a flattened linear problem into the solver.
| Parameters | |
|---|---|
| flat_lp | The flattened problem representation |
| Exceptions | |
| std::runtime_error | if the problem cannot be loaded |
constexpr int gtopt:: LinearInterface:: lp_names_level() const noexcept
Gets the current LP name uniqueness-check level.
| Returns | 0-2 level (see set_lp_names_level) |
|---|
double gtopt:: LinearInterface:: normalize_bound(double value) const noexcept
Normalize a bound value: map gtopt::DblMax to the solver's infinity.
SparseCol/SparseRow use std::numeric_limits<double>::max() as default unbounded markers, but solver backends (e.g. HiGHS) may use a smaller infinity threshold (e.g. 1e30). This method translates at the LinearInterface boundary so that formulation code and solver agree.
void gtopt:: LinearInterface:: reset_from(const LinearInterface& source,
size_ t base_rows)
Reset this LP to a base state by copying column bounds from source and deleting any rows beyond base_rows.
| Parameters | |
|---|---|
| source | The original (unmodified) LP to copy bounds from |
| base_rows | Number of structural rows to keep (delete beyond) |
Used by the clone pool to reuse a cached LP clone across aperture solves without re-allocating the underlying solver.
std::expected<int, Error> gtopt:: LinearInterface:: resolve(const SolverOptions& solver_options = {})
Resolves the problem with updated data using warm start.
| Parameters | |
|---|---|
| solver_options | Options controlling the solve process |
| Returns | Expected with solver status code (0 = optimal) or error |
void gtopt:: LinearInterface:: save_base_numrows() noexcept
Save the current row count as the "base" model size.
All rows added after this point are considered cuts and are eligible for pruning. Must be called once after the structural LP is built, before any Benders cuts are added.
void gtopt:: LinearInterface:: set_binary(ColIndex index)
Sets a variable to be binary (0-1 integer)
| Parameters | |
|---|---|
| index | Column index to modify |
void gtopt:: LinearInterface:: set_continuous(ColIndex index)
Sets a variable to be continuous (floating-point)
| Parameters | |
|---|---|
| index | Column index to modify |
void gtopt:: LinearInterface:: set_integer(ColIndex index)
Sets a variable to be integer.
| Parameters | |
|---|---|
| index | Column index to modify |
void gtopt:: LinearInterface:: set_lp_names_level(int level) noexcept
Sets the LP name uniqueness-check level.
| Parameters | |
|---|---|
| level | The LP name check level (matches names_level semantics) |
Controls name tracking and duplicate detection for add_row()/add_col():
- 0: col names tracked, row names disabled
- 1: col + row names tracked, warn on duplicate names via spdlog
- 2: col + row names tracked + throw std::runtime_error on duplicates
Col name-to-index maps are populated at level >= 0. Row name-to-index maps are populated at level >= 1. The overhead is a single map insert per add_row/add_col call.
void gtopt:: LinearInterface:: set_time_limit(double time_limit)
Sets a time limit for the solver.
| Parameters | |
|---|---|
| time_limit | Maximum solve time in seconds |
void gtopt:: LinearInterface:: set_warm_start_solution(std::span<const double> col_sol,
std::span<const double> row_dual)
Apply a saved solution as warm-start hint for the next resolve.
| Parameters | |
|---|---|
| col_sol | Primal solution to set (empty = skip) |
| row_dual | Dual solution to set (empty = skip) |
Handles dimension mismatches gracefully: if the LP has gained extra columns (e.g. elastic slack variables) or extra rows (e.g. Benders cuts) since the solution was captured, the vectors are zero-padded to match. If the saved vector is larger than the current LP dimension it is silently ignored (stale snapshot).
bool gtopt:: LinearInterface:: supports_set_coeff() const noexcept
Checks whether the solver supports in-place coefficient updates.
| Returns | true if set_coeff() is functional |
|---|
constexpr const auto& gtopt:: LinearInterface:: col_index_to_name() const noexcept
Column index → name vector (empty string for unnamed columns). Populated alongside col_name_map when lp_names_level >= 1.
constexpr const auto& gtopt:: LinearInterface:: row_index_to_name() const noexcept
Row index → name vector (empty string for unnamed rows). Populated alongside row_name_map when lp_names_level >= 1.