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:nobservations drawn with replacement, equally likely.kmeans:ncluster centroids, weighted by cluster size. Centroids preserve the mean exactly but shrink the tails; compare againstempiricalon the hold-out set before trusting a smalln.
stochlift.risk.Risk
dataclass
¶
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.