Solvers

All solvers follow the scenario approach pattern:

  1. Collect N random scenarios \(\delta_1, \ldots, \delta_N\)

  2. Formulate a convex program with soft scenario constraints \(A(\delta_i)x + b(\delta_i) \leq \zeta_i\)

  3. Solve with slack variables \(\zeta\) penalized by \(\rho\)

  4. Identify active (support) constraints to determine complexity k

  5. 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.0 the scenario constraints are hard. Default is 0.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 is 2.

  • solver (str or None, optional) – CVXPY solver name. None for automatic selection.

  • include_slack (bool or None, optional) – Whether to add the slack variables ζ_i (the relaxation formulation). None adds them only when rho != 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) – True if degeneracy was detected during support identification.

Raises:

ValueError – If deltas is 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.0 the scenario constraints are hard. Default is 0.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 is 2.

  • solver (str or None, optional) – CVXPY solver name. None for automatic selection.

  • include_slack (bool or None, optional) – Whether to add the slack variables ζ_i (the relaxation formulation). None adds them only when rho != 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) – True if 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 None if 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. None or 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.0 the scenario constraints are hard. Default is 0.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 is 2.

  • solver (str or None, optional) – CVXPY solver name. None for automatic selection.

  • include_slack (bool or None, optional) – Whether to add the slack variables ζ_i (the relaxation formulation). None adds them only when rho != 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) – True if 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.