pockit.base.systembase

class SystemBase(abc.ABC):

A system is the higher level objective of a multiple-phase optimal control problem.

SystemBase( static_parameter: int | list[str], simplify: bool = False, parallel: bool = False, fastmath: bool = False)

Initialize a system with given static parameters.

If static_parameter is an integer, the names are generated automatically as \( s_0, s_1, \dots, s_{n-1} \).

If simplify is True, every symbolic expression will be simplified (by sympy.simplify()) before being compiled. This will slow down the speed of compilation.

If parallel is True, the parallel flag will be passed to the Numba JIT compiler, which will generate parallel code for multicore CPUs. This will slow down the speed of compilation and sometimes the speed of execution.

If fastmath is True, the fastmath flag will be passed to the Numba JIT compiler, see Numba and LLVM documentations for details.

Arguments:
  • static_parameter: Number of static parameters or list of static parameter names.
  • simplify: Whether to use Sympy to simplify sympy.Expr before compilation.
  • parallel: Whether to use Numba parallel mode.
  • fastmath: Whether to use Numba fastmath mode.
def new_phase( self, state: int | list[str], control: int | list[str]) -> pockit.base.phasebase.PhaseBase:

Create a new phase for the given system.

This method is recommended to create a phase rather than using Phase's constructor directly, because it automatically set the symbol_static_parameter, identifier and flags of the phase.

Arguments:
  • state: Number of state variables or list of state variable names.
  • control: Number of control variables or list of control variable names.
Returns:

A new phase, with symbol_static_parameter, identifier and flags automatically set.

def set_phase(self, phase: list[pockit.base.phasebase.PhaseBase]) -> Self:

Set the phases of the system.

Arguments:
  • phase: List of Phase s of the system.
def set_objective( self, objective: float | sympy.core.expr.Expr, *, cache: Optional[str] = None) -> Self:

Set the objective of the system.

Arguments:
  • objective: Objective of the system composed with I and s.
  • cache: Path to the directory to store the compiled functions.
def set_system_constraint( self, system_constraint: list[sympy.core.expr.Expr], lower_bound: Iterable[float], upper_bound: Iterable[float], *, cache: Optional[str] = None) -> Self:

Set the system constraints of the system.

For equality constraints, set the corresponding entry of lower_bounds and upper_bounds to the same value. For one-sided inequality constraints, set the corresponding entry of lower_bounds or upper_bounds to -inf or inf.

Arguments:
  • system_constraint: List of system constraints composed with I and s.
  • lower_bound: Iterable of lower bounds of system constraints.
  • upper_bound: Iterable of upper bounds of system constraints.
  • cache: Path to the directory to store the compiled functions.
def update(self) -> None:

Update the system after changing any phase of the system.

def objective( self, x: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]) -> numpy.float64:

The objective function of the discretized optimization problem.

def constraints( self, x: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]:

Constraint functions of the discretized optimization problem.

def gradient( self, x: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]:

Gradient of the objective function of the discretized optimization problem.

def jacobianstructure( self) -> tuple[numpy.ndarray[typing.Any, numpy.dtype[numpy.int32]], numpy.ndarray[typing.Any, numpy.dtype[numpy.int32]]]:

Coordinates of the Jacobian of the constraint functions of the discretized optimization problem.

def jacobian( self, x: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]:

Jacobian of the constraint functions of the discretized optimization problem.

Arguments:
  • x: Vector of optimization variables.
Returns:

A plain 1D array, with coordinates given by jacobianstructure().

def hessianstructure_o( self) -> tuple[numpy.ndarray[typing.Any, numpy.dtype[numpy.int32]], numpy.ndarray[typing.Any, numpy.dtype[numpy.int32]]]:

Coordinates of the Hessian of the objective function of the discretized optimization problem.

Only includes entries in the lower triangle of the Hessian matrix.

def hessian_o( self, x: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]:

Hessian of the objective function of the discretized optimization problem.

Arguments:
  • x: Vector of optimization variables.
Returns:

A plain 1D array, with coordinates given by hessianstructure_o(). Only includes entries in the lower triangle of the Hessian matrix.

def hessianstructure_c( self) -> tuple[numpy.ndarray[typing.Any, numpy.dtype[numpy.int32]], numpy.ndarray[typing.Any, numpy.dtype[numpy.int32]]]:

Coordinates of the Hessian of the constraint functions of the discretized optimization problem.

