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

#676 - Add _projection method for set - hyperplane lazy intersection #694

Merged
merged 8 commits into from
Oct 4, 2018
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
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
2 changes: 1 addition & 1 deletion docs/src/lib/operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ dim(::Intersection)
σ(::AbstractVector{Real}, ::Intersection{Real})
∈(::AbstractVector{Real}, ::Intersection{Real})
isempty(::Intersection)
ρ(::AbstractVector{N}, ::Intersection{N, <:LazySet, S}) where {N<:AbstractFloat, S<:Union{HalfSpace, Hyperplane}}
ρ(::AbstractVector{N}, ::Intersection{N, <:LazySet, S}) where {N<:AbstractFloat, S<:Union{HalfSpace, Hyperplane, Line}}
```

Inherited from [`LazySet`](@ref):
Expand Down
65 changes: 55 additions & 10 deletions src/Intersection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ end
cap::Intersection{N, <:LazySet, S};
algorithm::String="line_search",
check_intersection::Bool=true,
kwargs...) where {N<:AbstractFloat, S<:Union{HalfSpace, Hyperplane}}
kwargs...) where {N<:AbstractFloat, S<:Union{HalfSpace, Hyperplane, Line}}

Return the support function of the intersection of a compact set and a half-space
or a hyperplane in a given direction.
Expand All @@ -308,6 +308,11 @@ or a hyperplane in a given direction.
* `"line_search"` -- solve the associated univariate optimization problem
using a line search method (either Brent or the
Golden Section method)
* `"projection"` -- evaluate the support function by reducing the problem to
the 2D intersection of a rank 2 linear transformation of
the given compat set in the plane generated by the given
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compact

direction `d` and the hyperplane's normal vector `n`;
only valid for intersection with a hyperplane
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe move the last sentence to the top; otherwise the hyperplane in the text is confusing.


- `check_intersection` -- (optional, default: `true`) if `true`, check if the
intersection is empty before actually calculating the
Expand Down Expand Up @@ -350,7 +355,7 @@ function ρ(d::AbstractVector{N},
cap::Intersection{N, <:LazySet, S};
algorithm::String="line_search",
check_intersection::Bool=true,
kwargs...) where {N<:AbstractFloat, S<:Union{HalfSpace, Hyperplane}}
kwargs...) where {N<:AbstractFloat, S<:Union{HalfSpace, Hyperplane, Line}}

X = cap.X # compact set
H = cap.Y # halfspace or hyperplane
Expand All @@ -362,14 +367,24 @@ function ρ(d::AbstractVector{N},

if algorithm == "line_search"
@assert isdefined(Main, :Optim) "the algorithm $algorithm needs " *
"the package 'Optim' to be loaded"
"the package 'Optim' to be loaded"
(s, _) = _line_search(d, X, H; kwargs...)
elseif algorithm == "projection"
@assert H isa Hyperplane "the algorithm $algorithm cannot be used with a
$(typeof(H)); it only works with hyperplanes"
s = _projection(d, X, H; kwargs...)
else
error("algorithm $(algorithm) unknown")
end
return s
end

# Symmetric case
ρ(ℓ::AbstractVector{N}, cap::Intersection{N, S, <:LazySet};
algorithm::String="line_search", check_intersection::Bool=true,
kwargs...) where {N<:AbstractFloat, S<:Union{HalfSpace, Hyperplane, Line}} = ρ(ℓ, cap.Y ∩ cap.X;
algorithm=algorithm, check_intersection=check_intersection, kwargs...)

function load_optim_intersection()
return quote

Expand Down Expand Up @@ -436,7 +451,7 @@ julia> _line_search([1.0, 0.0], X, H, upper=1e3, method=GoldenSection())
(1.0, 381.9660112501051)
```
"""
function _line_search(ℓ, X, H::Union{HalfSpace, Hyperplane}; kwargs...)
function _line_search(ℓ, X, H::Union{HalfSpace, Hyperplane, Line}; kwargs...)
options = Dict(kwargs)

# Initialization
Expand All @@ -448,7 +463,7 @@ function _line_search(ℓ, X, H::Union{HalfSpace, Hyperplane}; kwargs...)
else
if H isa HalfSpace
lower = 0.0
elseif H isa Hyperplane
elseif (H isa Hyperplane) || (H isa Line)
lower = -1e6 # "big": TODO relate with f(λ)
end
end
Expand All @@ -475,8 +490,38 @@ end # _line_search
end # quote
end # load_optim

# Symmetric case
ρ(ℓ::AbstractVector{N}, cap::Intersection{N, S, <:LazySet};
algorithm::String="line_search", check_intersection::Bool=true,
kwargs...) where {N<:AbstractFloat, S<:Union{HalfSpace, Hyperplane}} = ρ(ℓ, cap.Y ∩ cap.X;
algorithm=algorithm, check_intersection=check_intersection, kwargs...)
"""
_projection(ℓ, X, H::Union{Hyperplane{N}, Line{N}}; kwargs...) where {N}

