Skip to content

Commit

Permalink
Update to new versions (#60)
Browse files Browse the repository at this point in the history
* Update to new versions

* Bump version

* Algebraic -> Descriptor

* Fixes

* Fix

* Fix

* v0.3.0
  • Loading branch information
blegat authored Aug 13, 2024
1 parent 19c5002 commit d035ed2
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 59 deletions.
43 changes: 15 additions & 28 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "SwitchOnSafety"
uuid = "ceb7f16a-07bf-5f4a-9354-b68f01b1610f"
repo = "https://github.com/blegat/SwitchOnSafety.jl.git"
version = "0.2.4"
version = "0.3.0"

[deps]
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
Expand Down Expand Up @@ -29,37 +29,24 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
SumOfSquares = "4b9e565b-77fc-50a5-a571-1244f986bda1"

[compat]
CSDP = "1"
Combinatorics = "1"
DynamicPolynomials = "0.4"
ECOS = "1"
FillArrays = "0.7, 0.8, 0.9, 0.10, 0.11, 0.12, 0.13"
GLPK = "1"
GraphPlot = "0.3, 0.4, 0.5"
DynamicPolynomials = "0.5"
FillArrays = "1"
GraphPlot = "0.3, 0.4, 0.5, 0.6"
Graphs = "1"
HybridSystems = "0.4"
JuMP = "0.23, 1"
JuMP = "1"
MathOptInterface = "1"
MathematicalSystems = "0.11, 0.12"
MultivariateMoments = "0.3"
MultivariatePolynomials = "0.4"
Optim = "0.19, 0.20, 0.21, 0.22, 1"
MathematicalSystems = "0.11, 0.12, 0.13"
MultivariateMoments = "0.4"
MultivariatePolynomials = "0.5"
Optim = "1"
ParameterJuMP = "0.4"
Polyhedra = "0.7"
RecipesBase = "0.7, 0.8, 1"
Reexport = "0.2, 1"
SemialgebraicSets = "0.2"
SetProg = "0.3.1"
StaticArrays = "0.11, 0.12, 1"
SumOfSquares = "0.6"
RecipesBase = "1"
Reexport = "1"
SemialgebraicSets = "0.3"
SetProg = "0.4"
StaticArrays = "1"
SumOfSquares = "0.7"
julia = "1.6"

[extras]
CSDP = "0a46da34-8e4b-519e-b418-48813639ff34"
ECOS = "e2685f51-7e38-5353-a97d-a921fd2c8199"
GLPK = "60bf3e95-4087-53dc-ae20-288a0d20c6a6"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["LinearAlgebra", "Test", "CSDP", "ECOS", "GLPK"]
46 changes: 23 additions & 23 deletions src/invariant.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ using FillArrays
function algebraiclift(s::ConstrainedLinearControlDiscreteSystem)
A = [s.A s.B]
E = [Matrix(one(eltype(s.A)) * I, size(s.A)...) zeros(eltype(s.A), size(s.B)...)]
return ConstrainedLinearAlgebraicDiscreteSystem(A, E, stateset(s) * inputset(s))
return ConstrainedLinearDescriptorDiscreteSystem(A, E, stateset(s) * inputset(s))
end
function algebraiclift(s::ConstrainedLinearControlDiscreteSystem{T, MTA, MTB, ST, FullSpace}) where {T, MTA <: AbstractMatrix{T}, MTB <: AbstractMatrix{T}, ST}
as = algebraiclift(LinearControlDiscreteSystem(s.A, s.B))
return ConstrainedLinearAlgebraicDiscreteSystem(as.A, as.E, stateset(s))
return ConstrainedLinearDescriptorDiscreteSystem(as.A, as.E, stateset(s))
end
function algebraiclift(s::LinearControlDiscreteSystem)
n = statedim(s)
Expand All @@ -29,7 +29,7 @@ function algebraiclift(s::LinearControlDiscreteSystem)
null = nullspace(s.B[nz, :]')'
Enz = zeros(eltype(null), size(null, 1), n)
Enz[:, nz] = null
return LinearAlgebraicDiscreteSystem([s.A[z, :]; Enz * s.A], [Ez; Enz])
return LinearDescriptorDiscreteSystem([s.A[z, :]; Enz * s.A], [Ez; Enz])
end
algebraiclift(s::ConstrainedDiscreteIdentitySystem) = s
algebraiclift(S::AbstractVector) = algebraiclift.(S)
Expand All @@ -47,41 +47,41 @@ function constrain_invariance(model, ::IdentityMap, source_set, target_set, λ)
function constrain_invariance(model, s::LinearMap, source_set, target_set, λ)
return @constraint(model, s.A * source_set target_set)
end
function constrain_invariance(model, s::LinearAlgebraicDiscreteSystem,
function constrain_invariance(model, s::LinearDescriptorDiscreteSystem,
source_set, target_set, λ)
return @constraint(model, s.A * source_set s.E * target_set,
S_procedure_scaling = λ)
end

function Polyhedra.translate(system::ConstrainedLinearAlgebraicDiscreteSystem, c)
return ConstrainedAffineAlgebraicDiscreteSystem(
function Polyhedra.translate(system::ConstrainedLinearDescriptorDiscreteSystem, c)
return ConstrainedAffineDescriptorDiscreteSystem(
system.A, system.E, system.E * c - system.A * c,
Polyhedra.translate(stateset(system), c))
end

struct ConstrainedAffineAlgebraicDiscreteSystem{T, MTA <: AbstractMatrix{T}, MTE <: AbstractMatrix{T}, VTB <: AbstractVector{T}, ST} <: AbstractDiscreteSystem
struct ConstrainedAffineDescriptorDiscreteSystem{T, MTA <: AbstractMatrix{T}, MTE <: AbstractMatrix{T}, VTB <: AbstractVector{T}, ST} <: AbstractDiscreteSystem
A::MTA
E::MTE
b::VTB
X::ST
end
MathematicalSystems.statedim(s::ConstrainedAffineAlgebraicDiscreteSystem) = size(s.A, 1)
MathematicalSystems.stateset(s::ConstrainedAffineAlgebraicDiscreteSystem) = s.X
MathematicalSystems.inputdim(::ConstrainedAffineAlgebraicDiscreteSystem) = 0
MathematicalSystems.islinear(::ConstrainedAffineAlgebraicDiscreteSystem) = false
MathematicalSystems.isaffine(::ConstrainedAffineAlgebraicDiscreteSystem) = true
MathematicalSystems.statedim(s::ConstrainedAffineDescriptorDiscreteSystem) = size(s.A, 1)
MathematicalSystems.stateset(s::ConstrainedAffineDescriptorDiscreteSystem) = s.X
MathematicalSystems.inputdim(::ConstrainedAffineDescriptorDiscreteSystem) = 0
MathematicalSystems.islinear(::ConstrainedAffineDescriptorDiscreteSystem) = false
MathematicalSystems.isaffine(::ConstrainedAffineDescriptorDiscreteSystem) = true

struct AffineAlgebraicDiscreteSystem{T, MTA <: AbstractMatrix{T}, MTE <: AbstractMatrix{T}, VTB <: AbstractVector{T}} <: AbstractDiscreteSystem
struct AffineDescriptorDiscreteSystem{T, MTA <: AbstractMatrix{T}, MTE <: AbstractMatrix{T}, VTB <: AbstractVector{T}} <: AbstractDiscreteSystem
A::MTA
E::MTE
b::VTB
end
MathematicalSystems.statedim(s::AffineAlgebraicDiscreteSystem) = size(s.A, 1)
MathematicalSystems.inputdim(::AffineAlgebraicDiscreteSystem) = 0
MathematicalSystems.islinear(::AffineAlgebraicDiscreteSystem) = false
MathematicalSystems.isaffine(::AffineAlgebraicDiscreteSystem) = true
MathematicalSystems.statedim(s::AffineDescriptorDiscreteSystem) = size(s.A, 1)
MathematicalSystems.inputdim(::AffineDescriptorDiscreteSystem) = 0
MathematicalSystems.islinear(::AffineDescriptorDiscreteSystem) = false
MathematicalSystems.isaffine(::AffineDescriptorDiscreteSystem) = true

function constrain_invariance(model, s::AffineAlgebraicDiscreteSystem,
function constrain_invariance(model, s::AffineDescriptorDiscreteSystem,
source_set, target_set, λ)
return @constraint(model, s.A * source_set + s.b s.E * target_set,
S_procedure_scaling = λ)
Expand Down Expand Up @@ -261,17 +261,17 @@ _mode(s::AbstractDiscreteSystem) = ConstrainedContinuousIdentitySystem(statedim(
_resetmap(s::AbstractContinuousSystem) = IdentityMap(statedim(s))
_resetmap(s::ConstrainedDiscreteIdentitySystem) = IdentityMap(statedim(s))
_resetmap(s::ConstrainedLinearDiscreteSystem) = LinearMap(s.A)
# TODO need to add LinearAlgebraicMap to MathematicalSystems
_resetmap(s::ConstrainedLinearAlgebraicDiscreteSystem) = LinearAlgebraicDiscreteSystem(s.A, s.E)
_resetmap(s::ConstrainedAffineAlgebraicDiscreteSystem) = AffineAlgebraicDiscreteSystem(s.A, s.E, s.b)
# TODO need to add LinearDescriptorMap to MathematicalSystems
_resetmap(s::ConstrainedLinearDescriptorDiscreteSystem) = LinearDescriptorDiscreteSystem(s.A, s.E)
_resetmap(s::ConstrainedAffineDescriptorDiscreteSystem) = AffineDescriptorDiscreteSystem(s.A, s.E, s.b)

function invariant_set(
system::Union{
ConstrainedContinuousIdentitySystem,
ConstrainedDiscreteIdentitySystem,
ConstrainedLinearDiscreteSystem,
ConstrainedLinearAlgebraicDiscreteSystem,
ConstrainedAffineAlgebraicDiscreteSystem},
ConstrainedLinearDescriptorDiscreteSystem,
ConstrainedAffineDescriptorDiscreteSystem},
optimizer_constructor,
set_variable::SetProg.AbstractVariable=default_variable(system, optimizer_constructor);
λ=nothing,
Expand Down
4 changes: 2 additions & 2 deletions src/sosdata.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function SOSData{S, TT, XT, PT, DT}(s::S) where {S, TT,
XT <: HybridSystems.StateProperty,
PT <: HybridSystems.StateProperty,
DT <: HybridSystems.TransitionProperty}
y = HybridSystems.state_property(s, Vector{PolyVar{true}})::XT
y = HybridSystems.state_property(s, Vector{SetProg.Sets.SpaceVariable})::XT
for st in states(s)
@polyvar x[1:statedim(s, st)]
y[st] = x
Expand All @@ -41,7 +41,7 @@ const MeasureLyapunov{T} = MultivariateMoments.MomentMatrix{T, SetProg.Sets.Mono
function SOSData(s::AbstractDiscreteSwitchedSystem)
S = typeof(s)
TT = transitiontype(s)
XT = HybridSystems.state_property_type(S, Vector{PolyVar{true}})
XT = HybridSystems.state_property_type(S, Vector{SetProg.Sets.SpaceVariable})
PT = HybridSystems.state_property_type(S, PolynomialLyapunov{Float64})
DT = HybridSystems.transition_property_type(S, MeasureLyapunov{Float64})
SOSData{S, TT, XT, PT, DT}(s)
Expand Down
2 changes: 1 addition & 1 deletion src/sosext.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ end

function extractatomic(s::AbstractDiscreteSwitchedSystem, d, t, ranktol,
dual=getlyap(s, d).dual)
atoms = extractatoms(dual[t], ranktol)
atoms = atomic_measure(dual[t], ranktol)
if atoms === nothing
return nothing
else
Expand Down
2 changes: 1 addition & 1 deletion src/sosseq.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function best_dynamic(s::AbstractSwitchedSystem, d, μs, p::GramMatrix, l, curst
soslf = SetProg.apply_transformation(p, transformation)
ν = measurefor(μs, dyn)
# return dot(μ, soslf)
return dot(getmat(ν), getmat(soslf))
return dot(value_matrix(ν), value_matrix(soslf))
end
best_dyn = nothing
best = -Inf
Expand Down
5 changes: 3 additions & 2 deletions src/veronese.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ function veroneselift_explicit(A::AbstractMatrix, d::Integer)

# Computing permutations is the most expensive part so we precompute it
perms = collect(permutations(1:d))
for (i,α) in enumerate(with_replacement_combinations(1:n, d))
for (j,β) in enumerate(with_replacement_combinations(1:n, d))
combi = reverse(collect(with_replacement_combinations(1:n, d)))
for (i,α) in enumerate(combi)
for (j,β) in enumerate(combi)
Ad[i, j] = permanent(A[α, β], perms) / sqrt(μ(α) * μ(β))
end
end
Expand Down
15 changes: 15 additions & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[deps]
CSDP = "0a46da34-8e4b-519e-b418-48813639ff34"
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
ECOS = "e2685f51-7e38-5353-a97d-a921fd2c8199"
GLPK = "60bf3e95-4087-53dc-ae20-288a0d20c6a6"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
HybridSystems = "2207ec0c-686c-5054-b4d2-543502888820"
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
MultivariatePolynomials = "102ac46a-7ee4-5c85-9060-abc95bfdeaa3"
Polyhedra = "67491407-f73d-577b-9b50-8179a7c68029"
SemialgebraicSets = "8e049039-38e8-557d-ae3a-bc521ccf6204"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
SwitchOnSafety = "ceb7f16a-07bf-5f4a-9354-b68f01b1610f"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2 changes: 1 addition & 1 deletion test/controlled.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function ci_square_test(
Δt = 0.5
control_system = ConstrainedLinearControlDiscreteSystem(reshape([1.0], 1, 1), reshape([Δt], 1, 1), interval, interval)
@testset "$(typeof(system))" for system in [
ConstrainedLinearAlgebraicDiscreteSystem([1.0 Δt], [1.0 0.0], □),
ConstrainedLinearDescriptorDiscreteSystem([1.0 Δt], [1.0 0.0], □),
ConstrainedLinearControlDiscreteSystem([1.0 Δt; 0.0 0.0], reshape([0.0 1.0], 2, 1), □, FullSpace()),
algebraiclift(control_system)
]
Expand Down
3 changes: 2 additions & 1 deletion test/veronese.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ using Combinatorics
@test_throws ArgumentError SwitchOnSafety.veroneselift_explicit([1 2; 3 4], 0)
@test_throws ArgumentError veroneselift([1 2; 3 4], 0)

@test [1.0 2 * 3 4 * 3 8.0] @inferred veroneselift([1 2], 3)
@test reverse([1.0 2 * 3 4 * 3 8.0]) @inferred veroneselift([1 2], 3)

s3 = sqrt(3)
expected = [11^3 s3*11^2*12 s3*11*12^2 12^3;
s3*11^2*21 11*(11*22+2*21*12) 12*(2*11*22+21*12) s3*12^2*22;
s3*11*21^2 21*(2*11*22+21*12) 22*(11*22+2*21*12) sqrt(3)*12*22^2;
21^3 s3*21^2*22 s3*21*22^2 22^3]
expected = expected[end:-1:1, end:-1:1]
@test expected @inferred veroneselift([11 12; 21 22], 3)
@test expected @inferred SwitchOnSafety.veroneselift_explicit([11 12; 21 22], 3)
end

2 comments on commit d035ed2

@blegat
Copy link
Owner Author

@blegat blegat commented on d035ed2 Aug 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/113075

Tip: Release Notes

Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.

@JuliaRegistrator register

Release notes:

## Breaking changes

- blah

To add them here just re-invoke and the PR will be updated.

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.3.0 -m "<description of version>" d035ed2ddd229805e618784ca888aa7308ed2857
git push origin v0.3.0

Please sign in to comment.