Skip to content

Commit

Permalink
Use concrete type for matrix of MatRep
Browse files Browse the repository at this point in the history
  • Loading branch information
blegat committed Apr 24, 2018
1 parent 2cda7e2 commit 4951806
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 43 deletions.
14 changes: 7 additions & 7 deletions perf/runbenchmarks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ using StaticArrays
# evals/sample: 1
# MixedMatHRep
# BenchmarkTools.Trial:
# memory estimate: 152.77 KiB
# allocs estimate: 2893
# memory estimate: 148.64 KiB
# allocs estimate: 2775
# --------------
# minimum time: 541.129 μs (0.00% GC)
# median time: 550.350 μs (0.00% GC)
# mean time: 586.288 μs (4.79% GC)
# maximum time: 5.012 ms (84.70% GC)
# minimum time: 479.105 μs (0.00% GC)
# median time: 486.236 μs (0.00% GC)
# mean time: 508.813 μs (3.73% GC)
# maximum time: 3.555 ms (83.56% GC)
# --------------
# samples: 8505
# samples: 9809
# evals/sample: 1

let
Expand Down
5 changes: 5 additions & 0 deletions src/Polyhedra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ end
similar_type(::Type{<:Point}, ::FullDim{N}, ::Type{T}) where {N, T} = Point{N,T}
similar_type(::Type{<:Vec}, ::FullDim{N}, ::Type{T}) where {N, T} = Vec{N,T}

similar_type(::Type{<:Matrix}, ::Type{T}) where T = Matrix{T}
similar_type(::Type{SparseMatrixCSC{S, I}}, ::Type{T}) where {S, I, T} = SparseMatrixCSC{T, I}
arraytype(::Type{<:AbstractSparseArray{T}}) where T = SparseVector{T, Int}
arraytype(::Type{<:AbstractMatrix{T}}) where T = Vector{T}