Only includes entries in the lower triangle of the Hessian matrix.

def hessian_c( self, x: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], fct_c: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]:

Sum of Hessian of the constraint functions of the discretized optimization problem with factor fct_c.

Arguments:
  • x: Vector of optimization variables.
  • fct_c: Factors (Lagrange multipliers) for the constraints.
Returns:

A plain 1D array, with coordinates given by hessianstructure_c(). Only includes entries in the lower triangle of the Hessian matrix.

def hessianstructure( self) -> tuple[numpy.ndarray[typing.Any, numpy.dtype[numpy.int32]], numpy.ndarray[typing.Any, numpy.dtype[numpy.int32]]]:

Coordinates of the Hessian of the Lagrangian of the discretized optimization problem.

Only includes entries in the lower triangle of the Hessian matrix.

def hessian( self, x: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], fct_c: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]], fct_o: float) -> numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]:

Hessian of the Lagrangian of the discretized optimization problem with factors fct_c for constraints and fct_o for the objective.

Arguments:
  • x: Vector of optimization variables.
  • fct_c: Factors (Lagrange multipliers) for the constraints.
  • fct_o: Factor (Lagrange multiplier) for the objective.
Returns:

A plain 1D array, with coordinates given by hessianstructure(). Only includes entries in the lower triangle of the Hessian matrix.

def check_continuous( self, value: pockit.base.variablebase.VariableBase | list[typing.Union[pockit.base.variablebase.VariableBase, typing.Iterable[float]]], absolute_tolerance_continuous: float = 1e-08, relative_tolerance_continuous: float = 1e-08, tolerance_mesh: float = 0.0001) -> bool:

Check the continuous error.

Arguments:
  • value: The variable to be checked. If the system has only one phase and no static variables, value can be a single Variable object. Otherwise, value should be a list of Variable objects, one for each Phase, followed by an array as values of static variables.
  • absolute_tolerance_continuous: Absolute tolerance for continuous error.
  • relative_tolerance_continuous: Relative tolerance for continuous error.
  • tolerance_mesh: Skip the check if the mesh width is smaller than this value.
Returns:

True if the error is within the tolerance, False otherwise.

def check_discontinuous( self, value: pockit.base.variablebase.VariableBase | list[typing.Union[pockit.base.variablebase.VariableBase, typing.Iterable[float]]], tolerance_discontinuous: float = 0.001, tolerance_mesh: float = 0.0001) -> bool:

Check the discontinuous error.

Arguments:
  • value: The variable to be checked. If the system has only one phase and no static variables, value can be a single Variable object. Otherwise, value should be a list of Variable objects, one for each Phase, followed by an array as values of static variables.
  • tolerance_discontinuous: In each subinterval, after scaling to [0, 1], the bang-bang control functions should either be less than tolerance_discontinuous or greater than 1 - tolerance_discontinuous simultaneously.
  • tolerance_mesh: Skip the check if the mesh width is smaller than this value.
Returns:

True if the error is within the tolerance, False otherwise.

def check( self, value: pockit.base.variablebase.VariableBase | list[typing.Union[pockit.base.variablebase.VariableBase, typing.Iterable[float]]], absolute_tolerance_continuous: float = 1e-08, relative_tolerance_continuous: float = 1e-08, tolerance_discontinuous: float = 0.001, tolerance_mesh: float = 0.0001) -> bool:

Check the continuous and discontinuous error.

Arguments:
  • value: The variable to be checked. If the system has only one phase and no static variables, value can be a single Variable object. Otherwise, value should be a list of Variable objects, one for each Phase, followed by an array as values of static variables.
  • absolute_tolerance_continuous: Absolute tolerance for continuous error.
  • relative_tolerance_continuous: Relative tolerance for continuous error.
  • tolerance_discontinuous: In each subinterval, after scaling to [0, 1], the bang-bang control functions should either be less than tolerance_discontinuous or greater than 1 - tolerance_discontinuous simultaneously.
  • tolerance_mesh: Skip the check if the mesh width is smaller than this value.
Returns:

True if the error is within the tolerance, False otherwise.

def refine_continuous( self, value: pockit.base.variablebase.VariableBase | list[typing.Union[pockit.base.variablebase.VariableBase, typing.Iterable[float]]], absolute_tolerance_continuous: float = 1e-08, relative_tolerance_continuous: float = 1e-08, num_point_min: int = 6, num_point_max: int = 12, mesh_length_min: float = 0.001, mesh_length_max: float = 1) -> pockit.base.variablebase.VariableBase | list[typing.Union[pockit.base.variablebase.VariableBase, typing.Iterable[float]]]:

