pygradflow package
Subpackages
- pygradflow.step package
- Submodules
- pygradflow.step.asymmetric_step_solver module
- pygradflow.step.cond_estimate module
- pygradflow.step.extended_step_solver module
- pygradflow.step.linear_solver module
- pygradflow.step.scaled_step_solver module
- pygradflow.step.standard_step_solver module
- pygradflow.step.step_control module
- pygradflow.step.step_solver module
- pygradflow.step.symmetric_step_solver module
- Module contents
Submodules
pygradflow.active_set module
pygradflow.context module
pygradflow.controller module
- class pygradflow.controller.Controller(settings: ControllerSettings, ref: float)
Bases:
objectPI controller with given settings and reference value.
- __init__(settings: ControllerSettings, ref: float) None
- class pygradflow.controller.ControllerSettings(K_P: float = 0.0, K_I: float = 0.0, lamb_init: float = 0.0, lamb_red: float = 0.0)
Bases:
object
- class pygradflow.controller.LogController(settings: ControllerSettings, ref: float)
Bases:
objectPI controller working on log scale.
- __init__(settings: ControllerSettings, ref: float) None
pygradflow.deriv_check module
- exception pygradflow.deriv_check.DerivError(expected_value, actual_value, col_index, atol)
Bases:
ValueError
pygradflow.display module
pygradflow.eval module
- class pygradflow.eval.Component(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
Enum
- exception pygradflow.eval.EvalError(msg, x)
Bases:
ValueError- __init__(msg, x)
pygradflow.implicit_func module
- class pygradflow.implicit_func.ImplicitFunc(problem: Problem, iterate: Iterate, dt: float)
Bases:
StepFuncStandard residual function for implicit Euler steps with the value
\[\begin{split}F(x, y; \hat{x}, \hat{y}) = \begin{pmatrix} x - P_{C} (\hat{x} - \Delta t \nabla_{x} \mathcal{L}^{\rho}(x, y)) \\ y - (\hat{y} + \Delta t \nabla_{y} \mathcal{L}^{\rho}(x, y) \end{pmatrix}\end{split}\]The values \(\hat{x}\) and \(\hat{y}\) are obtained from the iteratre provided in the constructor
- class pygradflow.implicit_func.ScaledImplicitFunc(problem: Problem, iterate: Iterate, dt: float)
Bases:
StepFuncThe scaled residual function for implicit Euler steps is defined as the normal residual function given by
pygradflow.implicit_func.ImplicitFuncscaled by a factor of \(\lambda = 1 / \Delta t\).
- class pygradflow.implicit_func.StepFunc(problem: Problem, iterate: Iterate, dt: float)
Bases:
ABC- compute_active_set_box(x: ndarray, lb: ndarray, ub: ndarray)
Compute the active set at the given point with respect to the given bounds.
- Parameters:
x (np.ndarray) – A primal point in \(\mathbb{R}^{n}\)
lb (np.ndarray) – Bounds in \(\mathbb{R}^{n}\)
ub (np.ndarray) – Bounds in \(\mathbb{R}^{n}\)
- Returns:
A vector with boolean entries, where a value of True at index j indicates that \(x_j\) is outside the interval \([l_j, u_j]\) and should be clipped to it during the projection.
- Return type:
np.ndarray
pygradflow.iterate module
pygradflow.log module
pygradflow.newton module
- class pygradflow.newton.ActiveSetNewtonMethod(problem: Problem, orig_iterate: Iterate, dt: float, rho: float, step_solver: StepSolver, tau=None)
Bases:
NewtonMethodComputes step based on the matrix given in terms of the initial iterate with an active set based on the active set projection of the primal point of the current iterate. Requires a factorization at each step.
- class pygradflow.newton.FixedActiveSetNewtonMethod(problem, active_set, orig_iterate, dt, rho, tau=None)
Bases:
NewtonMethodComputes step based on the matrix given in terms of the current iterate. Requires evaluation of the derivative and a factorization at each step.
- __init__(problem, active_set, orig_iterate, dt, rho, tau=None)
- class pygradflow.newton.FullNewtonMethod(problem: Problem, orig_iterate: Iterate, dt: float, rho: float, step_solver: StepSolver, tau=None)
Bases:
NewtonMethodComputes step based on the matrix given in terms of the current iterate. Requires evaluation of the derivative and a factorization at each step.
- class pygradflow.newton.GlobalizedNewtonMethod(problem: Problem, orig_iterate: Iterate, dt: float, rho: float, step_solver: StepSolver, tau=None)
Bases:
NewtonMethodGlobalized Newton method with Armijo line search. Globalization is based on the underlying function of the step solver.
- class pygradflow.newton.NewtonMethod(problem: Problem, orig_iterate: Iterate, dt: float, rho: float, tau=None)
Bases:
ABC
- class pygradflow.newton.SimplifiedNewtonMethod(problem: Problem, orig_iterate: Iterate, dt: float, rho: float, step_solver: StepSolver, tau=None)
Bases:
NewtonMethodComputes step based on the matrix given in terms of the initial iterate. Only requires a back-solve for each step.
pygradflow.params module
- class pygradflow.params.ActiveSetType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
Enum
- class pygradflow.params.DerivCheck(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
FlagHow to check for derivatives
- CheckFirst = 1
Check first derivatives (objective gradient \(\nabla_{x} f(x)\) and \(J_c(x)\))
- CheckSecond = 2
Check Hessian of Lagrangian (\(\nabla_{xx} \mathcal{L}(x, y)\))
- NoCheck = 0
Disable checks
- class pygradflow.params.LinearSolverType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
EnumLinear solver to be used throughout the computations
- Cholesky = 4
Cholesky factorization using scikit-sparse
- GMRES = 3
Generalized minimal residual method (GMRES)
- LU = 1
LU decomposition
- MA57 = 5
HSL MA57 solver using pyomo
- MINRES = 2
Minimal residual method (MINRES), only works with symmetric step solver
pygradflow.params.StepSolverType.Symmetric
- MUMPS = 6
MUMPS solver
- SSIDS = 7
SPRAL / SSIDS solver
- class pygradflow.params.NewtonType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
EnumThe Newton method to be used to solve the semi-smooth systems. Different methods have trade-offs in terms of computational complexity and convergence speed
- ActiveSet = 3
Newton method with fixed derivative, but changing active sets. Requires refactorizations but no reevaluations of the derivatives
- Full = 2
Full Newton method, using a new derivative at each step, (requiring new derivative evaluations and factorizations)
- Globalized = 4
Globalizes the Newton method by using an Armijo line search
- Simplified = 1
Simplified Newton method, using the same derivative and active set throughout computations (cheapest)
- class pygradflow.params.Params(rho: float = 1e-08, theta_max: float = 0.9, theta_ref: float = 0.5, lamb_init: float = 1.0, lamb_min: float = 1e-12, lamb_max: float = 1000000000000.0, lamb_inc: float = 2.0, lamb_red: float = 0.5, K_P: float = 0.2, K_I: float = 0.005, opt_tol: float = 1e-06, lamb_term: float = 1e-08, active_tol: float = 1e-08, local_infeas_tol: float = 1e-08, active_set_type: ~pygradflow.params.ActiveSetType = ActiveSetType.Standard, active_set_method: ~typing.Callable[[...], float] | None = None, active_set_tau: float | None = None, newton_type: ~pygradflow.params.NewtonType = NewtonType.Simplified, newton_tol: float = 1e-08, step_control_type: ~pygradflow.params.StepControlType = StepControlType.DistanceRatio, step_solver: ~typing.Callable[[...], ~typing.Any] | None = None, step_solver_type: ~pygradflow.params.StepSolverType = StepSolverType.Symmetric, linear_solver_type: ~pygradflow.params.LinearSolverType = LinearSolverType.LU, penalty_update: ~pygradflow.params.PenaltyUpdate = PenaltyUpdate.DualNorm, deriv_check: ~pygradflow.params.DerivCheck = <DerivCheck.NoCheck: 0>, deriv_pert: float = 1e-08, deriv_tol: float = 0.0001, precision: ~pygradflow.params.Precision = Precision.Double, scaling_type: ~pygradflow.params.ScalingType = ScalingType.NoScaling, scaling_primal: ~numpy.ndarray | None = None, scaling_dual: ~numpy.ndarray | None = None, scaling: Scaling | None = None, validate_input: bool = True, iteration_limit: int | None = None, time_limit: float = inf, display_interval: float = 0.1, obj_lower_limit: float = -10000000000.0, report_rcond: bool = False, collect_path: bool = False, inertia_correction: bool = False)
Bases:
objectParameters used to solve a
pygradflow.problem.Problemusing apygradflow.solver.Solver- __init__(rho: float = 1e-08, theta_max: float = 0.9, theta_ref: float = 0.5, lamb_init: float = 1.0, lamb_min: float = 1e-12, lamb_max: float = 1000000000000.0, lamb_inc: float = 2.0, lamb_red: float = 0.5, K_P: float = 0.2, K_I: float = 0.005, opt_tol: float = 1e-06, lamb_term: float = 1e-08, active_tol: float = 1e-08, local_infeas_tol: float = 1e-08, active_set_type: ~pygradflow.params.ActiveSetType = ActiveSetType.Standard, active_set_method: ~typing.Callable[[...], float] | None = None, active_set_tau: float | None = None, newton_type: ~pygradflow.params.NewtonType = NewtonType.Simplified, newton_tol: float = 1e-08, step_control_type: ~pygradflow.params.StepControlType = StepControlType.DistanceRatio, step_solver: ~typing.Callable[[...], ~typing.Any] | None = None, step_solver_type: ~pygradflow.params.StepSolverType = StepSolverType.Symmetric, linear_solver_type: ~pygradflow.params.LinearSolverType = LinearSolverType.LU, penalty_update: ~pygradflow.params.PenaltyUpdate = PenaltyUpdate.DualNorm, deriv_check: ~pygradflow.params.DerivCheck = <DerivCheck.NoCheck: 0>, deriv_pert: float = 1e-08, deriv_tol: float = 0.0001, precision: ~pygradflow.params.Precision = Precision.Double, scaling_type: ~pygradflow.params.ScalingType = ScalingType.NoScaling, scaling_primal: ~numpy.ndarray | None = None, scaling_dual: ~numpy.ndarray | None = None, scaling: Scaling | None = None, validate_input: bool = True, iteration_limit: int | None = None, time_limit: float = inf, display_interval: float = 0.1, obj_lower_limit: float = -10000000000.0, report_rcond: bool = False, collect_path: bool = False, inertia_correction: bool = False) None
- class pygradflow.params.PenaltyUpdate(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
Enum
- class pygradflow.params.Precision(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
EnumPrecision to be used in all calculations
- Double = 2
Double precision (64 bit)
- Single = 1
Single precision (32 bit)
- class pygradflow.params.ScalingType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
EnumHow to scale the problem
- Custom = 5
User-provided custom scaling
- GradJac = 2
Scale based on gradient and equilibration of constraint Jacobian
- KKT = 3
Compute scales based on the equilibration of the KKT matrix
- NoScaling = 1
No scaling
- Nominal = 4
Scaled based on values of the variable and constraint values
- class pygradflow.params.StepControlType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
Enum
- class pygradflow.params.StepSolverType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)
Bases:
EnumStep solver type to be used throughout computations
- Asymmetric = 4
Scaled solver with asymmetric matrix
- Extended = 2
Scaled step solver with improved condition
- Standard = 1
Unscaled and unsymmetric
- Symmetric = 3
Scaled solver with symmetric matrix
pygradflow.penalty module
- class pygradflow.penalty.ConstantPenalty(problem: Problem, params: Params)
Bases:
PenaltyStrategy
- class pygradflow.penalty.DualEquilibration(problem: Problem, params: Params)
Bases:
PenaltyStrategyIncrease penalty such that the dual the violation is within a factor of the product of the dual variables and the constraint values
- class pygradflow.penalty.DualNormUpdate(problem: Problem, params: Params)
Bases:
PenaltyStrategyIncrease penalty such that it is within a factor of the inf-norm of the dual variables
- class pygradflow.penalty.LagrangianPenaltyFilter(problem: Problem, params: Params)
Bases:
PenaltyFilter
- class pygradflow.penalty.ObjectivePenaltyFilter(problem: Problem, params: Params)
Bases:
PenaltyFilter
- class pygradflow.penalty.ParetoDecrease(problem: Problem, params: Params)
Bases:
PenaltyStrategyIncrease penalty such that at least one of objective and constraint violation is (weakly) reduced in the direction of the curve
- class pygradflow.penalty.PenaltyFilter(problem: Problem, params: Params)
Bases:
PenaltyStrategyFilter maintaining a set of Pareto optimal points of objective and constraint violation. The penalty is increased at a point if it is dominated by any other point in the filter.
Note: The running time is linear in the size of the filter, this could be improved to be logarithmic
pygradflow.problem module
- class pygradflow.problem.Problem(var_lb: ndarray, var_ub: ndarray, **args)
Bases:
ABCBase class used to formulate the problem of minimizing a smooth objective \(f : \mathbb{R}^{n} \to \mathbb{R}\) over a set of smooth nonlinear constraints \(c : \mathbb{R}^{n} \to \mathbb{R}^{m}\) bounded by \(l, u \in \mathbb{R}^{m}\), and variable bounds \(x_l, x_u \in \mathbb{R}^{n}\), yielding the problem
\[\begin{split}\begin{align} \min_{x \in \mathbb{R}^{n}} \quad & f(x) \\ \text{s.t.} \quad & l \leq c(x) \leq u \\ & l^x \leq x \leq u^x \end{align}\end{split}\]- The Lagrangian of this problem is given by
- \[\mathcal{L}(x, y) = f(x) + y^{T} c(x),\]
where \(y \in \mathbb{R}^{m}\) is a vector of Lagrange multipliers
- __init__(var_lb: ndarray, var_ub: ndarray, **args) None
Creates the problem
- Parameters:
var_lb (np.ndarray) – The variable bounds \(l^x, u^x \in \mathbb{R}^{n}\) constraining the problem
var_ub (np.ndarray) – The variable bounds \(l^x, u^x \in \mathbb{R}^{n}\) constraining the problem
**args (dict, optional) –
Additional arguments to pass to the problem:
cons_lbnp.ndarrayThe lower bounds \(l \in \mathbb{R}^{m}\) on the constraints
cons_ubnp.ndarrayThe upper bounds \(u \in \mathbb{R}^{m}\) on the constraints
num_consintThe number of constraints (if not given by
cons_lborcons_ub), defaults to 0 (no constraints)
- cons(x: ndarray) ndarray
- Parameters:
x (np.ndarray) – The primal point \(x \in \mathbb{R}^{n}\) at which to evaluate the constraint function \(c\)
- Returns:
The constraint value \(c(x)\) at the given primal point \(x\)
- Return type:
np.ndarray
- cons_jac(x: ndarray) spmatrix
- Parameters:
x (np.ndarray) – The primal point \(x \in \mathbb{R}^{n}\) at which to evaluate the constraint Jacobian \(J_c\)
- Returns:
The constraint Jacobian \(J_c(x)\) at the given primal point \(x\)
- Return type:
sp.sparse.spmatrix
- abstract lag_hess(x: ndarray, y: ndarray) spmatrix
- Parameters:
x (np.ndarray) – The primal / dual points \(x \in \mathbb{R}^{n}\) and \(y \in \mathbb{R}^{m}\) at which to evaluate the Hessian \(\nabla_{xx} \mathcal{L}(x, y)\)
y (np.ndarray) – The primal / dual points \(x \in \mathbb{R}^{n}\) and \(y \in \mathbb{R}^{m}\) at which to evaluate the Hessian \(\nabla_{xx} \mathcal{L}(x, y)\)
- Returns:
The matrix \(\nabla_{xx} \mathcal{L}(x, y) \in \mathbb{R}^{n \times n}\) at the given primal / dual points \(x\) / \(y\)
- Return type:
sp.sparse.spmatrix
- abstract obj(x: ndarray) float
- Parameters:
x (np.ndarray) – The primal point \(x \in \mathbb{R}^{n}\) at which to evaluate the objective function
- Returns:
The objective function value \(f(x)\) at the given primal point \(x\)
- Return type:
- abstract obj_grad(x: ndarray) ndarray
- Parameters:
x (np.ndarray) – The primal point \(x \in \mathbb{R}^{n}\) at which to evaluate the objective function gradient
- Returns:
The objective function gradient \(\nabla f(x)\) at the given primal point \(x\)
- Return type:
np.ndarray
- property var_bounded
Whether of not the variable bounds are trivial (i.e., all infinte)
pygradflow.solver module
- class pygradflow.solver.Solver(problem: ~pygradflow.problem.Problem, params: ~pygradflow.params.Params = Params(rho=1e-08, theta_max=0.9, theta_ref=0.5, lamb_init=1.0, lamb_min=1e-12, lamb_max=1000000000000.0, lamb_inc=2.0, lamb_red=0.5, K_P=0.2, K_I=0.005, opt_tol=1e-06, lamb_term=1e-08, active_tol=1e-08, local_infeas_tol=1e-08, active_set_type=<ActiveSetType.Standard: 1>, active_set_method=None, active_set_tau=None, newton_type=<NewtonType.Simplified: 1>, newton_tol=1e-08, step_control_type=<StepControlType.DistanceRatio: 6>, step_solver=None, step_solver_type=<StepSolverType.Symmetric: 3>, linear_solver_type=<LinearSolverType.LU: 1>, penalty_update=<PenaltyUpdate.DualNorm: 2>, deriv_check=<DerivCheck.NoCheck: 0>, deriv_pert=1e-08, deriv_tol=0.0001, precision=<Precision.Double: 2>, scaling_type=<ScalingType.NoScaling: 1>, scaling_primal=None, scaling_dual=None, scaling=None, validate_input=True, iteration_limit=None, time_limit=inf, display_interval=0.1, obj_lower_limit=-10000000000.0, report_rcond=False, collect_path=False, inertia_correction=False))
Bases:
objectSolves a
pygradflow.problem.Probleminstance according to the givenpygradflow.params.Params. The solver attempts to find a solution given by vectors \(x \in \mathbb{R}^{n}\), \(y \in \mathbb{R}^{m}\), and \(d \in \mathbb{R}^{n}\), approximately satisfying the stationarity\[\begin{align} \nabla_x f(x) + y^{T} J_c(x) + d = 0, \end{align}\]feasibility
\[\begin{split}\begin{align} \quad & l \leq c(x) \leq u \\ \quad & l^x \leq x \leq u^x \\ \end{align}\end{split}\]and complementarity
\[\begin{split}\begin{align} y_i \begin{cases} \geq 0 & \text{ if } c(x)_i = u_i \\ \leq 0 & \text{ if } c(x)_i = l_i \\ = 0 & \text{ otherwise } \end{cases} \\ d_j \begin{cases} \geq 0 & \text{ if } x_j = u^x_j \\ \leq 0 & \text{ if } x_j = l^x_j \\ = 0 & \text{ otherwise } \end{cases} \end{align}\end{split}\]conditions.
- __init__(problem: ~pygradflow.problem.Problem, params: ~pygradflow.params.Params = Params(rho=1e-08, theta_max=0.9, theta_ref=0.5, lamb_init=1.0, lamb_min=1e-12, lamb_max=1000000000000.0, lamb_inc=2.0, lamb_red=0.5, K_P=0.2, K_I=0.005, opt_tol=1e-06, lamb_term=1e-08, active_tol=1e-08, local_infeas_tol=1e-08, active_set_type=<ActiveSetType.Standard: 1>, active_set_method=None, active_set_tau=None, newton_type=<NewtonType.Simplified: 1>, newton_tol=1e-08, step_control_type=<StepControlType.DistanceRatio: 6>, step_solver=None, step_solver_type=<StepSolverType.Symmetric: 3>, linear_solver_type=<LinearSolverType.LU: 1>, penalty_update=<PenaltyUpdate.DualNorm: 2>, deriv_check=<DerivCheck.NoCheck: 0>, deriv_pert=1e-08, deriv_tol=0.0001, precision=<Precision.Double: 2>, scaling_type=<ScalingType.NoScaling: 1>, scaling_primal=None, scaling_dual=None, scaling=None, validate_input=True, iteration_limit=None, time_limit=inf, display_interval=0.1, obj_lower_limit=-10000000000.0, report_rcond=False, collect_path=False, inertia_correction=False)) None
Creates a new solver
- Parameters:
problem (pygradflow.problem.Problem) – The problem to be solved
params (pygradflow.params.Params) – Parameters used by the solver