Skip to content

Commit

Permalink
#1911 - Type instability in genmat_fallback (#1981)
Browse files Browse the repository at this point in the history
* type stable genmat_fallback

* add generic and fast genmat_fallback versions
  • Loading branch information
schillic authored Feb 26, 2020
1 parent 83a553f commit 7faf8cb
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 6 deletions.
3 changes: 2 additions & 1 deletion src/Interfaces/AbstractHyperrectangle.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ Return the generator matrix of a hyperrectangular set.
A matrix where each column represents one generator of `H`.
"""
function genmat(H::AbstractHyperrectangle)
return genmat_fallback(H)
gens = generators(H)
return genmat_fallback(H, gens=gens, ngens=length(gens))
end

# iterator that wraps the generator matrix
Expand Down
41 changes: 37 additions & 4 deletions src/Interfaces/AbstractZonotope.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,51 @@ Fallback definition of `genmat` for zonotopic sets.
### Input
- `Z` -- zonotopic set
- `Z` -- zonotopic set
- `gens` -- (optional; default: `generators(Z)`) iterator over generators
- `ngens` -- (optional; default: `nothing`) number of generators or `nothing` if
unknown
### Output
A matrix where each column represents one generator of `Z`.
### Notes
Passing the number of generators is much more efficient as otherwise the
generators have to be obtained from the iterator (`gens`) and stored in an
intermediate vector until the final result matrix can be allocated.
"""
function genmat_fallback(Z::AbstractZonotope{N}) where {N<:Real}
gens = generators(Z)
function genmat_fallback(Z::AbstractZonotope{N};
gens=generators(Z),
ngens=nothing) where {N<:Real}
if isempty(gens)
return Matrix{N}(undef, dim(Z), 0)
elseif ngens == nothing
return _genmat_fallback_generic(Z, gens)
else
return _genmat_fallback_ngens(Z, gens, ngens)
end
end

function _genmat_fallback_generic(Z::AbstractZonotope{N}, gens) where {N<:Real}
Gv = Vector{Vector{N}}()
@inbounds for (i, g) in enumerate(gens)
push!(Gv, g)
end
G = Matrix{N}(undef, dim(Z), length(Gv))
@inbounds for (i, g) in enumerate(Gv)
G[:, i] = g
end
return G
end

function _genmat_fallback_ngens(Z::AbstractZonotope{N}, gens, ngens) where {N<:Real}
G = Matrix{N}(undef, dim(Z), ngens)
@inbounds for (i, g) in enumerate(gens)
G[:, i] = g
end
return hcat(gens...)
return G
end

# iterator that wraps the generator matrix
Expand Down
3 changes: 2 additions & 1 deletion src/Sets/LineSegment.jl
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,8 @@ Return the generator matrix of a line segment.
A matrix with a single column representing the generator of `L`.
"""
function genmat(L::LineSegment)
return genmat_fallback(L)
ngens = L.p == L.q ? 0 : 1
return genmat_fallback(L, ngens=ngens)
end

"""
Expand Down

0 comments on commit 7faf8cb

Please sign in to comment.