Solvers¶
All solvers follow the scenario approach pattern:
Collect N random scenarios \(\delta_1, \ldots, \delta_N\)
Formulate a convex program with soft scenario constraints \(A(\delta_i)x + b(\delta_i) \leq \zeta_i\)
Solve with slack variables \(\zeta\) penalized by \(\rho\)
Identify active (support) constraints to determine complexity k
Quantify the risk of constraint violation via Risk Quantification
All solvers accept optional regularization (\(\tau \|x - x_\text{ref}\|_p\)) and hard constraints that are not relaxed by slack variables.
Linear Programming¶
- src.LP.solve_lp(deltas, A_d, b_d, G, h, c, tau=0.0, x_ref=numpy.array, rho=0.0, norm_type=2, solver=None, include_slack=None)[source]¶
Solve a linear program with scenario constraints via the scenario approach.
\[\min \quad c^\top x \;+\; \tau \|x - x_{\text{ref}}\|_p \;+\; \rho \sum_i \zeta_i\]\[\text{s.t.} \quad A(\delta_i)\, x + b(\delta_i) \;\leq\; \zeta_i, \quad i = 1,\ldots,N\]\[G\, x + h \;\leq\; 0\]- Parameters:
deltas (numpy.ndarray) – Scenario samples with shape
(N,)or(N, q)where N is the number of scenarios and q is the uncertainty dimension.A_d (callable) – Function mapping a scenario to the constraint coefficient matrix,
A_d(delta) -> (m_s, n)array.b_d (callable) – Function mapping a scenario to the constraint right-hand-side vector,
b_d(delta) -> (m_s, 1)array.G (numpy.ndarray) – Coefficient matrix for hard (non-scenario) constraints. Pass
np.array([])if there are none.h (numpy.ndarray) – Right-hand-side vector for hard constraints. Pass
np.array([])if there are none.c (numpy.ndarray) – Linear objective coefficient vector with shape
(n, 1).tau (float, optional) – Regularization strength toward x_ref. Default is
0.0.x_ref (numpy.ndarray, optional) – Reference point for the regularization term. Default is
[0.0].rho (float, optional) – Penalty on slack variables. When
0.0the scenario constraints are hard. Default is0.0.norm_type (int, float or str, optional) – Order p of the vector norm in the regularization term: any number
p >= 1,'inf'or'fro'(Euclidean). Default is2.solver (str or None, optional) – CVXPY solver name.
Nonefor automatic selection.include_slack (bool or None, optional) – Whether to add the slack variables ζ_i (the relaxation formulation).
Noneadds them only whenrho != 0.
- Returns:
x (numpy.ndarray) – Optimal decision variable vector.
zeta (numpy.ndarray) – Optimal slack variable values (one per scenario).
cost (float) – Optimal objective value.
N (int) – Number of scenarios used.
complexity (int) – Cardinality of the support list (violated plus retained active scenario constraints).
constraints (list) – Scenario constraint objects (one per scenario; hard constraints are kept separate).
degeneracy (bool) –
Trueif degeneracy was detected during support identification.
- Raises:
ValueError – If
deltasis empty, or the solver does not reach an optimal or near-optimal status.
Quadratic Programming¶
- src.QP.solve_qp(deltas, A_d, b_d, G, h, c, Q, tau=0.0, x_ref=numpy.array, rho=0.0, norm_type=2, solver=None, include_slack=None)[source]¶
Solve a quadratic program with scenario constraints via the scenario approach.
\[\min \quad \tfrac{1}{2}\, x^\top Q\, x \;+\; c^\top x \;+\; \tau \|x - x_{\text{ref}}\|_p \;+\; \rho \sum_i \zeta_i\]\[\text{s.t.} \quad A(\delta_i)\, x + b(\delta_i) \;\leq\; \zeta_i, \quad i = 1,\ldots,N\]\[G\, x + h \;\leq\; 0\]- Parameters:
deltas (numpy.ndarray) – Scenario samples with shape
(N,)or(N, q)where N is the number of scenarios and q is the uncertainty dimension.A_d (callable) – Function mapping a scenario to the constraint coefficient matrix,
A_d(delta) -> (m_s, n)array.b_d (callable) – Function mapping a scenario to the constraint right-hand-side vector,
b_d(delta) -> (m_s, 1)array.G (numpy.ndarray) – Coefficient matrix for hard (non-scenario) constraints. Pass
np.array([])if there are none.h (numpy.ndarray) – Right-hand-side vector for hard constraints. Pass
np.array([])if there are none.c (numpy.ndarray) – Linear objective coefficient vector with shape
(n, 1).Q (numpy.ndarray) – Quadratic cost matrix with shape
(n, n). Must be positive semidefinite and symmetric.tau (float, optional) – Regularization strength toward x_ref. Default is
0.0.x_ref (numpy.ndarray, optional) – Reference point for the regularization term. Default is
[0.0].rho (float, optional) – Penalty on slack variables. When
0.0the scenario constraints are hard. Default is0.0.norm_type (int, float or str, optional) – Order p of the vector norm in the regularization term: any number
p >= 1,'inf'or'fro'(Euclidean). Default is2.solver (str or None, optional) – CVXPY solver name.
Nonefor automatic selection.include_slack (bool or None, optional) – Whether to add the slack variables ζ_i (the relaxation formulation).
Noneadds them only whenrho != 0.
- Returns:
x (numpy.ndarray) – Optimal decision variable vector.
zeta (numpy.ndarray) – Optimal slack variable values (one per scenario).
cost (float) – Optimal objective value.
N (int) – Number of scenarios used.
complexity (int) – Cardinality of the support list (violated plus retained active scenario constraints).
constraints (list) – Scenario constraint objects (one per scenario; hard constraints are kept separate).
degeneracy (bool) –
Trueif degeneracy was detected during support identification.
- Raises:
ValueError – If the solver does not reach an optimal or near-optimal status.
AssertionError – If Q is not positive semidefinite or not symmetric.
Semidefinite Programming¶
- src.SDP.solve_sdp(deltas, F_d, E, c, Q, tau=0.0, x_ref=numpy.array, rho=0.0, norm_type=2, solver=None, include_slack=None)[source]¶
Solve a semidefinite program with LMI scenario constraints via the scenario approach.
\[\min \quad \tfrac{1}{2}\, x^\top Q\, x \;+\; c^\top x \;+\; \tau \|x - x_{\text{ref}}\|_p \;+\; \rho \sum_i \zeta_i\]\[\text{s.t.} \quad F_0(\delta_i) + \sum_j x_j\, F_j(\delta_i) \;\preceq\; \zeta_i\, I, \quad i = 1,\ldots,N\]\[E_0 + \sum_j x_j\, E_j \;\preceq\; 0\]- Parameters:
deltas (numpy.ndarray) – Scenario samples with shape
(N,)or(N, q)where N is the number of scenarios and q is the uncertainty dimension.F_d (callable) – Function mapping a scenario to a dict of symmetric matrices keyed by variable index (
'0'for the constant term,'1'for \(x_1\), etc.):F_d(delta) -> {'0': F0, '1': F1, ...}. Integer keys (0, 1, ...) work too.E (dict or None) – Dict of symmetric matrices for the hard LMI constraint, same key format as F_d output. Pass
Noneif there are no hard constraints.c (numpy.ndarray) – Linear objective coefficient vector with shape
(n,).Q (numpy.ndarray or None) – Quadratic cost matrix with shape
(n, n). Must be positive semidefinite and symmetric.Noneor an empty array means no quadratic term.tau (float, optional) – Regularization strength toward x_ref. Default is
0.0.x_ref (numpy.ndarray, optional) – Reference point for the regularization term. Default is
[0.0].rho (float, optional) – Penalty on slack variables. When
0.0the scenario constraints are hard. Default is0.0.norm_type (int, float or str, optional) – Order p of the vector norm in the regularization term: any number
p >= 1,'inf'or'fro'(Euclidean). Default is2.solver (str or None, optional) – CVXPY solver name.
Nonefor automatic selection.include_slack (bool or None, optional) – Whether to add the slack variables ζ_i (the relaxation formulation).
Noneadds them only whenrho != 0.
- Returns:
x (numpy.ndarray) – Optimal decision variable vector.
zeta (numpy.ndarray) – Optimal slack variable values (one per scenario).
cost (float) – Optimal objective value.
N (int) – Number of scenarios used.
complexity (int) – Cardinality of the support list (violated plus retained active scenario constraints).
constraints (list) – Scenario constraint objects (one per scenario; hard constraints are kept separate).
degeneracy (bool) –
Trueif degeneracy was detected during support identification.
- Raises:
ValueError – If the solver does not reach an optimal or near-optimal status.
AssertionError – If Q or any \(F_j(\delta)\) matrix is not symmetric.