Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#1051 - Add more list of constraints methods #1053

Merged
merged 24 commits into from
Jan 24, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 69 additions & 7 deletions src/HPolyhedron.jl
Original file line number Diff line number Diff line change
Expand Up @@ -383,17 +383,37 @@ The tuple `(A, b)` where `A` is the matrix of normal directions and `b` are the
offsets.
"""
function tosimplehrep(P::HPoly{N}) where {N<:Real}
n = length(constraints_list(P))
return tosimplehrep(P.constraints)
mforets marked this conversation as resolved.
Show resolved Hide resolved
end

"""
tosimplehrep(constraints::AbstractVector{LinearConstraint{N}}) where {N<:Real}

Return the simple H-representation ``Ax ≤ b`` of a list of constraints.

### Input

- `constraints` -- a list of constraints

### Output

The tuple `(A, b)` where `A` is the matrix of normal directions and `b` are the
offsets.
"""
function tosimplehrep(constraints::AbstractVector{LinearConstraint{N}}) where {N<:Real}
n = length(constraints)
if n == 0
A = Matrix{N}(undef, 0, 0)
b = Vector{N}(undef, 0)
return (A, b)
end
A = zeros(N, n, dim(P))
A = zeros(N, n, dim(first(constraints)))
b = zeros(N, n)
for (i, Pi) in enumerate(constraints_list(P))
A[i, :] = Pi.a
b[i] = Pi.b
@inbounds begin
for (i, Pi) in enumerate(constraints)
A[i, :] = Pi.a
b[i] = Pi.b
end
end
return (A, b)
end
Expand Down Expand Up @@ -476,8 +496,40 @@ FAQ](https://www.cs.mcgill.ca/~fukuda/soft/polyfaq/node24.html).
"""
function remove_redundant_constraints!(P::PT;
backend=GLPKSolverLP())::Bool where {N, PT<:HPoly{N}}
remove_redundant_constraints!(P.constraints, backend=backend)
schillic marked this conversation as resolved.
Show resolved Hide resolved
end

A, b = tosimplehrep(P)
"""
remove_redundant_constraints!(constraints::Vector{LinearConstraint{N}};
backend=GLPKSolverLP())::Bool where {N}

Remove the redundant constraints of a given list of linear constraints; the list
is updated in-place.

### Input

- `constraints` -- list of constraints
- `backend` -- (optional, default: `GLPKSolverLP`) the numeric LP solver backend

### Output

`true` if the method was successful and the list of constraints `constraints` is
modified by removing the redundant constraints, and `false` if the constraints
are infeasible.

### Algorithm

If there are `m` constraints in `n` dimensions, this function checks one by one
if each of the `m` constraints is implied by the remaining ones.
To check if the `k`-th constraint is redundant, an LP is formulated.

For details, see [Fukuda's Polyhedra
FAQ](https://www.cs.mcgill.ca/~fukuda/soft/polyfaq/node24.html).
"""
function remove_redundant_constraints!(constraints::AbstractVector{LinearConstraint{N}};
backend=GLPKSolverLP())::Bool where {N}

A, b = tosimplehrep(constraints)
m, n = size(A)
non_redundant_indices = 1:m

Expand Down Expand Up @@ -506,10 +558,20 @@ function remove_redundant_constraints!(P::PT;
end
end

deleteat!(P.constraints, setdiff(1:m, non_redundant_indices))
deleteat!(constraints, setdiff(1:m, non_redundant_indices))
return true
end

function remove_redundant_constraints(constraints::AbstractVector{LinearConstraint{N}};
backend=GLPKSolverLP())::Bool where {N}
constraints_copy = copy(constraints)
if remove_redundant_constraints!(constraints_copy, backend=backend)
return constraints_copy
else # the constraints are infeasible
return N[]
schillic marked this conversation as resolved.
Show resolved Hide resolved
end
end

"""
linear_map(M::AbstractMatrix{N}, P::PT; [cond_tol=DEFAULT_COND_TOL]::Number)
where {N<:Real, PT<:HPoly{N}}
Expand Down
8 changes: 7 additions & 1 deletion src/Intersection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ export Intersection,
swap,
use_precise_ρ,
IntersectionArray,
array
array,
constraints_list

"""
IntersectionCache
Expand Down Expand Up @@ -510,6 +511,11 @@ function ∈(x::AbstractVector{N}, cap::Intersection{N})::Bool where {N<:Real}
return (x ∈ cap.X) && (x ∈ cap.Y)
end

function constraints_list(cap::Intersection{N, S1, S2}) where {N<:Real,
S1<:AbstractPolytope{N}, S2<:AbstractPolytope{N}}
constraints = [constraints_list(cap.X); constraints_list(cap.Y)]
return remove_redundant_constraints!(constraints)
end

# --- Intersection functions ---

Expand Down