gtopt::LinearInterface class

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 value represents 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 value represents 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 source and deleting any rows beyond base_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_col(const std::string& name)

Adds a new column (variable) to the problem.

Parameters
name The name of the column
Returns The index of the newly added column

ColIndex gtopt::LinearInterface::add_col(const std::string& name, double collb, double colub)

Adds a new column (variable) with bounds to the problem.

Parameters
name The name of the column
collb Lower bound for the column
colub Upper bound for the column
Returns The index of the newly added column

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)

double gtopt::LinearInterface::get_coeff(RowIndex row, ColIndex column) const

Gets a coefficient value from the constraint matrix.

Parameters
row Row index of the coefficient
column Column index of the coefficient
Returns The coefficient value, or 0.0 if the element does not exist

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

double gtopt::LinearInterface::get_kappa() const

Gets the condition number of the basis matrix (if available)

Returns Condition number kappa, or 1.0 if not available

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_coeff(RowIndex row, ColIndex column, double value)

Sets (modifies) a coefficient in the constraint matrix.

Parameters
row Row index of the coefficient
column Column index of the coefficient
value New coefficient value

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

std::expected<void, Error> gtopt::LinearInterface::write_lp(const std::string& filename) const

Writes the problem to an LP format file.

Parameters
filename Name of the file to write (without extension)
Returns Success, or an error if row names are not available

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.