Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/src/lib/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ SecondOrderContinuousSystem
SecondOrderConstrainedContinuousSystem
LinearParametricContinuousSystem
LinearControlParametricContinuousSystem
ConstrainedLinearControlParametricContinuousSystem
```

## Discrete Systems
Expand Down Expand Up @@ -98,6 +99,7 @@ SecondOrderDiscreteSystem
SecondOrderConstrainedDiscreteSystem
LinearParametricDiscreteSystem
LinearControlParametricDiscreteSystem
ConstrainedLinearControlParametricDiscreteSystem
```

#### Discretization Algorithms
Expand Down
2 changes: 2 additions & 0 deletions docs/src/man/systems.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ However in this table we only included continuous system types for brevity.
|SOCLCCS|[`SecondOrderConstrainedLinearControlContinuousSystem`](@ref)|
|LPCS|[`LinearParametricContinuousSystem`](@ref)|
|LCPCS|[`LinearControlParametricContinuousSystem`](@ref)|
|CLCPCS|[`ConstrainedLinearControlParametricContinuousSystem`](@ref)|

The following table summarizes the equation represented by each system type
(the names are given in abbreviated form). Again, discrete systems are not included. The column *Input constraints* is `yes` if the structure can model input or noise constraints (or both).
Expand Down Expand Up @@ -141,3 +142,4 @@ The following table summarizes the equation represented by each system type
|``Mx'' + Cx' + f_i(x) = f_e``, x ∈ X, u ∈ U``|yes|yes|SOCCS|
|``x' = A(θ)x, θ ∈ Θ``| no|no|LPCS|
|``x' = A(θ)x + B(θ)u, θ ∈ Θ``| no|no|LPCS|
|``x' = A(θ)x + B(θ)u, θ ∈ Θ, x ∈ X, u ∈ U``| no|yes|CLCPCS|
4 changes: 3 additions & 1 deletion src/MathematicalSystems.jl
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ export ContinuousIdentitySystem,
LinearParametricContinuousSystem,
LinearParametricDiscreteSystem,
LinearControlParametricContinuousSystem,
LinearControlParametricDiscreteSystem
LinearControlParametricDiscreteSystem,
ConstrainedLinearControlParametricContinuousSystem,
ConstrainedLinearControlParametricDiscreteSystem

#==================================
Concrete Types for Discrete Systems
Expand Down
24 changes: 14 additions & 10 deletions src/macros.jl
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ function _parse_system(exprs::NTuple{N,Expr}) where {N}

# error handling for the given set constraints
nsets = length(constraints)
nsets > 3 && throw(ArgumentError("cannot parse $nsets set constraints"))
nsets > 4 && throw(ArgumentError("cannot parse $nsets set constraints"))

# error handling for variable names
isnothing(state_var) && throw(ArgumentError("the state variable was not found"))
Expand Down Expand Up @@ -694,18 +694,18 @@ function constructor_input(lhs, rhs, set, parametric)
var_names = (rhs_var_names..., lhs_var_names..., set_var_names...)
if parametric
# strip off normal matrices from expressions (they are just variables)
if length(field_names) == 2
@assert field_names == (:A, :AS)
field_names = (field_names[2],)
@assert length(var_names) == 2
if field_names == (:A, :AS)
field_names = (:AS,)
@assert var_names == (:A, :AS)
var_names = (var_names[2],)
elseif length(field_names) == 4
@assert field_names == (:A, :B, :AS, :BS)
field_names = (field_names[3], field_names[4])
@assert length(var_names) == 4
var_names = (:AS,)
elseif field_names == (:A, :B, :AS, :BS)
@assert (var_names[3], var_names[4]) == (:AS, :BS)
field_names = (:AS, :BS)
var_names = (var_names[3], var_names[4])
elseif field_names == (:A, :B, :X, :U, :AS, :BS)
@assert (var_names[3], var_names[4], var_names[5], var_names[6]) == (:X, :U, :AS, :BS)
field_names = (:AS, :BS, :X, :U)
var_names = (var_names[5], var_names[6], var_names[3], var_names[4])
else
throw(ArgumentError("the entry $(field_names) does not match a " *
"parametric `MathematicalSystems.jl` structure"))
Expand All @@ -724,6 +724,10 @@ function extract_set_parameter(expr, state, input, noise, parametric) # input =>
return Set, :AS
elseif @capture(expr, B ∈ Set_)
return Set, :BS
elseif @capture(expr, x_ ∈ Set_) && x == state
return Set, :X
elseif @capture(expr, x_ ∈ Set_) && x == input
return Set, :U
end
elseif @capture(expr, x_ ∈ Set_)
if x == state
Expand Down
108 changes: 108 additions & 0 deletions src/systems.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3482,3 +3482,111 @@ for (Z, AZ) in
end
end
end

@doc """
ConstrainedLinearControlParametricContinuousSystem

Continuous-time linear parametric control system with state and input constraints of the form:

```math
x(t)' = A(θ) x(t) + B(θ) u(t), ; x(t) ∈ X, u(t) \\; ∈ U, θ ∈ \\Theta \\; ∀t
```

### Fields

- `AS` -- parametric state matrix
- `BS` -- parametric input matrix
- `X` -- state constraints
- `U` -- input constraints
"""
ConstrainedLinearControlParametricContinuousSystem