# Interface/Definitions
include("elements.jl")
include("comp.jl")
Expand Down
4 changes: 1 addition & 3 deletions src/lphrep.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ function LPHRepresentation(A::AbstractMatrix, l::AbstractVector, u::AbstractVect
LPHRepresentation{size(A,2), T, typeof(AT)}(AT, AbstractVector{T}(l), AbstractVector{T}(u), AbstractVector{T}(lb), AbstractVector{T}(ub))
end

similar_type(::Type{<:Matrix}, ::Type{T}) where T = Matrix{T}
similar_type(::Type{SparseMatrixCSC{S, I}}, ::Type{T}) where {S, I, T} = SparseMatrixCSC{T, I}
arraytype(::Union{LPHRepresentation{N, T, MT}, Type{LPHRepresentation{N, T, MT}}}) where {N, T, MT} = MT <: AbstractSparseArray ? SparseVector{T, Int} : Vector{T}
arraytype(::Union{LPHRepresentation{N, T, MT}, Type{LPHRepresentation{N, T, MT}}}) where {N, T, MT} = arraytype(MT)
similar_type(::Type{LPHRepresentation{M, S, MT}}, ::FullDim{N}, ::Type{T}) where {M, S, N, T, MT} = LPHRepresentation{N, T, similar_type(MT, T)}
fulltype(::Type{LPHRepresentation{N, T, MT}}) where {N, T, MT} = LPHRepresentation{N, T, MT}

Expand Down
65 changes: 36 additions & 29 deletions src/matrep.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ and ``\\langle A_i, x \\rangle \\le b_i`` otherwise where ``A_i`` is the ``i``th
hrep(A::AbstractMatrix, b::AbstractVector, linset::IntSet=IntSet()) = MixedMatHRep(A, b, linset)

# No copy since I do not modify anything and a copy is done when building a polyhedron
mutable struct MixedMatHRep{N, T} <: MixedHRep{N, T}
mutable struct MixedMatHRep{N, T, MT<:AbstractMatrix{T}} <: MixedHRep{N, T}
# Ax <= b
A::AbstractMatrix{T}
b::AbstractVector{T}
A::MT
b::Vector{T}
linset::IntSet

function MixedMatHRep{N, T}(A::AbstractMatrix, b::AbstractVector, linset::IntSet) where {N, T}
function MixedMatHRep{N, T, MT}(A::MT, b::AbstractVector, linset::IntSet) where {N, T, MT}
if size(A, 1) != length(b)
error("The length of b must be equal to the number of rows of A")
end
Expand All @@ -26,26 +26,29 @@ mutable struct MixedMatHRep{N, T} <: MixedHRep{N, T}
if size(A, 2) != N
error("dimension does not match")
end
new{N, T}(A, b, linset)
new{N, T, typeof(A)}(A, b, linset)
end
end

similar_type{N,T}(::Type{<:MixedMatHRep}, ::FullDim{N}, ::Type{T}) = MixedMatHRep{N,T}
arraytype(p::Union{MixedMatHRep{N, T}, Type{MixedMatHRep{N, T}}}) where {N, T} = Vector{T}
fulltype(::Type{MixedMatHRep{N, T}}) where {N, T} = MixedMatHRep{N, T}
similar_type(::Type{<:MixedMatHRep{M, S, MT}}, ::FullDim{N}, ::Type{T}) where {M, S, N, T, MT} = MixedMatHRep{N, T, similar_type(MT, T)}
arraytype(p::Union{MixedMatHRep{N, T, MT}, Type{MixedMatHRep{N, T, MT}}}) where {N, T, MT} = arraytype(MT)
fulltype(::Type{MixedMatHRep{N, T, MT}}) where {N, T, MT} = MixedMatHRep{N, T, MT}

function MixedMatHRep(A::AbstractMatrix{S}, b::AbstractVector{T}, linset::IntSet) where {S <: Real, T <: Real}
MixedMatHRep{N, T}(A::AbstractMatrix{T}, b::AbstractVector{T}, linset::IntSet) where {N, T} = MixedMatHRep{N, T, typeof(A)}(A, b, linset)
MixedMatHRep(A::AbstractMatrix{T}, b::AbstractVector{T}, linset::IntSet) where T = MixedMatHRep{size(A, 2), T, typeof(A)}(A, b, linset)
MixedMatHRep{N, U}(A::AbstractMatrix{S}, b::AbstractVector{T}, linset::IntSet) where {N, S, T, U} = MixedMatHRep{N, U}(AbstractMatrix{U}(A), AbstractVector{U}(b), linset)
function MixedMatHRep(A::AbstractMatrix{S}, b::AbstractVector{T}, linset::IntSet) where {S, T}
U = promote_type(S, T)
MixedMatHRep{size(A,2),U}(AbstractMatrix{U}(A), AbstractVector{U}(b), linset)
MixedMatHRep(AbstractMatrix{U}(A), AbstractVector{U}(b), linset)
end
MixedMatHRep(A::AbstractMatrix{T}, b::AbstractVector{T}, linset::IntSet) where T <: Real = MixedMatHRep{size(A,2),T}(A, b, linset)

MixedMatHRep(h::HRep{N,T}) where {N,T} = MixedMatHRep{N,T}(h)

function MixedMatHRep{N, T}(hyperplanes::HyperPlaneIt{N, T}, halfspaces::HalfSpaceIt{N, T}) where {N, T}
function MixedMatHRep{N, T, MT}(hyperplanes::HyperPlaneIt{N, T}, halfspaces::HalfSpaceIt{N, T}) where {N, T, MT}
nhyperplane = length(hyperplanes)
nhrep = nhyperplane + length(halfspaces)
A = Matrix{T}(nhrep, N)
A = MT <: AbstractSparseArray ? spzeros(eltype(MT), nhrep, N) : MT(nhrep, N)
b = Vector{T}(nhrep)
linset = IntSet(1:nhyperplane)
for (i, h) in enumerate(hyperplanes)
Expand All @@ -56,10 +59,10 @@ function MixedMatHRep{N, T}(hyperplanes::HyperPlaneIt{N, T}, halfspaces::HalfSpa
A[nhyperplane+i,:] = h.a
b[nhyperplane+i] = h.β
end
MixedMatHRep{N, T}(A, b, linset)
MixedMatHRep{N, T, MT}(A, b, linset)
end

Base.copy(ine::MixedMatHRep{N,T}) where {N,T} = MixedMatHRep{N,T}(copy(ine.A), copy(ine.b), copy(ine.linset))
Base.copy(ine::MixedMatHRep{N, T, MT}) where {N, T, MT} = MixedMatHRep{N, T, MT}(copy(ine.A), copy(ine.b), copy(ine.linset))

Base.isvalid(hrep::MixedMatHRep{N, T}, idx::HIndex{N, T}) where {N, T} = 0 < idx.value <= size(hrep.A, 1) && (idx.value in hrep.linset) == islin(idx)
Base.done(idxs::HIndices{N, T, <:MixedMatHRep{N, T}}, idx::HIndex{N, T}) where {N, T} = idx.value > size(idxs.rep.A, 1)
Expand All @@ -76,12 +79,12 @@ where ``V_i`` (resp. ``R_i``) is the ``i``th row of `V` (resp. `R`), i.e. `V[i,:
vrep(V::AbstractMatrix, R::AbstractMatrix, Rlinset::IntSet=IntSet()) = MixedMatVRep(V, R, Rlinset)
vrep(V::AbstractMatrix) = vrep(V, similar(V, 0, size(V, 2)))

mutable struct MixedMatVRep{N,T} <: MixedVRep{N,T}
V::AbstractMatrix{T} # each row is a vertex
R::AbstractMatrix{T} # each row is a ray
mutable struct MixedMatVRep{N, T, MT<:AbstractMatrix{T}} <: MixedVRep{N, T}
V::MT # each row is a vertex
R::MT # each row is a ray
Rlinset::IntSet

function MixedMatVRep{N, T}(V::AbstractMatrix, R::AbstractMatrix, Rlinset::IntSet) where {N, T}
function MixedMatVRep{N, T, MT}(V::MT, R::MT, Rlinset::IntSet) where {N, T, MT}
if iszero(size(V, 1)) && !iszero(size(R, 1))
vconsistencyerror()
end
Expand All @@ -91,22 +94,25 @@ mutable struct MixedMatVRep{N,T} <: MixedVRep{N,T}
if !isempty(Rlinset) && last(Rlinset) > size(R, 1)
error("The elements of Rlinset should be between 1 and the number of rows of R")
end
new{N, T}(V, R, Rlinset)
new{N, T, MT}(V, R, Rlinset)
end
end

similar_type{N,T}(::Type{<:MixedMatVRep}, ::FullDim{N}, ::Type{T}) = MixedMatVRep{N,T}
arraytype(p::Union{MixedMatVRep{N, T}, Type{MixedMatVRep{N, T}}}) where {N, T} = Vector{T}
fulltype(::Type{MixedMatVRep{N, T}}) where {N, T} = MixedMatVRep{N, T}
similar_type(::Type{<:MixedMatVRep{M, S, MT}}, ::FullDim{N}, ::Type{T}) where {M, S, N, T, MT} = MixedMatVRep{N, T, similar_type(MT, T)}
arraytype(p::Union{MixedMatVRep{N, T, MT}, Type{MixedMatVRep{N, T, MT}}}) where {N, T, MT} = arraytype(MT)
fulltype(::Type{MixedMatVRep{N, T, MT}}) where {N, T, MT} = MixedMatVRep{N, T, MT}

function MixedMatVRep(V::AbstractMatrix{S}, R::AbstractMatrix{T}, Rlinset::IntSet) where {S <: Real, T <: Real}
MixedMatVRep{N, T}(V::MT, R::MT, Rlinset::IntSet) where {N, T, MT<:AbstractMatrix{T}} = MixedMatVRep{N, T, MT}(V, R, Rlinset)
MixedMatVRep(V::MT, R::MT, Rlinset::IntSet) where {T, MT<:AbstractMatrix{T}} = MixedMatVRep{size(V, 2), T, MT}(V, R, Rlinset)
MixedMatVRep{N, U}(V::AbstractMatrix{S}, R::AbstractMatrix{T}, Rlinset::IntSet) where {N, S, T, U} = MixedMatVRep{N, U}(AbstractMatrix{U}(V), AbstractMatrix{U}(R), Rlinset)
function MixedMatVRep(V::AbstractMatrix{S}, R::AbstractMatrix{T}, Rlinset::IntSet) where {S, T}
U = promote_type(S, T)
MixedMatVRep{size(V,2),U}(AbstractMatrix{U}(V), AbstractMatrix{U}(R), Rlinset)
MixedMatVRep(AbstractMatrix{U}(V), AbstractMatrix{U}(R), Rlinset)
end

MixedMatVRep(v::VRep{N,T}) where {N,T} = MixedMatVRep{N,T}(v)

function MixedMatVRep{N, T}(vits::VIt{N, T}...) where {N, T}
function MixedMatVRep{N, T, MT}(vits::VIt{N, T}...) where {N, T, MT}
points, lines, rays = fillvits(FullDim{N}(), vits...)
npoint = length(points)
nline = length(lines)
Expand All @@ -125,10 +131,10 @@ function MixedMatVRep{N, T}(vits::VIt{N, T}...) where {N, T}
_fill!(V, nothing, 0, points)
_fill!(R, Rlinset, 0, lines)
_fill!(R, Rlinset, nline, rays)
MixedMatVRep{N, T}(V, R, Rlinset)
MixedMatVRep{N, T, MT}(V, R, Rlinset)
end

Base.copy(ext::MixedMatVRep{N,T}) where {N,T} = MixedMatVRep{N,T}(copy(ext.V), copy(ext.R), copy(ext.Rlinset))
Base.copy(ext::MixedMatVRep{N, T, MT}) where {N, T, MT} = MixedMatVRep{N, T, MT}(copy(ext.V), copy(ext.R), copy(ext.Rlinset))

_mat(hrep::MixedMatVRep, ::PIndex) = hrep.V
_mat(hrep::MixedMatVRep, ::RIndex) = hrep.R
Expand All @@ -139,8 +145,9 @@ Base.isvalid(vrep::MixedMatVRep{N, T}, idx::VIndex{N, T}) where {N, T} = 0 < idx
Base.done(idxs::VIndices{N, T, <:MixedMatVRep{N, T}}, idx::VIndex{N, T}) where {N, T} = idx.value > size(_mat(idxs.rep, idx), 1)
Base.get(vrep::MixedMatVRep{N, T}, idx::VIndex{N, T}) where {N, T} = valuetype(idx)(_mat(vrep, idx)[idx.value, :])

dualtype(::Type{MixedMatHRep{N, T}}) where {N, T} = MixedMatVRep{N, T}
dualtype(::Type{MixedMatVRep{N, T}}) where {N, T} = MixedMatHRep{N, T}
# sparse halfspaces does not mean sparse points
dualtype(::Type{MixedMatHRep{N, T, MT}}) where {N, T, MT} = MixedMatVRep{N, T, Matrix{T}}
dualtype(::Type{MixedMatVRep{N, T, MT}}) where {N, T, MT} = MixedMatHRep{N, T, Matrix{T}}
function dualfullspace(h::MixedMatHRep, ::FullDim{N}, ::Type{T}) where {N, T}
MixedMatVRep{N, T}(zeros(T, 1, N), eye(T, N), IntSet(1:N))
end
Expand Down
10 changes: 8 additions & 2 deletions test/polyhedron.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@
@test p isa SimplePolyhedron{2, Rational{BigInt}, LPHRepresentation{2, Rational{BigInt}, SparseMatrixCSC{Rational{BigInt},Int}}, Polyhedra.Hull{2, Rational{BigInt}, Vector{Rational{BigInt}}}}
h = hrep(zeros(2, 2), zeros(2))
p = @inferred polyhedron(h)
@test p isa SimplePolyhedron{2, Float64, MixedMatHRep{2, Float64}, MixedMatVRep{2, Float64}}
@test p isa SimplePolyhedron{2, Float64, MixedMatHRep{2, Float64, Matrix{Float64}}, MixedMatVRep{2, Float64, Matrix{Float64}}}
h = hrep(spzeros(2, 2), zeros(2))
p = @inferred polyhedron(h)
@test p isa SimplePolyhedron{2, Float64, MixedMatHRep{2, Float64, SparseMatrixCSC{Float64, Int}}, MixedMatVRep{2, Float64, Matrix{Float64}}}
v = vrep(zeros(2, 3))
p = @inferred polyhedron(v)
@test p isa SimplePolyhedron{3, Float64, MixedMatHRep{3, Float64}, MixedMatVRep{3, Float64}}
@test p isa SimplePolyhedron{3, Float64, MixedMatHRep{3, Float64, Matrix{Float64}}, MixedMatVRep{3, Float64, Matrix{Float64}}}
v = vrep(spzeros(2, 3))
p = @inferred polyhedron(v)
@test p isa SimplePolyhedron{3, Float64, MixedMatHRep{3, Float64, Matrix{Float64}}, MixedMatVRep{3, Float64, SparseMatrixCSC{Float64, Int}}}
end

struct BadPoly{N, T} <: Polyhedra.Polyhedron{N, T}
Expand Down
6 changes: 4 additions & 2 deletions test/representation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ Polyhedra.@subrepelem InconsistentVRep Ray rays
((@inferred hrep(hps, hss)), Vector{Float64}),
((@inferred hrep(shps, shss)), SVector{3, Float64}),
(hrep([1 2 3; 4 5 6], [7., 8], IntSet([1])), Vector{Float64}),
(hrep(spzeros(2, 3), [7., 8], IntSet([1])), SparseVector{Float64, Int}),
(SimpleHRepresentation([1 2 3; 4 5 6], [7., 8], IntSet([1])), Vector{Float64}),
(SimpleHRepresentation([1 2 3; 4 5 6], [7., 8]), Vector{Float64}))
@test (@inferred coefficienttype(hr)) == Float64
Expand Down Expand Up @@ -146,6 +147,7 @@ Polyhedra.@subrepelem InconsistentVRep Ray rays
((@inferred vrep(ps, ls, rs)), Vector{Int}),
((@inferred vrep(sps, sls, srs)), SVector{2, Int}),
(vrep([1 2; 3 4]), Vector{Int}),
(vrep(spzeros(Int, 2, 2)), SparseVector{Int, Int}),
(SimpleVRepresentation([1 2; 3 4], zeros(Int, 0, 0), IntSet()), Vector{Int}),
(SimpleVRepresentation([1 2; 3 4], zeros(Int, 0, 0)), Vector{Int}),
(SimpleVRepresentation([1 2; 3 4]), Vector{Int}))
Expand Down Expand Up @@ -199,7 +201,7 @@ Polyhedra.@subrepelem InconsistentVRep Ray rays
N = 5
M = 10
T = Int64
reps = [MixedMatHRep{N, T}, MixedMatVRep{N, T}, LiftedHRepresentation{N, T}, LiftedVRepresentation{N, T}]
reps = [MixedMatHRep{N, T, Matrix{T}}, MixedMatVRep{N, T, Matrix{T}}, LiftedHRepresentation{N, T}, LiftedVRepresentation{N, T}]
for rep in reps
changedrep = Polyhedra.similar_type(rep, FullDim{M}())
@test fulldim(changedrep) == M
Expand Down Expand Up @@ -298,7 +300,7 @@ Polyhedra.@subrepelem InconsistentVRep Ray rays
T = Int
AT = Vector{Int}
for VRepType in (Polyhedra.LiftedVRepresentation{2, T},
Polyhedra.MixedMatVRep{2, T},
Polyhedra.MixedMatVRep{2, T, Matrix{T}},
Polyhedra.Hull{2, T, AT})
@test_throws ErrorException VRepType(AT[], [Line([1, 2])])
@test_throws ErrorException VRepType(AT[], Line{2, T, AT}[], [Ray([1, 2])])
Expand Down

0 comments on commit 4951806

Please sign in to comment.