Optim
This folder contains all the different (abstraction-based or not) solvers that can be used. Note that all the solvers are defined using the MathOptInterface framework as a subtype of AbstractOptimizer
by implementig the optimize!
function.
Abstraction-based solvers
Uniform grid abstraction solver
Dionysos.Optim.Abstraction.UniformGridAbstraction.Optimizer
— TypeOptimizer{T} <: MOI.AbstractOptimizer
A high-level abstraction-based solver that automatically orchestrates system abstraction and control synthesis. This wrapper follows the classical abstraction pipeline (e.g., as in SCOTS), where the state and input spaces are discretized into hyper-rectangular cells, independent of the specific control task.
It delegates responsibility to modular sub-solvers: one for abstraction and one for control, depending on the type of problem to be solved.
Structure and Sub-solvers
The optimizer internally manages two sub-solvers:
abstraction_solver
:OptimizerEmptyProblem
: Used to compute the symbolic abstraction of the system from its dynamics and domain.control_solver
: One of the following control-specific optimizers, depending on the problem type:
Behavior
The user sets the control task via:
MOI.set(optimizer, MOI.RawOptimizerAttribute("concrete_problem"), my_problem)
wheremy_problem
is a subtype ofProblemType
.The optimizer automatically dispatches to the appropriate control solver based on the problem type.
If the abstraction has not yet been computed, it is automatically built before solving the control problem.
Once computed, the abstraction is cached — switching the control problem (e.g., from safety to reachability) does not recompute it.
The field
solve_time_sec
tracks the runtime of the last call toMOI.optimize!
.The resulting controller and value function are stored and can be queried from the wrapper.
User-settable and access to subsolver fields
Via MOI.set(...)
, the user may configure abstraction_solver
and control_solver
parameters. Any field accessible in the sub-solvers (abstraction or control) can be transparently accessed via:
MOI.set(optimizer, MOI.RawOptimizerAttribute("state_grid"), grid)
MOI.get(optimizer, MOI.RawOptimizerAttribute("abstract_value_function"))
Example
using Dionysos, JuMP
optimizer = MOI.instantiate(Dionysos.Optim.UniformGridAbstraction.Optimizer)
MOI.set(optimizer, MOI.RawOptimizerAttribute("concrete_problem"), my_problem)
MOI.set(optimizer, MOI.RawOptimizerAttribute("state_grid"), state_grid)
MOI.set(optimizer, MOI.RawOptimizerAttribute("input_grid"), input_grid)
MOI.set(optimizer, MOI.RawOptimizerAttribute("time_step"), 0.1)
MOI.set(optimizer, MOI.RawOptimizerAttribute("print_level"), 2)
MOI.optimize!(optimizer)
time = MOI.get(optimizer, MOI.RawOptimizerAttribute("solve_time_sec"))
value_fun = MOI.get(optimizer, MOI.RawOptimizerAttribute("abstract_value_function"))
controller = MOI.get(optimizer, MOI.RawOptimizerAttribute("concrete_controller"))
Dionysos.Optim.Abstraction.UniformGridAbstraction.OptimizerEmptyProblem
— TypeOptimizerEmptyProblem{T} <: MOI.AbstractOptimizer
A solver responsible for constructing an abstraction of the system dynamics, independently of the control specification.
This optimizer wraps everything needed to solve an EmptyProblem
, which is used to generate a symbolic model (abstraction) of either a continuous- or discrete-time system.
Purpose
This optimizer builds a symbolic abstraction by simulating or approximating the behavior of the given system. The abstraction method is chosen via the approx_mode
field, and determines which parameters and approximation logic are used.
Parameters
Mandatory fields set by the user
empty_problem
(required): An instance ofEmptyProblem
containing the system to abstract and the state region.state_grid
(required): The discretization grid for the state space.input_grid
(required): The discretization grid for the input space.
Optional user-tunable fields
time_step
(optional, required if the system is continuous): Time step used for discretizing or simulating continuous-time systems.nsystem
(optional, default =5
): Number of substeps to use when simulating continuous-time systems (e.g., in Runge-Kutta integration).approx_mode
(required): The abstraction technique to use. Supported modes:USER_DEFINED
: Use a custom overapproximation function. Setoverapproximation_map::Function
.GROWTH
: Use growth-bound based overapproximation. Setjacobian_bound
, optionallygrowthbound_map
,ngrowthbound
.LINEARIZED
: Use linearization + Jacobian/Hessian. SetDF_sys
,bound_DF
, andbound_DDF
.CENTER_SIMULATION
: Simulate the center of each cell only.RANDOM_SIMULATION
: Sample and simulate random points in each cell. Setn_samples
.
efficient
(optional, default =true
): Whether to use optimized internal routines based onapprox_mode
.print_level
(optional, default =1
): Verbosity level:0
: silent1
: standard2
: verbose/debug
Internally computed fields (after MOI.optimize!
)
abstract_system
: The resulting symbolic abstraction, of typeSymbolicModelList
.discrete_time_system
: Internally constructed discrete-time version of the system used during abstraction.abstraction_construction_time_sec
: Time (in seconds) spent constructing the abstraction.
System approximation objects (derived from approx_mode
)
continuous_time_system_approximation
: AContinuousTimeSystemApproximation
, automatically created if the original system is continuous.discrete_time_system_approximation
: ADiscreteTimeSystemApproximation
, created in all cases.
Example
using Dionysos, JuMP
optimizer = MOI.instantiate(Dionysos.Optim.OptimizerEmptyProblem.Optimizer)
MOI.set(optimizer, MOI.RawOptimizerAttribute("concrete_problem"), my_problem)
MOI.set(optimizer, MOI.RawOptimizerAttribute("state_grid"), state_grid)
MOI.set(optimizer, MOI.RawOptimizerAttribute("input_grid"), input_grid)
MOI.set(optimizer, MOI.RawOptimizerAttribute("time_step"), 0.1)
MOI.set(optimizer, MOI.RawOptimizerAttribute("print_level"), 2)
MOI.set(optimizer, MOI.RawOptimizerAttribute("approx_mode"), GROWTH)
MOI.set(optimizer, MOI.RawOptimizerAttribute("jacobian_bound"), my_jacobian_bound)
MOI.optimize!(optimizer)
time = MOI.get(optimizer, MOI.RawOptimizerAttribute("abstraction_construction_time_sec"))
abstract_system = MOI.get(optimizer, MOI.RawOptimizerAttribute("abstract_system"))
discrete_time_system = MOI.get(optimizer, MOI.RawOptimizerAttribute("discrete_time_system"))
Dionysos.Optim.Abstraction.UniformGridAbstraction.OptimizerOptimalControlProblem
— TypeOptimizerOptimalControlProblem{T} <: MOI.AbstractOptimizer
An optimizer that solves reachability or reach-avoid optimal control problems using symbolic abstractions of the system.
This solver takes as input a concrete problem (typically an instance of OptimalControlProblem
) and a symbolic abstraction of the system (i.e., an abstract_system
). It then solves the abstract version of the control problem.
Key Behavior
- Lifts the concrete problem to the symbolic abstraction space (
abstract_system
) and constructs the correspondingabstract_problem
. - Computes the
controllable_set
— the largest set of abstract states from which reachability can be guaranteed. - Synthesizes an
abstract_controller
that brings the system to the target set under worst-case dynamics. - Computes the
abstract_value_function
that maps each state (cell) to the worst-case number of steps needed to reach the target. - The solver is successful if the field
success
istrue
afterMOI.optimize!
.
Parameters
Mandatory fields set by the user
concrete_problem
(required): An instance ofOptimalControlProblem
that defines the reach-avoid task (system, initial set, target, costs, horizon).abstract_system
(required): The symbolic abstraction of the system, usually obtained from an abstraction optimizer such asOptimizerEmptyProblem
.
Optional user-tunable parameters
early_stop
(optional, default =true
): Iftrue
, the fixpoint algorithm stops early when the initial set is fully contained in the controllable set. Iffalse
, it computes the entire maximal controllable set.sparse_input
(optional, default =false
): Iftrue
, uses a sparse representation of the transition table, reducing memory usage when the number of inputs is large but only few are admissible per state (e.g., indeterminized abstractions
, withnew_input = (input, target)
).print_level
(optional, default =1
): Controls verbosity:0
: silent1
: default2
: detailed logging
Internally computed fields
These fields are generated automatically during MOI.optimize!
.
abstract_problem
: The lifted version of the concrete problem over the abstract system.abstract_problem_time_sec
: Time taken to solve the abstract problem.abstract_controller
: A controller mapping abstract states to control inputs.controllable_set
: Set of abstract states from which the target is reachable.uncontrollable_set
: Complementary states with no admissible reachability strategy.value_fun_tab
: Tabular value function over abstract states (e.g., cost-to-go or step count).abstract_value_function
: Functional form of the abstract value function.concrete_value_function
: Functional form of the value function mapped back to the original system.success
: Boolean flag indicating whether the solver completed successfully.
Example
using Dionysos, JuMP
optimizer = MOI.instantiate(Dionysos.Optim.OptimizerOptimalControlProblem.Optimizer)
MOI.set(optimizer, MOI.RawOptimizerAttribute("concrete_problem"), my_problem)
MOI.set(optimizer, MOI.RawOptimizerAttribute("abstract_system"), abstract_system)
MOI.set(optimizer, MOI.RawOptimizerAttribute("print_level"), 2)
MOI.optimize!(optimizer)
time = MOI.get(optimizer, MOI.RawOptimizerAttribute("abstract_problem_time_sec"))
controllable_set = MOI.get(optimizer, MOI.RawOptimizerAttribute("controllable_set"))
abstract_value_function = MOI.get(optimizer, MOI.RawOptimizerAttribute("abstract_value_function"))
concrete_value_function = MOI.get(optimizer, MOI.RawOptimizerAttribute("concrete_value_function"))
abstract_controller = MOI.get(optimizer, MOI.RawOptimizerAttribute("concrete_controller"))
Dionysos.Optim.Abstraction.UniformGridAbstraction.OptimizerSafetyProblem
— TypeOptimizerSafetyProblem{T} <: MOI.AbstractOptimizer
An optimizer for solving safety control problems over symbolic system abstractions.
This solver takes as input a SafetyProblem
and a symbolic abstraction of the system (e.g., a SymbolicModelList
), and computes a controller that ensures the system remains within a safe set over a time horizon or indefinitely.
Key Behavior
- Lifts the concrete safety problem to the abstract domain and builds an
abstract_problem
. - Computes the invariant set, i.e., the largest set of abstract states from which all trajectories can be safely controlled.
- Synthesizes an
abstract_controller
that guarantees safety under worst-case transitions. - The optimization is successful if
success == true
after callingMOI.optimize!
.
Parameters
Mandatory fields set by the user
concrete_problem
(required): An instance ofSafetyProblem
that specifies the system, initial set, safe set, and horizon.abstract_system
(required): A symbolic abstraction of the system, e.g., obtained fromOptimizerEmptyProblem
.
Optional user-tunable parameters
print_level
(optional, default =1
): Controls verbosity:0
: silent1
: default (info)2
: verbose debug output
Internally computed fields
These fields are automatically filled in by MOI.optimize!
.
abstract_problem
: The lifted version of the safety problem in the symbolic domain.abstract_problem_time_sec
: Time taken to solve the safety problem over the abstract system.abstract_controller
: A controller mapping abstract states to admissible inputs that keep the system safe.invariant_set
: The largest subset of abstract states from which safety can be maintained.invariant_set_complement
: States from which safety cannot be guaranteed.success
: Boolean flag indicating whether a valid invariant set and controller were found.
Example
using Dionysos, JuMP
optimizer = MOI.instantiate(Dionysos.Optim.OptimizerSafetyProblem.Optimizer)
MOI.set(optimizer, MOI.RawOptimizerAttribute("concrete_problem"), my_problem)
MOI.set(optimizer, MOI.RawOptimizerAttribute("abstract_system"), abstract_system)
MOI.set(optimizer, MOI.RawOptimizerAttribute("print_level"), 2)
MOI.optimize!(optimizer)
time = MOI.get(optimizer, MOI.RawOptimizerAttribute("abstract_problem_time_sec"))
invariant_set = MOI.get(optimizer, MOI.RawOptimizerAttribute("invariant_set"))
abstract_controller = MOI.get(optimizer, MOI.RawOptimizerAttribute("concrete_controller"))
Other abstraction-based solvers
Dionysos.Optim.Abstraction.EllipsoidsAbstraction.Optimizer
— TypeOptimizer{T} <: MOI.AbstractOptimizer
Abstraction-based solver for which the domain is covered with ellipsoidal cells, independently of the control task.
Dionysos.Optim.Abstraction.HierarchicalAbstraction.Optimizer
— TypeOptimizer{T} <: MOI.AbstractOptimizer
Abstraction-based solver for which the domain is initially partioned into coarse hyper-rectangular cells, which are iteratively locally smartly refined with respect to the control task.
Dionysos.Optim.Abstraction.LazyAbstraction.Optimizer
— TypeOptimizer{T} <: MOI.AbstractOptimizer
Abstraction-based solver for which the hyper-rectangular abstraction and the controller are co-designed to reduce the computation cost of the abstraction.
Dionysos.Optim.Abstraction.LazyEllipsoidsAbstraction.Optimizer
— TypeOptimizer{T} <: MOI.AbstractOptimizer
Abstraction-based solver using the lazy abstraction method with ellipsoidal cells.
Other solvers
Dionysos.Optim.BemporadMorari.Optimizer
— TypeOptimizer{T} <: MOI.AbstractOptimizer
Bemporad Morari solver: Optimal control of hybrid systems via a predictive control scheme using mixed integer quadratic programming (MIQP) online optimization procedures.
Dionysos.Optim.BranchAndBound.Optimizer
— TypeOptimizer{T} <: MOI.AbstractOptimizer
Branch and bound solver: Optimal control of hybrid systems via a predictive control scheme combining a branch and bound algorithm that can refine Q-functions using Lagrangian duality.