@doc """
ConstrainedLinearControlParametricDiscreteSystem

Discrete-time linear parametric control system with state and input constraints of the form:

```math
x_{k+1} = A(θ) x_k + B(θ) u_k, \\; x_k ∈ X \\; u_k ∈ U, θ ∈ \\Theta \\; ∀k
```

### Fields

- `AS` -- parametric state matrix
- `BS` -- parametric input matrix
- `X` -- states constraints
- `U` -- input constraints
"""
ConstrainedLinearControlParametricDiscreteSystem

for (Z, AZ) in
((:ConstrainedLinearControlParametricContinuousSystem, :AbstractContinuousSystem),
(:ConstrainedLinearControlParametricDiscreteSystem, :AbstractDiscreteSystem))
@eval begin
struct $(Z){MTA,MTB,XT, UT} <: $(AZ)
AS::MTA
BS::MTB
X::XT
U::UT

function $(Z)(AS::MTA, BS::MTB, X::XT, U::UT) where {MTA,MTB,XT,UT}
if checksquare(AS) != size(BS, 1)
throw(DimensionMismatch("incompatible dimensions"))
end
return new{MTA,MTB,XT,UT}(AS, BS, X, U)
end
end

function $(Z)(AS::Number, BS::Number, U)
return $(Z)(hcat(AS), hcat(BS), U)
end

function statedim(s::$Z)
return size(s.AS, 1)
end
function inputdim(s::$Z)
return size(s.BS, 2)
end
function noisedim(::$Z)
return 0
end
function state_matrix(s::$Z)
return s.AS
end
function input_matrix(s::$Z)
return s.BS
end
function stateset(s::$Z)
return s.X
end
function inputset(s::$Z)
return s.U
end
end

for T in [Z, Type{<:eval(Z)}]
@eval begin
function islinear(::$T)
return true
end
function isaffine(::$T)
return true
end
function ispolynomial(::$T)
return false
end
function isnoisy(::$T)
return false
end
function iscontrolled(::$T)
return true
end
function isconstrained(::$T)
return true
end
function isparametric(::$T)
return true
end
end
end
end
16 changes: 16 additions & 0 deletions test/@ivp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,19 @@
P3 = @ivp(@system(x' = -x), x(0) ∈ Interval(-1.0, 1.0))
@test P3 == testSystem
end

@testset "@ivp for constrained parametric control systems" begin
@static if isdefined(@__MODULE__, :LazySets)
AS = rand(MatrixZonotope)
BS = rand(MatrixZonotope)
U = BallInf(zeros(1), 1.0)
X = BallInf(zeros(1), 1.0)
X0 = Interval(-1.0, 1.0)

P = @ivp(x' = A * x + B * u, x(0) ∈ X0, x ∈ X, u ∈ U, A ∈ AS, B ∈ BS)
@test P == InitialValueProblem(ConstrainedLinearControlParametricContinuousSystem(AS, BS,
X, U), X0)
@test inputset(system(P)) == U
end
end

6 changes: 6 additions & 0 deletions test/@system.jl
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ end
BS = AS
sys = @system(x' = A * x + B * u, A ∈ AS, B ∈ BS)
@test sys == LinearControlParametricContinuousSystem(AS, BS)

sys = @system(x' = A * x + B * u, x ∈ X, u ∈ U, A ∈ AS, B ∈ BS)
@test sys == ConstrainedLinearControlParametricContinuousSystem(AS, BS, X, U)
end
end

Expand Down Expand Up @@ -320,6 +323,9 @@ end
BS = AS
sys = @system(x⁺ = A * x + B * u, A ∈ AS, B ∈ BS)
@test sys == LinearControlParametricDiscreteSystem(AS, BS)

sys = @system(x⁺ = A * x + B * u, x ∈ X, u ∈ U, A ∈ AS, B ∈ BS)
@test sys == ConstrainedLinearControlParametricDiscreteSystem(AS, BS, X, U)
end
end

Expand Down
4 changes: 2 additions & 2 deletions test/discretize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ end
!occursin("Descriptor", string(x)), subtypes(AbstractContinuousSystem))

# this test doesn't apply for second order systems and parametric systems
filter!(x -> x ∉ SECOND_ORDER_CTYPES && x ∉ PARAMETRIC_CTYPES, CTYPES)
filter!(x -> x ∉ SECOND_ORDER_CTYPES && !isparametric(x), CTYPES)

DTYPES = MathematicalSystems._complementary_type.(CTYPES)
n_types = length(CTYPES)
Expand Down Expand Up @@ -79,7 +79,7 @@ end
!occursin("Descriptor", string(x)), subtypes(AbstractContinuousSystem))

# this test doesn't apply for second order systems and parametric systems
filter!(x -> x ∉ SECOND_ORDER_CTYPES && x ∉ PARAMETRIC_CTYPES, CTYPES)
filter!(x -> x ∉ SECOND_ORDER_CTYPES && !isparametric(x), CTYPES)

DTYPES = MathematicalSystems._complementary_type.(CTYPES)
n_types = length(CTYPES)
Expand Down
Loading