-
Notifications
You must be signed in to change notification settings - Fork 33
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
#1500 - Option to apply linear_map in H-rep without invertibility check #1713
Conversation
e49c29b
to
285d518
Compare
The logic of the PR looks good to me. On the other hand, after successive extensions to the concrete linear map interface, i think it has become rather obscure... no? I suggest to either: (i) add more examples that illustrate the different use cases, or Thoughts for point (ii): Problem: To compute
Keywords:
Additional arguments:
Defaults:
Additional arguments:
Pseudocode: function linear_map(M::Union{AbstractMatrix{N}, Nothing},
P::AbstractPolyhedron{N};
use_vrep::Bool=false,
inverse::Union{Nothing, AbstractMatrix{N}}=nothing,
check_invertibility::Bool=(inverse == nothing),
cond_tol::Number=DEFAULT_COND_TOL,
use_inv::Bool=(inverse != nothing || !issparse(M))
) where {N<:Real}
@assert # check that dimensions match, should work if M is Nothing as well, by checking the dimensions of inverse
# if use_vrep is activated, the rest of the arguments can be safely ignored
use_vrep && return _linear_map_vrep(M, P)
is_invertible = true
if check_invertibility # check if we can invert
is_invertible = isinvertible(M; cond_tol=cond_tol)
end
if is_invertible
# if we can invert => use hrep
return _linear_map_hrep(M, P, use_inv; inverse=inverse)
else
# otherwise, use vrep
return _linear_map_vrep(M, P)
end
end Comments on the pseudocode:
|
I also thought about this but did not want to break the current API. But since this seems okay, let me add another proposal. Since passing the inverse is a special use case, I think we can add a new method for this purpose. function linear_map(M::Union{AbstractMatrix{N}, Nothing},
P::AbstractPolyhedron{N};
inverse::AbstractMatrix) where {N<:Real}
return _linear_map_hrep(M, P, true; inverse=inverse)
end
function linear_map(M::AbstractMatrix{N}, P::AbstractPolyhedron{N};
algorithm::Symbol=(issparse(M) ? :division : :inverse),
check_invertibility::Bool=true,
cond_tol::Number=DEFAULT_COND_TOL) where {N<:Real}
@assert dim(P) == size(M, 2)
@assert algorithm in [:vrep, :inverse, :division]
# check invertibility
if algorithm != :vrep && check_invertibility && !isinvertible(M; cond_tol=cond_tol)
algorithm = :vrep
end
if algorithm == :vrep
return _linear_map_vrep(M, P)
else
use_inv = algorithm == :inverse
return _linear_map_hrep(M, P, use_inv)
end
end |
We agreed to use the version in #1713 (comment) with strings instead of symbols. |
285d518
to
5c28abf
Compare
Unfortunately the idea with the two methods does not work. For some reason, Julia does not find the method. It only works when passing julia> using LazySets
julia> M = rand(2, 2)
2×2 Array{Float64,2}:
0.0509302 0.107692
0.0785203 0.835182
julia> linear_map(nothing, Singleton([1., 1.]); inverse=inv(M))
HPolygon{Float64}(HalfSpace{Float64,VN} where VN<:AbstractArray{Float64,1}[HalfSpace{Float64,Array{Float64,1}}([-2.3040029056097, 1.4944331500210524], 1.0), HalfSpace{Float64,Array{Float64,1}}([-24.50655542281636, 3.1599899249110077], -1.0), HalfSpace{Float64,Array{Float64,1}}([2.3040029056097, -1.4944331500210524], -1.0), HalfSpace{Float64,Array{Float64,1}}([24.50655542281636, -3.1599899249110077], 1.0)])
julia> linear_map(M, Singleton([1., 1.]); inverse=inv(M))
ERROR: MethodError: no method matching linear_map(::Array{Float64,2}, ::Singleton{Float64,Array{Float64,1}}; inverse=[24.50655542281636 -3.1599899249110077; -2.3040029056097 1.4944331500210524]) EDIT: When I replace Should we instead assign a new name to the "inverse" function? |
ok then i tend to prefer having a single |
Finally the build passes. |
Closes #1500.
CC @ueliwechsler