ppopt package
Subpackages
- ppopt.geometry package
- ppopt.mp_solvers package
- Submodules
- ppopt.mp_solvers.mpqp_ahmadi module
- ppopt.mp_solvers.mpqp_combinatorial module
- ppopt.mp_solvers.mpqp_geometric module
- ppopt.mp_solvers.mpqp_graph module
- ppopt.mp_solvers.mpqp_parallel_geometric module
- ppopt.mp_solvers.mpqp_parallel_geometric_exp module
- ppopt.mp_solvers.mpqp_parrallel_combinatorial module
- ppopt.mp_solvers.mpqp_parrallel_combinatorial_exp module
- ppopt.mp_solvers.mpqp_parrallel_graph module
- ppopt.mp_solvers.solve_mplp module
- ppopt.mp_solvers.solve_mpqp module
filter_solution()
mpqp_algorithm
mpqp_algorithm.combinatorial
mpqp_algorithm.combinatorial_parallel
mpqp_algorithm.combinatorial_parallel_exp
mpqp_algorithm.geometric
mpqp_algorithm.geometric_parallel
mpqp_algorithm.geometric_parallel_exp
mpqp_algorithm.graph
mpqp_algorithm.graph_exp
mpqp_algorithm.graph_parallel
mpqp_algorithm.graph_parallel_exp
solve_mpqp()
- ppopt.mp_solvers.solver_utils module
- Module contents
- ppopt.solver_interface package
- ppopt.upop package
- ppopt.utils package
- Submodules
- ppopt.utils.chebyshev_ball module
- ppopt.utils.constraint_utilities module
calculate_redundant_constraints()
cheap_remove_redundant_constraints()
constraint_norm()
detect_implicit_equalities()
facet_ball_elimination()
find_implicit_equalities()
find_redundant_constraints()
get_indices_of_zero_rows()
is_full_rank()
process_program_constraints()
process_region_constraints()
remove_duplicate_rows()
remove_strongly_redundant_constraints()
remove_zero_rows()
row_equality()
scale_constraint()
shuffle_processed_constraints()
- ppopt.utils.general_utils module
- ppopt.utils.geometric module
- ppopt.utils.mpqp_utils module
- Module contents
Submodules
ppopt.critical_region module
- class ppopt.critical_region.CriticalRegion(A: ~numpy.ndarray, b: ~numpy.ndarray, C: ~numpy.ndarray, d: ~numpy.ndarray, E: ~numpy.ndarray, f: ~numpy.ndarray, active_set: ~typing.List[int] | ~numpy.ndarray, omega_set: ~typing.List[int] | ~numpy.ndarray = <factory>, lambda_set: ~typing.List[int] | ~numpy.ndarray = <factory>, regular_set: ~typing.List[int] | ~numpy.ndarray = <factory>, y_fixation: ~numpy.ndarray | None = None, y_indices: ~numpy.ndarray | None = None, x_indices: ~numpy.ndarray | None = None)
Bases:
object
Critical region is a polytope that defines a region in the uncertainty space with an associated optimal value, active set, lagrange multipliers and constraints
\[\begin{split}\begin{align} x(\theta) &= A\theta + b\\ \lambda(\theta) &= C\theta + d\\ \Theta &:= \{\forall \theta \in \mathbf{R}^m: E\theta \leq f\} \end{align}\end{split}\]equality_indices: numpy array of indices
constraint_set: if this is an A@x = b + F@theta boundary
lambda_set: if this is a λ = 0 boundary
boundary_set: if this is an Eθ <= f boundary
- A: ndarray
- C: ndarray
- E: ndarray
- active_set: List[int] | ndarray
- b: ndarray
- d: ndarray
- evaluate(theta: ndarray) ndarray
Evaluates x(θ) = Aθ + b.
- f: ndarray
- get_constraints()
An assessor function to quickly access the fields of the extends of the critical region
- Returns:
a list with E, and f as elements
- is_full_dimension() bool
Tests dimensionality of critical region. This is done by checking the radius of the chebyshev ball inside the region
- Returns:
a boolean value, of whether the critical region is full dimensional
- is_inside(theta: ndarray) ndarray
Tests if point θ is inside the critical region.
- lagrange_multipliers(theta: ndarray) ndarray
Evaluates λ(θ) = Cθ + d.
- lambda_set: List[int] | ndarray
- omega_set: List[int] | ndarray
- regular_set: List[int] | ndarray
- x_indices: ndarray = None
- y_fixation: ndarray = None
- y_indices: ndarray = None
ppopt.mplp_program module
- class ppopt.mplp_program.MPLP_Program(A, b, c, H, A_t, b_t, F, c_c=None, c_t=None, Q_t=None, equality_indices=None, solver=None)
Bases:
object
The standard class for multiparametric linear programming
\[\begin{split}\begin{align} \min_x \quad \theta^TH^Tx& + c^Tx\\ \text{s.t.} \quad Ax &\leq b + F\theta\\ A_{eq}x &= b_{eq}\\ A_\theta \theta &\leq b_\theta\\ x &\in R^n\\ \end{align}\end{split}\]- A: ndarray
- A_t: ndarray
- F: ndarray
- H: ndarray
- Q_t: ndarray
- b: ndarray
- b_t: ndarray
- c: ndarray
- c_c: ndarray
- c_t: ndarray
- check_active_set_rank(active_set)
Checks the rank of the matrix is equal to the cardinality of the active set
\[\textrm{Rank}(A_{\mathcal{A}}) = |\mathcal{A}|\]- Parameters:
active_set – an active set combination
- Returns:
True if full rank otherwise false
- check_feasibility(active_set, check_rank=True) bool
Checks the feasibility of an active set combination w.r.t. a multiparametric program.
\[\begin{split}\begin{align} \min_{x,\theta} \quad \quad &0\\ \text{s.t.}\quad Ax &\leq b + F\theta\\ A_{i}x &= b_{i} + F_{i}\theta, \quad \forall i \in \mathcal{A}\\ A_\theta \theta &\leq b_\theta\\ x &\in R^n\\ \theta &\in R^m \end{align}\end{split}\]- Parameters:
active_set – an active set combination
check_rank – Checks the rank of the LHS matrix for a violation of LINQ if True (default)
- Returns:
True if active set is feasible else False
- check_optimality(active_set)
Tests if the active set is optimal for the provided mpLP program
\[\max_{x, \theta, \lambda, s, t} \quad t\]\[\begin{split}\begin{align*} H \theta + (A_{A_i})^T \lambda_{A_i} + c &= 0\\ A_{A_i}x - b_ai-F_{a_i}\theta &= 0\\ A_{A_j}x - b_{A_j}-F_{A_j}\theta + s{j_k} &= 0\\ t*e_1 &\leq \lambda_{A_i}\\ t*e_2 &\leq s_{J_i}\\ t &\geq 0\\ \lambda_{A_i} &\geq 0\\ s_{J_i} &\geq 0\\ A_t\theta &\leq b_t \end{align*}\end{split}\]- Parameters:
active_set – active set being considered in the optimality test
- Returns:
dictionary of parameters, or None if active set is not optimal
- constraint_datatype_conversion() None
Makes sure that all the data types of the problem are in fp64, this is important as some solvers do not accept integral data types.
- display_latex() None
Displaces Latex text of the multiparametric problem.
- display_warnings() None
Displaces warnings.
- equality_indices: List[int] | ndarray
- evaluate_objective(x: ndarray, theta_point: ndarray)
- feasible_space_chebychev_ball()
Formulates and solves the (x, Θ) chebychev ball of the multiparametric program.
- Returns:
the lp solution object of the chebychev ball
- feasible_theta_point() ndarray | None
This generates a feasible theta point for the multiparametric problem
- Returns:
- gen_optimal_active_set() List[int] | None
Self contained method to geometrically sample the theta feasible space to generate an optimal active set.
- Returns:
an optimal active set
- latex() List[str]
Generates latex of the multiparametric problem
- Returns:
returns latex of the
- num_constraints() int
Returns number of constraints.
- num_equality_constraints() int
- num_inequality_constraints() int
- num_t() int
Returns number of uncertain variables.
- num_x() int
Returns number of parameters.
- optimal_control_law(active_set: List[int]) Tuple
This function calculates the optimal control law corresponding to an active set combination
- Parameters:
active_set – an active set combination
- Returns:
a tuple of the optimal x* and λ* functions in the following form(A_x, b_x, A_l, b_l)
\[\begin{split}\begin{align*} x^*(\theta) &= A_x\theta + b_x\\ \lambda^*(\theta) &= A_l\theta + b_l\\ \end{align*}\end{split}\]
- process_constraints() None
Removes redundant constraints from the multiparametric programming problem.
- sample_theta_space(num_samples: int = 100) list | None
Samples the theta feasible space with a Diken walk algorithm. This is typically used to initiate the graph and geometric algorithm.
- Returns:
list of found optimal active sets
- scale_constraints() None
Rescales the constraints of the multiparametric problem to ||[A|-F]||_i = 1, in the L2 sense.
- solve_theta(theta_point: ndarray) SolverOutput | None
Substitutes theta into the multiparametric problem and solves the following optimization problem
\[\min_{x} \tilde{c}^Tx\]\[\begin{split}\begin{align} Ax &\leq \tilde{b}\\ A_{eq}x &= \tilde{b}_{eq}\\ x &\in R^n\\ \end{align}\end{split}\]- Parameters:
theta_point – An uncertainty realization
- Returns:
The Solver output of the substituted problem, returns None if not solvable
- solve_theta_variable() SolverOutput | None
Leaves Theta as an optimization variable, solves the following problem
define y’ = [x^T theta^T]^T
min [c^T 0]^Ty’ s.t. [A -F]y’ <= b
- Returns:
the Solver output of the substituted problem, returns None if not solvable
- warnings() List[str]
Checks the dimensions of the matrices to ensure consistency.
- ppopt.mplp_program.calc_weakly_redundant(A, b, equality_set: List[int] | None = None, deterministic_solver='gurobi')
ppopt.mpqp_program module
- class ppopt.mpqp_program.MPQP_Program(A: ndarray, b: ndarray, c: ndarray, H: ndarray, Q: ndarray, A_t: ndarray, b_t: ndarray, F: ndarray, c_c: ndarray | None = None, c_t: ndarray | None = None, Q_t: ndarray | None = None, equality_indices=None, solver=None)
Bases:
MPLP_Program
The standard class for quadratic multiparametric programming.
\[\begin{split}\begin{align} \min_x\quad \frac{1}{2}x^TQx& + \theta^TH^Tx + c^Tx\\ \text{s.t.}\quad Ax &\leq b + F\theta\\ A_{eq}x &= b_{eq}\\ A_\theta \theta &\leq b_\theta\\ x &\in R^n\\ \end{align}\end{split}\]- A: ndarray
- A_t: ndarray
- F: ndarray
- H: ndarray
- Q_t: ndarray
- b: ndarray
- b_t: ndarray
- c: ndarray
- c_c: ndarray
- c_t: ndarray
- check_optimality(active_set: list)
Tests if the active set is optimal for the provided mpqp program
\[\max_{x, \theta, \lambda, s, t} \quad t\]\[\begin{split}\begin{align*} Qx + H \theta + (A_{A_i})^T \lambda_{A_i} + c &= 0\\ A_{A_i}x - b_ai-F_{a_i}\theta &= 0\\ A_{A_j}x - b_{A_j}-F_{A_j}\theta + s{j_k} &= 0\\ t*e_1 &\leq \lambda_{A_i}\\ t*e_2 &\leq s_{J_i}\\ t &\geq 0\\ \lambda_{A_i} &\geq 0\\ s_{J_i} &\geq 0\\ A_t\theta &\leq b_t \end{align*}\end{split}\]- Parameters:
active_set – active set being considered in the optimality test
- Returns:
dictionary of parameters, or None if active set is not optimal
- equality_indices: List[int] | ndarray
- evaluate_objective(x, theta_point)
Evaluates the objective of the multiparametric program. for a given x and θ.
\[\frac{1}{2}x^TQx + \theta^TH^Tx+c^Tx\]- Parameters:
x – x input
theta_point – θ input
- Returns:
Objective function evaluated at x, θ
- latex() List[str]
Creates a latex output for the multiparametric problem.
- optimal_control_law(active_set: List[int]) Tuple
This function calculates the optimal control law corresponding to an active set combination. This is effectivley just manipulating the stationarity conditions and active constraints for x, and λ
\[ \begin{align}\begin{aligned}Qx + c + H\theta + \hat{A}^T\hat{\lambda} = 0\\\hat{A}x = \hat{b} + \hat{F}\theta\end{aligned}\end{align} \]\[\begin{split}\begin{align*} x^*(\theta) &= A_x\theta + b_x\\ \lambda^*(\theta) &= A_l\theta + b_l\\ \end{align*}\end{split}\]- Parameters:
active_set – an active set combination
- Returns:
a tuple of the optimal x* and λ* functions in the following form(A_x, b_x, A_l, b_l)
- solve_theta(theta_point: ndarray) SolverOutput | None
Substitutes a particular realization of θ into the multiparametric problem and solves the resulting optimization problem.
\[\begin{split}\begin{align} \tilde{b} &= b + F\theta\\ \tilde{b}_eq &= b_{eq} + F_{eq}\theta\\ \tilde{c}^T &= c^T + \theta^T H^T \end{align}\end{split}\]\[\begin{split}\begin{align} \min_{x}\quad &\frac{1}{2}x^TQx + \tilde{c}^Tx\\ \text{s.t.} \quad Ax &\leq \tilde{b}\\ A_{eq}x &= \tilde{b}_{eq}\\ x &\in \mathbb{R}^n \end{align}\end{split}\]- Parameters:
theta_point – An uncertainty realization
- Returns:
The Solver output of the substituted problem, returns None if not solvable
- warnings() List[str]
Checks the dimensions of the matrices to ensure consistency.
ppopt.plot module
- ppopt.plot.gen_vertices(solution: Solution)
Generates the vertices associated with the critical regions in the solution.
- Parameters:
solution – a multiparametric region
- Returns:
a list of a collection of vertices sorted counterclockwise that correspond to the specific region
- ppopt.plot.parametric_plot(solution: Solution, save_path: str | None = None, show=True, save_format: str = 'png', seed: int | None = None) None
Makes a simple plot from a solution. This uses matplotlib to generate a plot, it is the general plotting backend.
- Parameters:
solution – a multiparametric solution
save_path – if specified saves the plot in the directory
save_format – changes the saved image format to the specified
show – Keyword argument, if True displays the plot otherwise does not display
seed – If not set, will default to time in nanoseconds since the epoc
- Returns:
no return, creates graph of solution
- ppopt.plot.parametric_plot_1D(solution: Solution, save_path: str | None = None, show=True, save_format: str = 'png') None
Makes a simple plot from a 1D parametric solution. This uses matplotlib to generate a plot, it is the general plotting backend.
- Parameters:
solution – a multiparametric solution
save_path – if specified saves the plot in the directory
save_format – changes the saved image format to the specified
show – Keyword argument, if True displays the plot otherwise does not display
- Returns:
no return, creates graph of solution
- ppopt.plot.plotly_plot(solution: Solution, save_path: str | None = None, show=True, save_format: str = 'png') None
Makes a plot via the plotly library, this is good for interactive figures that you can embed into webpages and handle interactively.
- Parameters:
solution – a 2D parametric solution
save_path – Keyword argument, if a directory path is specified it will save a html copy and a png to that directory
save_format – changes the saved image format to the specified
show – Keyword argument, if True displays the plot otherwise does not display
- Returns:
no return, creates a graph of the solution
- ppopt.plot.sort_clockwise(vertices: List[ndarray]) List[ndarray]
Sorts the vertices in clockwise order. This is important for rendering as if they were not sorted then you would see nonsense.
- Parameters:
vertices – a list of 2D vertices
- Returns:
List of vertices that have been sorted in a clockwise direction
- ppopt.plot.vertex_enumeration_2d(A: ndarray, b: ndarray, solver: Solver) List[ndarray]
Computes the vertices of a 2D polytope from the half space representation, uses a naive O(n^2) algorithm but is sufficient for plotting purposes.
Generates vertices for the 2D polytope of the following structure Ax <= b
- Parameters:
solver – A solver object to solve the LPs
A – The left-hand side constraint matrix
b – The right-hand side constraint matrix
- Returns:
List of vertices
ppopt.problem_generator module
- ppopt.problem_generator.generate_mplp(x: int = 2, t: int = 2, m: int = 10) MPLP_Program
Generates a random mpLP problem with of the following characteristics
- Parameters:
x – number of parameters
t – number of uncertain variables
m – number of constraints
- Returns:
A random mpLP of the specified type
- ppopt.problem_generator.generate_mpqp(x: int = 2, t: int = 2, m: int = 10) MPQP_Program
Generates a random mpQP problem with of the following characteristics
- Parameters:
x – number of x dimensions
t – number of theta dimensions
m – number of constraints
- Returns:
A random mpQP problem of the specified type
ppopt.solution module
- class ppopt.solution.Solution(program: MPLP_Program | MPQP_Program, critical_regions: List[CriticalRegion], is_overlapping=False)
Bases:
object
The Solution object is the output of multiparametric solvers, it contains all the critical regions as well as holds a copy of the original problem that was solved.
- add_region(region: CriticalRegion) None
Adds a region to the solution
- Parameters:
region – region to add to the solution
- critical_regions: List[CriticalRegion]
- evaluate(theta_point: ndarray) ndarray | None
returns the optimal x* from the solution, if it exists
- Parameters:
theta_point – an uncertainty realization
- Returns:
the calculated x* from theta
- evaluate_objective(theta_point) ndarray | None
Given a realization of an uncertainty parameter, calculate the objective value
- Parameters:
theta_point – a theta realization
- Returns:
the value of the objective or None (if theta_point is not inside any critical region)
- get_region(theta_point: ndarray) CriticalRegion | None
Find the critical region in the solution that corresponds to the theta provided
The method finds all critical regions that the solution is inside and returns the solutions, x*, with the lowest objective function of all of these regions.
In the case of no overlap we can make a shortcut
- Parameters:
theta_point – an uncertainty realization
- Returns:
the region that contains theta
- get_region_no_overlap(theta_point: ndarray) CriticalRegion | None
Find the critical region in the solution that corresponds to the provided theta, assumes that no critical regions overlap
- Parameters:
theta_point – a theta realization
- Returns:
the critical region that contains theta_point or None
- get_region_overlap(theta_point: ndarray) CriticalRegion | None
Find the critical region in the solution that corresponds to the provided theta
- Parameters:
theta_point – realization of uncertainty
- Returns:
the critical region that that theta is in with the lowest objective value or none
- is_mixed_integer_sol()
- program: MPLP_Program | MPQP_Program | MPMIQP_Program | MPMILP_Program
- theta_dim() int
Returns the number of theta/ parameter dimensions
- verify_solution() bool
This can be called to verify that all the critical regions agree with the optimization problem. With problems with numerically small critical regions the deterministic optimizer value could fail. This does NOT necessarily mean that the critical region is at fault but that perhaps more analysis should be done. This is especially apparent with critical regions with chebychev radii on the order of sqrt(machine epsilon).
In the case of overlapping critical regions this is not the proper analysis and a different method should be used.
- Returns:
True if all is verified, else False
- verify_theta(theta_point: ndarray) bool
Checks that the result of the solution is consistent with theta substituted multiparametric problem
- Parameters:
theta_point – an uncertainty realization
- Returns:
True if they are the same, False if they are different
ppopt.solver module
- class ppopt.solver.Solver(solvers: ~typing.Dict[str, str] = <factory>)
Bases:
object
This is the primary user interface for deterministic solvers
The solvers can be changed by directly editing the solver dict to different solver names
- check_supported_problem(problem_name: str) None
- static problem_not_supported(problem_name: str) None
This is an internal method that throws an error and prompts the user when they use an unsupported Solver
- solve_lp(c: ndarray | None, A: ndarray | None, b: ndarray | None, equality_constraints=None, verbose=False, get_duals=True) SolverOutput | None
This is the breakout for solving linear programs
The Linear programming problem
\[\min_{xy} c^Tx\]\[\begin{split}\begin{align} Ax &\leq b\\ A_{eq}x &= beq\\ x &\in R^n\\ \end{align}\end{split}\]- Parameters:
c – Column Vector, can be None
A – Constraint LHS matrix, can be None
b – Constraint RHS matrix, can be None
equality_constraints – List of Equality constraints
verbose – Flag for output of underlying Solver, default False
get_duals – Flag for returning dual variable of problem, default True (false for all mixed integer models)
- Returns:
A SolverOutput object if optima found, otherwise None.
- solve_milp(c: ndarray | None, A: ndarray | None, b: ndarray | None, equality_constraints: Iterable[int] | None = None, bin_vars: Iterable[int] | None = None, verbose=False, get_duals=True) SolverOutput | None
This is the breakout for solving mixed integer linear programs
The Mixed Integer Linear programming problem
\[\min_{x,y} c^T[x,y]\]\[\begin{split}\begin{align} A[x,y] &\leq b\\ A_{eq}[x,y] &= beq\\ x &\in R^n\\ y &\in \{0, 1\}^m \end{align}\end{split}\]- Parameters:
c – Column Vector, can be None
A – Constraint LHS matrix, can be None
b – Constraint RHS matrix, can be None
equality_constraints – List of Equality constraints
bin_vars – List of binary variable indices
verbose – Flag for output of underlying Solver, default False
get_duals – Flag for returning dual variable of problem, default True (false for all mixed integer models)
- Returns:
A dictionary of the Solver outputs, or none if infeasible or unbounded. output[‘sol’] = primal variables, output[‘dual’] = dual variables, output[‘obj’] = objective value, output[‘const’] = slacks, output[‘active’] = active constraints.
- solve_miqp(Q: ndarray | None, c: ndarray | None, A: ndarray | None, b: ndarray | None, equality_constraints: Iterable[int] | None = None, bin_vars: Iterable[int] | None = None, verbose: bool = False, get_duals: bool = True) SolverOutput | None
This is the breakout for solving mixed integer quadratic programs
The Mixed Integer Quadratic program programming problem
\[\min_{xy} \frac{1}{2} [xy]^TQ[xy] + c^T[xy]\]\[\begin{split}\begin{align} A[xy] &\leq b\\ A_{eq}[xy] &= beq\\ x &\in R^n\\ y &\in \{0, 1\}^m \end{align}\end{split}\]- Parameters:
Q – Square matrix, can be None
c – Column Vector, can be None
A – Constraint LHS matrix, can be None
b – Constraint RHS matrix, can be None
equality_constraints – List of Equality constraints
bin_vars – List of binary variable indices
verbose – Flag for output of underlying Solver, default False
get_duals – Flag for returning dual variable of problem, default True (false for all mixed integer models)
- Returns:
A SolverOutput object if optima found, otherwise None.
- solve_qp(Q: ndarray | None, c: ndarray | None, A: ndarray | None, b: ndarray | None, equality_constraints: Iterable[int] | None = None, verbose=False, get_duals=True) SolverOutput | None
This is the breakout for solving quadratic programs
The Quadratic programming problem
\[\min_{x} \frac{1}{2}x^TQx + c^Tx\]\[\begin{split}\begin{align} Ax &\leq b\\ A_{eq}x &= beq\\ x &\in R^n\\ \end{align}\end{split}\]- Parameters:
Q – Square matrix, can be None
c – Column Vector, can be None
A – Constraint LHS matrix, can be None
b – Constraint RHS matrix, can be None
equality_constraints – List of Equality constraints
verbose – Flag for output of underlying Solver, default False
get_duals – Flag for returning dual variable of problem, default True (false for all mixed integer models)
- Returns:
A SolverOutput object if optima found, otherwise None.
- static solver_not_supported(solver_name: str) None
This is an internal method that throws an error and prompts the user when they use an unsupported Solver
- solvers: Dict[str, str]
- supported_problems = ['lp', 'qp', 'milp', 'miqp']
- supported_solvers = ['gurobi', 'glpk', 'quadprog']
- ppopt.solver.available_LP_solvers() Iterable
Checks what LP solvers are available to use
- Returns:
Installed and supported solvers for linear programs
- ppopt.solver.available_QP_solvers()
Checks what QP solvers are avalable to use
- Returns:
Installed and supported solvers for quadratic programs
- ppopt.solver.check_modules(modules: Iterable) Iterable
Given an iterable of module names, returns modules that are installed
- ppopt.solver.check_solver_modules(module_map, packages) Iterable
Maps optimization python package names to internal names and returns an iterable
- ppopt.solver.default_solver_options()
Generates the default system solvers to use for optimization sub problems
- Returns:
A dictionary of determanistic solvers to use
Module contents
PPOPT INIT FILE