Skip to content

Commit

Permalink
Merge pull request #3025 from JuliaReach/lf-spz-exact-sum
Browse files Browse the repository at this point in the history
added exact sum for sparse polynomial zonotopes
  • Loading branch information
schillic authored Aug 7, 2022
2 parents bb368ba + d4b1d49 commit ae10d7e
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 4 deletions.
1 change: 1 addition & 0 deletions docs/src/lib/sets/SparsePolynomialZonotope.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ nindependentgens(::SparsePolynomialZonotope)
nparams(::SparsePolynomialZonotope)
order(::SparsePolynomialZonotope)
linear_map(::AbstractMatrix, ::SparsePolynomialZonotope)
exact_sum(::SparsePolynomialZonotope, ::SparsePolynomialZonotope)
```
33 changes: 32 additions & 1 deletion src/Sets/SparsePolynomialZonotope.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export SparsePolynomialZonotope, expmat, nparams, ndependentgens, nindependentgens,
dependent_genmat, independent_genmat, indexvector,
dependent_genmat, independent_genmat, indexvector, exact_sum, ,
linear_map, quadratic_map, remove_redundant_generators

"""
Expand Down Expand Up @@ -288,6 +288,37 @@ function rand(::Type{SparsePolynomialZonotope};
return SparsePolynomialZonotope(center(SSPZ), genmat(SSPZ), GI, expmat(SSPZ))
end


"""
exact_sum(P1::SparsePolynomialZonotope, P2::SparsePolynomialZonotope)
Compute the exact sum of sparse polyomial zonotopes ``P₁`` and ``P₂``.
### Input
- `P1` -- sparse polynomial zonotope
- `P2` -- sparse polynomial zonotope
### Output
exact sum ``P₁ ⊞ P₂``
"""
function exact_sum(P1::SparsePolynomialZonotope, P2::SparsePolynomialZonotope)

indexvector(P1) == indexvector(P2) || throw(ArgumentError("Exact sum currently only implemented for Sparse Polynomial Zonotopes with the same index vector"))

c = center(P1) + center(P2)
G = hcat(dependent_genmat(P1), dependent_genmat(P2))
GI = hcat(independent_genmat(P1), independent_genmat(P2))
E = hcat(expmat(P1), expmat(P2))
idx = indexvector(P1)

return SparsePolynomialZonotope(c, G, GI, E, idx)
end

const = exact_sum

# function quadratic_map(Q::Vector{MT}, S::SparsePolynomialZonotope) where {N, MT<:AbstractMatrix{N}}
# m = length(Q)
# c = center(S)
Expand Down
13 changes: 10 additions & 3 deletions test/Sets/SparsePolynomialZonotope.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,20 @@ for N in [Float64, Float32, Rational{Int}]
@test order(PZ) == 2//1

M = N[-0.5 0.2;-0.1 0.6]
PZ = SparsePolynomialZonotope(zeros(N, 2), N[2 0 1;1 2 1], zeros(N, 2, 0), [1 0 1;0 1 3])
LMPZ = linear_map(M, PZ)
@test center(PZ) == zeros(N, 2)
PZ2 = SparsePolynomialZonotope(zeros(N, 2), N[2 0 1;1 2 1], zeros(N, 2, 0), [1 0 1;0 1 3])
LMPZ = linear_map(M, PZ2)
@test center(LMPZ) == zeros(N, 2)
@test dependent_genmat(LMPZ) N[-0.8 0.4 -0.3;0.4 1.2 0.5] atol=1e-7
@test isempty(independent_genmat(LMPZ))
@test expmat(LMPZ) == [1 0 1;0 1 3]
@test indexvector(LMPZ) == indexvector(PZ)

ESPZ = PZ PZ2
@test center(ESPZ) == [4, 4]
@test dependent_genmat(ESPZ) == [2 1 2 2 0 1;0 2 2 1 2 1]
@test independent_genmat(ESPZ) == hcat([1, 0])
@test expmat(ESPZ) == [1 0 3 1 0 1;0 1 1 0 1 3]
@test indexvector(ESPZ) == indexvector(PZ)
end

SSPZ = SimpleSparsePolynomialZonotope([0.2, -0.6], [1 0;0 0.4], [1 0;0 1])
Expand Down

0 comments on commit ae10d7e

Please sign in to comment.