Skip to content

Commit

Permalink
adding portsoort()
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Doolittle committed May 27, 2020
1 parent 0a0a9fe commit 1ea64e4
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 14 deletions.
1 change: 1 addition & 0 deletions docs/src/exports.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ IEQ

```@docs
traf
portsort
posie
fctp
```
18 changes: 11 additions & 7 deletions src/XPORTA.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ historical names from the PORTA software.
# Exports
- [`POI`](@ref) - *Type*, The vertex representation of a polyhedra.
- [`IEQ`](@ref) - *Type*, The intersecting halfspace representation of a polyhedra.
- [`traf`](@ref) - *Method*, Converts a `POI` -> `IEQ` or `IEQ` -> `POI`.
- [`posie`](@ref) - *Method*, Enumerates the points and rays of a `POI` which satisfy the linear system of an `IEQ`.
- [`fctp`](@ref) - *Method*, Given a set of inequalities and a `POI`, determines which
inequalities tightly bound the `POI` and which inequalities exclude elements of the `POI`.
*Types*
- [`POI`](@ref) - The vertex representation of a polyhedra.
- [`IEQ`](@ref) - The intersecting halfspace representation of a polyhedra.
*Methods*
- [`traf`](@ref) - Converts a `POI` -> `IEQ` or `IEQ` -> `POI`.
- [`portsort`](@ref) - Sorts the elements of `POI` and `IEQ` structs.
- [`posie`](@ref) - Enumerates the points and rays of a `POI` which satisfy the linear system of an `IEQ`.
- [`fctp`](@ref) - Given inequalities and a `POI`, determines which inequalities
tightly bound the `POI` and which inequalities exclude elements of the `POI`.
In each case, the satisfying/violating elements are returned in a `POI`.
The compiled PORTA binaries are accessed through [PORTA_jll.jl](https://github.com/JuliaBinaryWrappers/PORTA_jll.jl)
Expand All @@ -35,7 +39,7 @@ using PORTA_jll
using Suppressor

export POI, IEQ # types
export traf # xporta methods
export traf, portsort # xporta methods
export fctp, posie # valid methods

# including local files
Expand Down
86 changes: 79 additions & 7 deletions src/xporta_subroutines.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ end
"""
The `traf` method computes an `IEQ` struct given a `POI` struct,
traf( poi::POI; kwargs... ) :: IEQ
traf( poi::POI; kwargs... ) :: IEQ{Rational{Int}}
or computes the `POI` struct from the `IEQ` struct.
traf(ieq::IEQ; kwargs... ) :: POI
traf(ieq::IEQ; kwargs... ) :: POI{Rational{Int}}
When converting an `IEQ` -> `POI` the `valid` field of the `IEQ` must be populated
if the origin is not a feasible point of the linear system.
Expand Down Expand Up @@ -75,7 +75,7 @@ The following excerpt from the PORTA documentation lists valid optional flags an
are written in hexadecimal format (hex). Such hexadecimal format
can not be reread as input.
For more details regarding `traf` please refer to the [PORTA traf documentation](https://github.com/bdoolittle/julia-porta/blob/master/README.md#traf).
For more details regarding `traf` please refer to the [PORTA traf documentation](https://github.com/bdoolittle/julia-porta#traf).
"""
function traf(poi::POI;
dir::String="./",
Expand All @@ -87,7 +87,7 @@ function traf(poi::POI;
xporta_args = Array{String,1}(undef,0)
if opt_flag != ""
if !occursin(r"^-[poscvl]{1,6}$", opt_flag) || (length(opt_flag) != length(unique(opt_flag)))
throw(DomainError(opt_flags, "invalid opt_flags argument. Valid options any ordering of '-poscvl' and substrings."))
throw(DomainError(opt_flags, "invalid `opt_flag` argument. Valid options any ordering of '-poscvl' and substrings."))
end
push!(xporta_args, opt_flag)
end
Expand All @@ -108,11 +108,17 @@ function traf(poi::POI;
return ieq
end

function traf(ieq::IEQ; dir::String="./", filename::String="traf_tmp", opt_flag::String="", cleanup::Bool=true, verbose::Bool=false) :: POI
function traf(ieq::IEQ;
dir::String="./",
filename::String="traf_tmp",
opt_flag::String="",
cleanup::Bool=true,
verbose::Bool=false
) :: POI{Rational{Int}}
xporta_args = Array{String,1}(undef,0)
if opt_flag != ""
if !occursin(r"^-[poscvl]{1,6}$", opt_flag) || (length(opt_flag) != length(unique(opt_flag)))
throw(DomainError(opt_flags, "invalid opt_flags argument. Valid options any ordering of '-poscvl' and permuted substrings."))
throw(DomainError(opt_flags, "invalid `opt_flag` argument. Valid options any ordering of '-poscvl' and permuted substrings."))
end
end

Expand All @@ -125,7 +131,73 @@ function traf(ieq::IEQ; dir::String="./", filename::String="traf_tmp", opt_flag:

poi = read_poi(file_path * ".poi")

if (cleanup)
if cleanup
rm_porta_tmp(dir)
end

return poi
end

"""
portsort( ieq::IEQ; kwargs... ) :: IEQ{Rational{Int}}
Sorts the inequalities and equalities of the provided `IEQ`.
portsort( poi::POI; kwargs... ) :: POI{Rational{Int}}
Sorts the vertices and rays of the provided `POI`.
Sorting is performed in the following hierarchy:
1. Right-hand-side of in/equalities from high to low.
2. Scale factors from low to high.
3. Lexicographical order.
`kwargs` is shorthand for the keyword arguments:
* `dir::String = "./"` - The directory in which to write files.
* `filename::String = "traf_tmp"`- The name of produced files.
* `cleanup::Bool = true` - If `true`, created files are removed after computation.
* `verbose::Bool = false`- If `true`, PORTA will print progress to `STDOUT`.
For more details regarding `portsort` please refer to the [PORTA portsort documentation](https://github.com/bdoolittle/julia-porta#portsort).
"""
function portsort(ieq::IEQ;
dir::String="./",
filename::String="portsort_tmp",
cleanup::Bool=true,
verbose::Bool=false
) :: IEQ{Rational{Int}}

workdir = cleanup ? make_porta_tmp(dir) : dir

ieq_filepath = write_ieq(filename, ieq, dir=workdir)

run_xporta("-S", [ieq_filepath], verbose=verbose)

ieq = read_ieq(ieq_filepath * ".ieq")

if cleanup
rm_porta_tmp(dir)
end

return ieq
end

function portsort(poi::POI;
dir::String="./",
filename::String="portsort_tmp",
cleanup::Bool=true,
verbose::Bool=false
) :: POI{Rational{Int}}

workdir = cleanup ? make_porta_tmp(dir) : dir

poi_filepath = write_poi(filename, poi, dir=workdir)

run_xporta("-S", [poi_filepath], verbose=verbose)

poi = read_poi(poi_filepath * ".poi")

if cleanup
rm_porta_tmp(dir)
end

Expand Down
60 changes: 60 additions & 0 deletions test/integration/xporta_subroutines.jl
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,64 @@ end
end
end

@testset "portsort()" begin
@testset "ieq inputs" begin
@testset "sorts inequalities by scale factor (high to low)" begin
sort_ieq = portsort(IEQ(inequalities=[-1 0 0 0;-2 0 0 0;1 0 0 0], equalities=[1 0 -1 0;2 0 -1 0]), dir=dir)
@test sort_ieq.inequalities == [1 0 0 0;-1 0 0 0;-2 0 0 0]
@test sort_ieq.equalities == [2 0 -1 0;1 0 -1 0]

sort_ieq = portsort(IEQ(inequalities=[3 0 0 0;0 2 0 0;0 0 1 0]), dir=dir)
@test sort_ieq.inequalities == [3 0 0 0;0 2 0 0;0 0 1 0]
end

@testset "sorts inequalities by lexicographical order" begin
sort_ieq = portsort(IEQ(inequalities=[0 -1 0 0;-1 0 0 0;0 0 -1 0], equalities = [2 0 -1 0;2 -1 0 0]), dir=dir)
@test sort_ieq.inequalities == [-1 0 0 0;0 -1 0 0;0 0 -1 0]
@test sort_ieq.equalities == [2 -1 0 0;2 0 -1 0]
end

@testset "sorts inequalites by rhs bound (low to high)" begin
sort_ieq = portsort(IEQ(inequalities=[-1 0 0 3;-1 0 0 2;-1 0 0 1], equalities = [1 1 1 1;1 1 1 -1]), dir=dir)
@test sort_ieq.inequalities == [-1 0 0 1;-1 0 0 2;-1 0 0 3]
@test sort_ieq.equalities == [1 1 1 -1;1 1 1 1]
end

@testset "sorts inequalities by scale factor over lexicographical order" begin
sort_ieq = portsort(IEQ(inequalities=[-3 0 0 0;0 -2 0 0;0 0 -1 0]), dir=dir)
@test sort_ieq.inequalities == [0 0 -1 0;0 -2 0 0;-3 0 0 0]
end

@testset "sorts inequalities by rhs bound, scale factor, then lexicographical order" begin
sort_ieq = portsort(IEQ(inequalities=[0 -3 0 0;0 -1 0 2;0 -1 0 1;-2 0 0 2]), dir=dir)
@test sort_ieq.inequalities == [0 -3 0 0;0 -1 0 1;0 -1 0 2;-2 0 0 2]
end
end

@testset "poi inputs" begin
@testset "sorts points by scale factor (high to low)" begin
sort_poi = portsort(POI(vertices=[-1 0 0 0;-2 0 0 0;1 0 0 0], rays=[0 1 0 0;0 2 0 0;0 3 0 0]), dir=dir)
@test sort_poi.conv_section == [1 0 0 0;-1 0 0 0;-2 0 0 0]
@test sort_poi.cone_section == [0 3 0 0;0 2 0 0;0 1 0 0]

sort_poi = portsort(POI(vertices=[3 0 0 0;0 2 0 0;0 0 1 0]), dir=dir)
@test sort_poi.conv_section == [3 0 0 0;0 2 0 0;0 0 1 0]
end

@testset "sorts points by lexicographical order" begin
sort_poi = portsort(POI(vertices=[0 -1 0 0;-1 0 0 0;0 0 -1 0]), dir=dir)
@test sort_poi.conv_section == [-1 0 0 0;0 -1 0 0;0 0 -1 0]
end

@testset "sorts points by scale factor over lexicographical order" begin
sort_poi = portsort(POI(vertices=[-3 0 0 0;0 -2 0 0;0 0 -1 0], rays=[0 0 0 3;1 0 0 0;0 -1 0 0]), dir=dir)
@test sort_poi.conv_section == [0 0 -1 0;0 -2 0 0;-3 0 0 0]
@test sort_poi.cone_section == [0 0 0 3;1 0 0 0;0 -1 0 0]

sort_poi = portsort(POI(vertices=[0 -3 0 0;0 -1 0 2;0 -1 0 1;-2 0 0 2]), dir=dir)
@test sort_poi.conv_section == [0 -1 0 2;0 -1 0 1;-2 0 0 2;0 -3 0 0]
end
end
end

end

0 comments on commit 1ea64e4

Please sign in to comment.