diff --git a/src/HPolyhedron.jl b/src/HPolyhedron.jl index 0b85e43168..846e322321 100644 --- a/src/HPolyhedron.jl +++ b/src/HPolyhedron.jl @@ -502,14 +502,17 @@ function remove_redundant_constraints!(P::PT; end """ - linear_map(M::AbstractMatrix{N}, P::PT) where {N<:Real, PT<:HPoly{N}} + linear_map(M::AbstractMatrix{N}, P::PT; [cond_tol=DEFAULT_COND_TOL]::Number) + where {N<:Real, PT<:HPoly{N}} Concrete linear map of a polyhedron in constraint representation. ### Input -- `M` -- matrix -- `P` -- polyhedron in constraint representation +- `M` -- matrix +- `P` -- polyhedron in constraint representation +- `cond_tol` -- (optional) tolerance of matrix condition (used to check whether + the matrix is invertible) ### Output @@ -521,8 +524,11 @@ If the matrix ``M`` is invertible (which we check with a sufficient condition), then ``y = M x`` implies ``x = \\text{inv}(M) y`` and we transform the constraint system ``A x ≤ b`` to ``A \\text{inv}(M) y ≤ b``. """ -function linear_map(M::AbstractMatrix{N}, P::PT) where {N<:Real, PT<:HPoly{N}} - if !isinvertible(M) +function linear_map(M::AbstractMatrix{N}, + P::PT; + cond_tol::Number=DEFAULT_COND_TOL + ) where {N<:Real, PT<:HPoly{N}} + if !isinvertible(M; cond_tol=cond_tol) if P isa HPolyhedron error("linear maps for polyhedra need to be invertible") end diff --git a/src/LinearMap.jl b/src/LinearMap.jl index 29bfe15d1c..0b4d156371 100644 --- a/src/LinearMap.jl +++ b/src/LinearMap.jl @@ -201,13 +201,15 @@ function ρ(d::AbstractVector{N}, lm::LinearMap{N}; kwargs...) where {N<:Real} end """ - isbounded(lm::LinearMap)::Bool + isbounded(lm::LinearMap; cond_tol::Number=DEFAULT_COND_TOL)::Bool Determine whether a linear map is bounded. ### Input -- `lm` -- linear map +- `lm` -- linear map +- `cond_tol` -- (optional) tolerance of matrix condition (used to check whether + the matrix is invertible) ### Output @@ -221,11 +223,11 @@ If the matrix is invertible, then the map being bounded is equivalent to the wrapped set being bounded, and hence the map is unbounded. Otherwise, we check boundedness via [`isbounded_unit_dimensions`](@ref). """ -function isbounded(lm::LinearMap)::Bool +function isbounded(lm::LinearMap; cond_tol::Number=DEFAULT_COND_TOL)::Bool if iszero(lm.M) || isbounded(lm.X) return true end - if isinvertible(lm.M) + if isinvertible(lm.M; cond_tol=cond_tol) return false end return isbounded_unit_dimensions(lm) diff --git a/src/helper_functions.jl b/src/helper_functions.jl index aeb285f4fc..e76066ac30 100644 --- a/src/helper_functions.jl +++ b/src/helper_functions.jl @@ -1,3 +1,6 @@ +# default tolerance for matrix condition number (see 'isinvertible') +DEFAULT_COND_TOL = 1e6 + """ sign_cadlag(x::N)::N where {N<:Real} @@ -87,14 +90,15 @@ function ispermutation(u::AbstractVector{T}, v::AbstractVector{T})::Bool where T end """ - isinvertible(M::AbstractMatrix; [cond_tol]::Number=1e6) + isinvertible(M::AbstractMatrix; [cond_tol]::Number=DEFAULT_COND_TOL) A sufficient check of a matrix being invertible (or nonsingular). ### Input - `M` -- matrix -- `cond_tol` -- (optional, default: `1e6`) tolerance of matrix condition +- `cond_tol` -- (optional, default: `DEFAULT_COND_TOL`) tolerance of matrix + condition ### Output @@ -107,7 +111,7 @@ We check whether the [matrix condition number](https://en.wikipedia.org/wiki/Condition_number#Matrices) `cond(M)` is below some prescribed tolerance. """ -function isinvertible(M::AbstractMatrix; cond_tol::Number=1e6) +function isinvertible(M::AbstractMatrix; cond_tol::Number=DEFAULT_COND_TOL) return cond(M) < cond_tol end