Given a compact and convex set ``X`` and a hyperplane ``H = \\{x: n ⋅ x = γ \\}``,
calculate ...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"...", now I am excited 😄

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haha sorry. forgot to write the maths


### Input

- `ℓ` -- direction
- `X` -- set
- `H` -- hyperplane
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spaces


### Output

The support function of ``X ∩ H`` along direction ``ℓ``.
"""
function _projection(ℓ, X, H::Union{Hyperplane{N}, Line{N}};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-> d?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if u don't mind i would keep here so that it matches the original algorithm

lazy_linear_map=false,
lazy_2d_intersection=true,
kwargs...) where {N}

options = Dict(kwargs)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

options is never actually used.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct, i have to remove it 👍

n = H.a # normal vector to the hyperplane
γ = H.b # displacement of the hyperplane
Πnℓ = vcat(n', ℓ') # projection map
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Πnℓ - cool idea


x_dir = [one(N), zero(N)]
y_dir = [zero(N), one(N)]

Lγ = Line(x_dir, γ)

Snℓ = lazy_linear_map ? LinearMap(Πnℓ, X) : linear_map(Πnℓ, X)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the spirit of above, what about \bigcap<TAB>Sℓ or S\bigcap<TAB>ℓ (resp. d instead of )?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice! we can use the \bigcap notation in the hybrid algorithm too 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I misinterpreted the n as a symbol for intersection 😄

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm better if i use Xnℓ since the given set is X

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does the notation mean?

cap = lazy_2d_intersection ? Intersection(Snℓ, Lγ) : intersection(Snℓ, Lγ)
return ρ(y_dir, cap; kwargs...)
end
15 changes: 14 additions & 1 deletion test/unit_Intersection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,19 @@ d = normalize([1.0, 0.0])
using Optim
@test ρ(d, X ∩ H) == ρ(d, H ∩ X) == 1.0

# Hyperplane - Ball1 intersection
# Ball1 vs HalfSpace intersection using default algorithm
H = HalfSpace([1.0, 0.0], 0.0); # x = 0
@test ρ(d, X ∩ H) < 1e-6 && ρ(d, H ∩ X) < 1e-6
# specify line search algorithm
@test ρ(d, X ∩ H, algorithm="line_search") < 1e-6 &&
ρ(d, H ∩ X, algorithm="line_search") < 1e-6

# Ball1 vs Hyperplane intersection
H = Hyperplane([1.0, 0.0], 0.5); # x = 0.5
@test isapprox(ρ(d, X ∩ H, algorithm="line_search"), 0.5, atol=1e-6)
# For the projection algorithm, if the linear map is taken lazily we can use Ball1
@test isapprox(ρ(d, X ∩ H, algorithm="projection", lazy_linear_map=true), 0.5, atol=1e-6)
# But the default is to take the linear map concretely; in this case, we *may*
# need Polyhedra (in the general case), for the concrete linear map. As a valid workaround
# if we don't want to load Polyhedra here is to convert the given set to a polygon in V-representation
@test isapprox(ρ(d, convert(VPolygon, X) ∩ H, algorithm="projection", lazy_linear_map=false), 0.5, atol=1e-6)