Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
22 changes: 13 additions & 9 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
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, u_ ∈ Set_) && u == input
return Set, :U
end
elseif @capture(expr, x_ ∈ Set_)
if x == state
Expand Down
104 changes: 104 additions & 0 deletions src/systems.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3482,3 +3482,107 @@ 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 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
22 changes: 21 additions & 1 deletion test/continuous.jl
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ end

@testset "Linear parametric continuous systems" begin
@static if isdefined(@__MODULE__, :LazySets)
using LazySets: MatrixZonotope
using LazySets: MatrixZonotope, Zonotope

Ac = [1.0 0.0; 0.0 1.0]
A1 = [0.1 0.0; 0.0 0.0]
Expand Down Expand Up @@ -840,5 +840,25 @@ end
@test iscontrolled(sc)
@test !isnoisy(sc)
@test !isconstrained(sc)

X = Zonotope([0.0, 0.0], Matrix{Float64}(I, 2, 2))
U = Zonotope([0.0], Matrix{Float64}(I, 1, 1))

scc = ConstrainedLinearControlParametricContinuousSystem(A, B, X, U)
@test scc isa ConstrainedLinearControlParametricContinuousSystem

@test statedim(scc) == 2
@test inputdim(scc) == 1
@test noisedim(scc) == 0
@test state_matrix(scc) === A
@test input_matrix(scc) === B
@test stateset(scc) === X
@test inputset(scc) === U
@test islinear(scc)
@test isparametric(scc)
@test isaffine(scc)
@test iscontrolled(scc)
@test isconstrained(scc)
@test !isnoisy(scc)
end
end
20 changes: 20 additions & 0 deletions test/discrete.jl
Original file line number Diff line number Diff line change
Expand Up @@ -561,5 +561,25 @@ end
@test iscontrolled(sc)
@test !isnoisy(sc)
@test !isconstrained(sc)

X = Zonotope([0.0, 0.0], Matrix{Float64}(I, 2, 2))
U = Zonotope([0.0], Matrix{Float64}(I, 1, 1))

scd = ConstrainedLinearControlParametricDiscreteSystem(A, B, X, U)
@test scd isa ConstrainedLinearControlParametricDiscreteSystem

@test statedim(scd) == 2
@test inputdim(scd) == 1
@test noisedim(scd) == 0
@test state_matrix(scd) === A
@test input_matrix(scd) === B
@test stateset(scd) === X
@test inputset(scd) === U
@test islinear(scd)
@test isparametric(scd)
@test isaffine(scd)
@test iscontrolled(scd)
@test isconstrained(scd)
@test !isnoisy(scd)
end
end
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