Basics
- class rtctools.optimization.timeseries.Timeseries(times: ndarray, values: float | ndarray | list | DM)[source]
Bases:
object
Time series object, bundling time stamps with values.
- __init__(times: ndarray, values: float | ndarray | list | DM)[source]
Create a new time series object.
- Parameters:
times – Iterable of time stamps.
values – Iterable of values.
- property times: ndarray
Array of time stamps.
- property values: ndarray
Array of values.
- class rtctools.optimization.optimization_problem.OptimizationProblem(**kwargs)[source]
Bases:
DataStoreAccessor
Base class for all optimization problems.
- bounds() AliasDict[str, Tuple[float | ndarray | Timeseries, float | ndarray | Timeseries]] [source]
Returns variable bounds as a dictionary mapping variable names to a pair of bounds. A bound may be a constant, or a time series.
- Returns:
A dictionary of variable names and
(upper, lower)
bound pairs. The bounds may be numbers orTimeseries
objects.
Example:
def bounds(self): return {'x': (1.0, 2.0), 'y': (2.0, 3.0)}
- constant_inputs(ensemble_member: int) AliasDict[str, Timeseries] [source]
Returns a dictionary of constant inputs.
- Parameters:
ensemble_member – The ensemble member index.
- Returns:
A dictionary of constant input names and time series.
- constraints(ensemble_member: int) List[Tuple[MX, float | ndarray, float | ndarray]] [source]
Returns a list of constraints for the given ensemble member.
Call
OptimizationProblem.state_at()
to return a symbol representing a model variable at a given time.- Parameters:
ensemble_member – The ensemble member index.
- Returns:
A list of triples
(f, m, M)
, with anMX
object representing the constraint functionf
, lower boundm
, and upper boundM
. The bounds must be numbers.
Example:
def constraints(self, ensemble_member): t = 1.0 constraint1 = ( 2 * self.state_at('x', t, ensemble_member), 2.0, 4.0) constraint2 = ( self.state_at('x', t, ensemble_member) + self.state_at('y', t, ensemble_member), 2.0, 3.0) return [constraint1, constraint2]
- control(variable: str) MX [source]
Returns an
MX
symbol for the given control input, not bound to any time.- Parameters:
variable – Variable name.
- Returns:
MX
symbol for given control input.- Raises:
KeyError
- abstract control_at(variable: str, t: float, ensemble_member: int = 0, scaled: bool = False) MX [source]
Returns an
MX
symbol representing the given control input at the given time.- Parameters:
variable – Variable name.
t – Time.
ensemble_member – The ensemble member index.
scaled – True to return the scaled variable.
- Returns:
MX
symbol representing the control input at the given time.- Raises:
KeyError
- delayed_feedback() List[Tuple[str, str, float]] [source]
Returns the delayed feedback mappings. These are given as a list of triples \((x, y, \tau)\), to indicate that \(y = x(t - \tau)\).
- Returns:
A list of triples.
Example:
def delayed_feedback(self): fb1 = ['x', 'y', 0.1] fb2 = ['x', 'z', 0.2] return [fb1, fb2]
- abstract der(variable: str) MX [source]
Returns an
MX
symbol for the time derivative given state, not bound to any time.- Parameters:
variable – Variable name.
- Returns:
MX
symbol for given state.- Raises:
KeyError
- abstract der_at(variable: str, t: float, ensemble_member: int = 0) MX [source]
Returns an expression for the time derivative of the specified variable at time t.
- Parameters:
variable – Variable name.
t – Time.
ensemble_member – The ensemble member index.
- Returns:
MX
object representing the derivative.- Raises:
KeyError
- ensemble_member_probability(ensemble_member: int) float [source]
The probability of an ensemble member occurring.
- Parameters:
ensemble_member – The ensemble member index.
- Returns:
The probability of an ensemble member occurring.
- Raises:
IndexError
- property ensemble_size: int
The number of ensemble members.
- get_timeseries(variable: str, ensemble_member: int = 0) Timeseries [source]
Looks up a timeseries from the internal data store.
- Parameters:
variable – Variable name.
ensemble_member – The ensemble member index.
- Returns:
The requested time series.
- Return type:
- Raises:
KeyError
- history(ensemble_member: int) AliasDict[str, Timeseries] [source]
Returns the state history.
- Parameters:
ensemble_member – The ensemble member index.
- Returns:
A dictionary of variable names and historical time series (up to and including t0).
- property initial_time: float
The initial time in seconds.
- abstract integral(variable: str, t0: float = None, tf: float = None, ensemble_member: int = 0) MX [source]
Returns an expression for the integral over the interval [t0, tf].
- Parameters:
variable – Variable name.
t0 – Left bound of interval. If equal to None, the initial time is used.
tf – Right bound of interval. If equal to None, the final time is used.
ensemble_member – The ensemble member index.
- Returns:
MX
object representing the integral.- Raises:
KeyError
- interpolate(t: float | ndarray, ts: ndarray, fs: ndarray, f_left: float = nan, f_right: float = nan, mode: int = 0) float | ndarray [source]
Linear interpolation over time.
- Parameters:
t (float or vector of floats) – Time at which to evaluate the interpolant.
ts (numpy array) – Time stamps.
fs – Function values at time stamps ts.
f_left – Function value left of leftmost time stamp.
f_right – Function value right of rightmost time stamp.
mode – Interpolation mode.
- Returns:
The interpolated value.
- lookup_tables(ensemble_member: int) AliasDict[str, LookupTable] [source]
Returns a dictionary of lookup tables.
- Parameters:
ensemble_member – The ensemble member index.
- Returns:
A dictionary of variable names and lookup tables.
- static merge_bounds(a: Tuple[float | ndarray | Timeseries, float | ndarray | Timeseries], b: Tuple[float | ndarray | Timeseries, float | ndarray | Timeseries]) Tuple[float | ndarray | Timeseries, float | ndarray | Timeseries] [source]
Returns a pair of bounds which is the intersection of the two pairs of bounds given as input.
- Parameters:
a – First pair
(upper, lower)
boundsb – Second pair
(upper, lower)
bounds
- Returns:
A pair of
(upper, lower)
bounds which is the intersection of the two input bounds.
- objective(ensemble_member: int) MX [source]
The objective function for the given ensemble member.
Call
OptimizationProblem.state_at()
to return a symbol representing a model variable at a given time.- Parameters:
ensemble_member – The ensemble member index.
- Returns:
An
MX
object representing the objective function.
Example:
def objective(self, ensemble_member): # Return value of state 'x' at final time: times = self.times() return self.state_at('x', times[-1], ensemble_member)
- optimize(preprocessing: bool = True, postprocessing: bool = True, log_solver_failure_as_error: bool = True) bool [source]
Perform one initialize-transcribe-solve-finalize cycle.
- Parameters:
preprocessing – True to enable a call to
pre
preceding the optimization.postprocessing – True to enable a call to
post
following the optimization.
- Returns:
True on success.
- parameters(ensemble_member: int) AliasDict[str, bool | int | float | MX] [source]
Returns a dictionary of parameters.
- Parameters:
ensemble_member – The ensemble member index.
- Returns:
A dictionary of parameter names and values.
- path_constraints(ensemble_member: int) List[Tuple[MX, float | ndarray, float | ndarray]] [source]
Returns a list of path constraints.
Path constraints apply to all times and ensemble members simultaneously. Call
OptimizationProblem.state()
to return a time- and ensemble-member-independent symbol representing a model variable.- Parameters:
ensemble_member – The ensemble member index. This index may only be used to supply member-dependent bounds.
- Returns:
A list of triples
(f, m, M)
, with anMX
object representing the path constraint functionf
, lower boundm
, and upper boundM
. The bounds may be numbers orTimeseries
objects.
Example:
def path_constraints(self, ensemble_member): # 2 * x must lie between 2 and 4 for every time instance. path_constraint1 = (2 * self.state('x'), 2.0, 4.0) # x + y must lie between 2 and 3 for every time instance path_constraint2 = (self.state('x') + self.state('y'), 2.0, 3.0) return [path_constraint1, path_constraint2]
- path_objective(ensemble_member: int) MX [source]
Returns a path objective the given ensemble member.
Path objectives apply to all times and ensemble members simultaneously. Call
OptimizationProblem.state()
to return a time- and ensemble-member-independent symbol representing a model variable.- Parameters:
ensemble_member – The ensemble member index. This index is currently unused, and here for future use only.
- Returns:
A
MX
object representing the path objective.
Example:
def path_objective(self, ensemble_member): # Minimize x(t) for all t return self.state('x')
- seed(ensemble_member: int) AliasDict[str, float | Timeseries] [source]
Seeding data. The optimization algorithm is seeded with the data returned by this method.
- Parameters:
ensemble_member – The ensemble member index.
- Returns:
A dictionary of variable names and seed time series.
- set_timeseries(variable: str, timeseries: Timeseries, ensemble_member: int = 0, output: bool = True, check_consistency: bool = True) None [source]
Sets a timeseries in the internal data store.
- Parameters:
variable – Variable name.
timeseries (iterable of floats, or
Timeseries
) – Time series data.ensemble_member – The ensemble member index.
output – Whether to include this time series in output data files.
check_consistency – Whether to check consistency between the time stamps on the new timeseries object and any existing time stamps.
- solver_options() Dict[str, str | int | float | bool] [source]
Returns a dictionary of CasADi optimization problem solver options.
The default solver for continuous problems is Ipopt.
The default solver for mixed integer problems is Bonmin.
- Returns:
A dictionary of solver options. See the CasADi and respective solver documentation for details.
- solver_success(solver_stats: Dict[str, str | bool], log_solver_failure_as_error: bool) Tuple[bool, int] [source]
Translates the returned solver statistics into a boolean and log level to indicate whether the solve was succesful, and how to log it.
- Parameters:
solver_stats – Dictionary containing information about the solver status. See explanation below.
log_solver_failure_as_error – Indicates whether a solve failure Should be logged as an error or info message.
solver_stats
typically consist of three fields:return_status:
str
secondary_return_status:
str
success:
bool
By default we rely on CasADi’s interpretation of the return_status (and secondary status) to the success variable, with an exception for IPOPT (see below).
The logging level is typically
logging.INFO
for success, andlogging.ERROR
for failure. Only for IPOPT an exception is made for Not_Enough_Degrees_Of_Freedom, which returnslogging.WARNING
instead. For example, this can happen when too many goals are specified, and lower priority goals cannot improve further on the current result.- Returns:
A tuple indicating whether or not the solver has succeeded, and what level to log it with.
- state(variable: str) MX [source]
Returns an
MX
symbol for the given state, not bound to any time.- Parameters:
variable – Variable name.
- Returns:
MX
symbol for given state.- Raises:
KeyError
- abstract state_at(variable: str, t: float, ensemble_member: int = 0, scaled: bool = False) MX [source]
Returns an
MX
symbol representing the given variable at the given time.- Parameters:
variable – Variable name.
t – Time.
ensemble_member – The ensemble member index.
scaled – True to return the scaled variable.
- Returns:
MX
symbol representing the state at the given time.- Raises:
KeyError
- abstract states_in(variable: str, t0: float = None, tf: float = None, ensemble_member: int = 0) Iterator[MX] [source]
Iterates over symbols for states in the interval [t0, tf].
- Parameters:
variable – Variable name.
t0 – Left bound of interval. If equal to None, the initial time is used.
tf – Right bound of interval. If equal to None, the final time is used.
ensemble_member – The ensemble member index.
- Raises:
KeyError
- rtctools.util.run_optimization_problem(optimization_problem_class, base_folder='..', log_level=20, profile=False, **kwargs)[source]
Sets up and solves an optimization problem.
This function makes the following assumptions:
That the
base_folder
contains subfoldersinput
,output
, andmodel
, containing input data, output data, and the model, respectively.When using
CSVLookupTableMixin
, that the base folder contains a subfolderlookup_tables
.When using
ModelicaMixin
, that the base folder contains a subfoldermodel
.When using
ModelicaMixin
, that the toplevel Modelica model name equals the class name.
- Parameters:
optimization_problem_class – Optimization problem class to solve.
base_folder – Base folder.
log_level – The log level to use.
profile – Whether or not to enable profiling.
- Returns:
OptimizationProblem
instance.