Adjust the mesh and the number of interpolation points to match the continuous error tolerance.

Arguments:
  • value: The variable to be checked. If the system has only one phase and no static variables, value can be a single Variable object. Otherwise, value should be a list of Variable objects, one for each Phase, followed by an array as values of static variables.
  • absolute_tolerance_continuous: Absolute tolerance for continuous error.
  • relative_tolerance_continuous: Relative tolerance for continuous error.
  • num_point_min: Minimum number of interpolation points.
  • num_point_max: Maximum number of interpolation points.
  • mesh_length_min: Minimum mesh length.
  • mesh_length_max: Maximum mesh length.
Returns:

The Variable s interpolated to the new discretization scheme.

def refine_discontinuous( self, value: pockit.base.variablebase.VariableBase | list[typing.Union[pockit.base.variablebase.VariableBase, typing.Iterable[float]]], tolerance_discontinuous: float = 0.001, num_point_min: int = 6, num_point_max: int = 12, mesh_length_min: float = 0.001, mesh_length_max: float = 1) -> pockit.base.variablebase.VariableBase | list[typing.Union[pockit.base.variablebase.VariableBase, typing.Iterable[float]]]:

Adjust the mesh and the number of interpolation points to match the discontinuous error tolerance.

Arguments:
  • value: The variable to be checked. If the system has only one phase and no static variables, value can be a single Variable object. Otherwise, value should be a list of Variable objects, one for each Phase, followed by an array as values of static variables.
  • tolerance_discontinuous: In each subinterval, after scaling to [0, 1], the bang-bang control functions should either be less than tolerance_discontinuous or greater than 1 - tolerance_discontinuous simultaneously.
  • num_point_min: Minimum number of interpolation points.
  • num_point_max: Maximum number of interpolation points.
  • mesh_length_min: Minimum mesh length.
  • mesh_length_max: Maximum mesh length.
Returns:

The Variable s interpolated to the new discretization scheme.

def refine( self, value: pockit.base.variablebase.VariableBase | list[typing.Union[pockit.base.variablebase.VariableBase, typing.Iterable[float]]], absolute_tolerance_continuous: float = 1e-08, relative_tolerance_continuous: float = 1e-08, tolerance_discontinuous: float = 0.001, num_point_min: int = 6, num_point_max: int = 12, mesh_length_min: float = 0.001, mesh_length_max: float = 1) -> pockit.base.variablebase.VariableBase | list[typing.Union[pockit.base.variablebase.VariableBase, typing.Iterable[float]]]:

Adjust the mesh and the number of interpolation points to match the error tolerances.

If the discontinuous error is not within the tolerance, refine for discontinuous error. Otherwise, if the continuous error is not within the tolerance, refine for continuous error. At most one of the continuous or discontinuous refinements will be performed.

Arguments:
  • value: The variable to be checked. If the system has only one phase and no static variables, value can be a single Variable object. Otherwise, value should be a list of Variable objects, one for each Phase, followed by an array as values of static variables.
  • absolute_tolerance_continuous: Absolute tolerance for continuous error.
  • relative_tolerance_continuous: Relative tolerance for continuous error.
  • tolerance_discontinuous: In each subinterval, after scaling to [0, 1], the bang-bang control functions should either be less than tolerance_discontinuous or greater than 1 - tolerance_discontinuous simultaneously.
  • num_point_min: Minimum number of interpolation points.
  • num_point_max: Maximum number of interpolation points.
  • mesh_length_min: Minimum mesh length.
  • mesh_length_max: Maximum mesh length.
Returns:

The Variable s interpolated to the new discretization scheme.

n_s: int

Number of static parameters.

s: list[sympy.core.symbol.Symbol]

sympy.Symbol s of static parameters.

n_p: int

Number of phases.

pockit.phase.Phase s of system.

n_c: int

Number of system constraints.

pockit.base.fastfunc.FastFunc s of system constraints.

v_lb: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

Lower bounds of variables.

v_ub: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

Upper bounds of variables.

c_lb: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

Lower bounds of constraints.

c_ub: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

Upper bounds of constraints.

N: int

Number of phases.

L: int

Number of optimization variables of the discretized optimization problem.

ok: bool

Whether the system is fully configured.