Skip to content

API reference

The workflow is lift → Study.review → Study.solve → Study.check → Study.report.

stochlift.lift

Build the extensive form (deterministic equivalent) of a two-stage program.

The lift needs no knowledge of where the uncertain data enters the model. Each scenario is simply the user's own model built with that scenario's data; the first-stage columns are shared across scenarios and everything else is copied per scenario.

extensive_form(models, probs, is_first, risk=None)

The deterministic equivalent. With an active risk (see :mod:stochlift.risk) the objective is (1 - w) E[f] + w CVaR_alpha(f), linearized with one free column eta and one non-negative column per scenario after all model columns.

first_stage_row_report(models, is_first)

Rows that involve first-stage variables only but change with the scenario.

Such a row means uncertain data constrains a here-and-now decision; the extensive form then enforces it for every scenario at once.

stochlift.Study

A deterministic model plus an uncertainty specification.

solve()

check()

review(show=True)

report(outdir, figures=True)

out_of_sample(observations=None, n_boot=10000, seed=0)

Apply both first-stage decisions to observations that were not used to build scenarios.

These are the held-out rows of the history, an independent sample when the scenarios come from distributions, or observations when given.

stability(sizes=(5, 10, 20, 50), reps=10, seed=0)

Re-solve with reps random scenario samples of each size.

Reports the spread of the in-sample optimum and, when a hold-out set exists, the hold-out result of each sampled solution.

saa_gap(n=50, batches=20, seed=0)

Optimality-gap estimate for the stochastic solution (Mak, Morton and Wood, 1999).

The reference distribution is the specified distributions, the empirical distribution of the training history, or the scenario set, in that order. Each batch draws n scenarios and measures how much worse the solution is than the batch optimum; the mean over batches estimates an upper bound on the true gap.

risk_frontier(weights=(0.0, 0.25, 0.5, 0.75, 0.9, 1.0), alpha=None)

Mean-CVaR trade-off: solve with each CVaR weight and report the expected cost and the CVaR of the resulting decision on the scenario set (and out of sample when there is a hold-out set).

probe(keys=None, rel=0.1)

Where does each data key enter the model?

Every numeric entry under a key is shifted by rel and the model is rebuilt; the result counts the coefficients that changed, split into objective, constraint matrix, right-hand sides and variable bounds. With keys=None all numeric top-level keys are probed.

probe_uncertain(rel=0.1)

The same, but changing only the entries declared uncertain.

to_mpisppy()

Scenario names and a scenario_creator for mpi-sppy (see :mod:stochlift.export).

models(values=None)

model_for(values)

The user's model built with the uncertain entries set to values (cached).

mean_model()

stochlift.Results dataclass

stochlift.Spec dataclass

is_first_stage(name)

Match name against the patterns. Only * and ? are wildcards, so Pyomo-style names such as open[S1] can be matched by open[*].

stochlift.sample(data, distributions, n, seed=0, correlation=0.0)

A :class:ScenarioSet of n equally likely draws from distributions.

sample(DATA, {"yield": {"dist": "normal", "cv": 0.15}}, n=200, correlation=0.8)

stochlift.ScenarioSet dataclass

stochlift.explicit(base, scenarios)

Scenarios given by hand.

scenarios is a list of (probability, overrides) where overrides is a partial, nested copy of the data dictionary, e.g. (1/3, {"yield": {"wheat": 3.0, "corn": 3.6, "beets": 24}}).

stochlift.from_history(history, paths, method='empirical', n=None, seed=0)

Build scenarios from observations (one row per observation).

  • empirical: every observation is one equally likely scenario.
  • sample: n observations drawn with replacement, equally likely.
  • kmeans: n cluster centroids, weighted by cluster size. Centroids preserve the mean exactly but shrink the tails; compare against empirical on the hold-out set before trusting a small n.

stochlift.risk.Risk dataclass

value(costs, probs=None)

Risk-adjusted cost; inf if any scenario is infeasible (nan).

values_equal_weights(C)

Risk-adjusted cost of every row of C, each row an equally likely sample.

stochlift.export.to_pyomo(model, name='scenario')

A Pyomo ConcreteModel equivalent to a :class:~stochlift.model.LinearModel.

Variables are m.x[j] in column order (m.names[j] holds the original name); the objective is m.obj (minimize).

stochlift.to_linear_model(obj)

stochlift.LinearModel dataclass

same_as(other, tol=0.0)

Exact structural and numerical equality (used by the checks).

stochlift.solve(model, fixed=None, mip_gap=1e-06, time_limit=None, threads=1, solver='highs')

Solve model with HiGHS (default) or Gurobi. fixed maps column index -> value.

stochlift.diagnose.ScenarioInfeasible

Bases: SolveError

Some scenarios have no solution even with perfect information.

stochlift.diagnose.NoCommonFirstStage

Bases: SolveError

Every scenario is feasible on its own, but no first-stage decision suits them all.