1+ # We use `Zero` so that it is allocation-free, while `zero(Rational{BigInt})` would be costly
2+ _default_tol (:: Type{<:Union{Integer, Rational}} ) = MA. Zero ()
3+ # `rtoldefault(BigFloat)` is quite slow and allocates a lot so we hope that
4+ # `tol` will be called at some upper level function and passed in here instead
5+ # of created everytime
6+ _default_tol (:: Type{T} ) where {T<: AbstractFloat } = Base. rtoldefault (T)
7+
8+ _default_tol (:: Type{T} , :: Type{U} ) where {T,U} = _default_tol (promote_type (T, U))
9+
10+ # We should **not** define `isless(::Float64, ::MutableArithmetics.Zero)`.
11+ # When we get such `MethodError`, it a nice error that always indicate some underlying issue
12+ # so we should fix that underlying issue, not add this method that would just hide bugs.
13+
114isapproxzero (x:: T ; kws... ) where {T<: Real } = x == zero (T)
2- isapproxzero (x:: T ; ztol = Base. rtoldefault (T)) where {T<: AbstractFloat } = abs (x) < ztol
3- isapproxzero (x:: AbstractVector{T} ; kws... ) where {T<: Real } = isapproxzero (maximum (abs .(x) ); kws... )
15+ isapproxzero (x:: T ; tol = Base. rtoldefault (T)) where {T<: AbstractFloat } = abs (x) < tol
16+ isapproxzero (x:: AbstractVector{T} ; kws... ) where {T<: Real } = isapproxzero (maximum (abs, x ); kws... )
417# isapproxzero(x::Union{SymPoint, Ray, Line}; kws...) = isapproxzero(coord(x); kws...)
518isapproxzero (x:: Union{Ray, Line} ; kws... ) = isapproxzero (coord (x); kws... )
619isapproxzero (h:: HRepElement ; kws... ) = isapproxzero (h. a; kws... ) && isapproxzero (h. β; kws... )
720
8- _isapprox (x:: Union{T, AbstractArray{T}} , y:: Union{T, AbstractArray{T}} ) where {T<: Union{Integer, Rational} } = x == y
21+ _isapprox (x:: Union{T, AbstractArray{T}} , y:: Union{T, AbstractArray{T}} ; tol ) where {T<: Union{Integer, Rational} } = x == y
922# I check with zero because isapprox(0, 1e-100) is false...
1023# but isapprox(1e-100, 2e-100) should be false
11- _isapprox (x, y) = (isapproxzero (x) ? isapproxzero (y) : (isapproxzero (y) ? isapproxzero (x) : isapprox (x, y)))
24+ _isapprox (x, y; tol ) = (isapproxzero (x; tol ) ? isapproxzero (y; tol ) : (isapproxzero (y; tol ) ? isapproxzero (x; tol ) : isapprox (x, y; rtol = tol )))
1225
1326# Base.isapprox(r::SymPoint, s::SymPoint) = _isapprox(coord(r), coord(s)) || _isapprox(coord(r), -coord(s))
1427function _scaleray (r:: Union{Line, Ray} , s:: Union{Line, Ray} )
1528 cr = coord (r)
1629 cs = coord (s)
1730 cr * sum (abs .(cs)), cs * sum (abs .(cr))
1831end
19- function Base . isapprox (r:: Line , s:: Line )
32+ function _isapprox (r:: Line , s:: Line ; tol )
2033 rs, ss = _scaleray (r, s)
21- _isapprox (rs, ss) || _isapprox (rs, - ss)
34+ _isapprox (rs, ss; tol ) || _isapprox (rs, - ss; tol )
2235end
23- function Base . isapprox (r:: Ray , s:: Ray )
24- _isapprox (_scaleray (r, s)... )
36+ function _isapprox (r:: Ray , s:: Ray ; tol )
37+ _isapprox (_scaleray (r, s)... ; tol )
2538end
2639# TODO check that Vec in GeometryTypes also does that
2740function _scalehp (h1, h2)
@@ -33,28 +46,28 @@ function Base.:(==)(h1::HyperPlane, h2::HyperPlane)
3346 (a1, β1), (a2, β2) = _scalehp (h1, h2)
3447 (a1 == a2 && β1 == β2) || (a1 == - a2 && β1 == - β2)
3548end
36- function Base . isapprox (h1:: HyperPlane , h2:: HyperPlane )
49+ function _isapprox (h1:: HyperPlane , h2:: HyperPlane ; tol )
3750 (a1, β1), (a2, β2) = _scalehp (h1, h2)
38- (_isapprox (a1, a2) && _isapprox (β1, β2)) || (_isapprox (a1, - a2) && _isapprox (β1, - β2))
51+ (_isapprox (a1, a2; tol ) && _isapprox (β1, β2; tol )) || (_isapprox (a1, - a2; tol ) && _isapprox (β1, - β2; tol ))
3952end
4053function Base.:(== )(h1:: HalfSpace , h2:: HalfSpace )
4154 (a1, β1), (a2, β2) = _scalehp (h1, h2)
4255 a1 == a2 && β1 == β2
4356end
44- function Base . isapprox (h1:: HalfSpace , h2:: HalfSpace )
57+ function _isapprox (h1:: HalfSpace , h2:: HalfSpace ; tol )
4558 (a1, β1), (a2, β2) = _scalehp (h1, h2)
46- _isapprox (a1, a2) && _isapprox (β1, β2)
59+ _isapprox (a1, a2; tol ) && _isapprox (β1, β2; tol )
4760end
4861
49- _lt (x:: T , y:: T ) where {T<: Real } = x < y
50- _lt (x:: T , y:: T ) where {T<: AbstractFloat } = x < y && ! _isapprox (x, y)
51- _lt (x:: S , y:: T ) where {S<: Real ,T<: Real } = _lt (promote (x, y)... )
52- _gt (x:: S , y:: T ) where {S<: Real , T<: Real } = _lt (y, x)
53- _leq (x:: T , y:: T ) where {T<: Real } = x <= y
54- _leq (x:: T , y:: T ) where {T<: AbstractFloat } = x <= y || _isapprox (x, y)
55- _leq (x:: S , y:: T ) where {S<: Real ,T<: Real } = _leq (promote (x, y)... )
56- _geq (x:: T , y:: T ) where {T<: Real } = _leq (y, x)
57- _pos (x:: T ) where {T<: Real } = _gt (x, zero (T))
58- _neg (x:: T ) where {T<: Real } = _lt (x, zero (T))
59- _nonneg (x:: T ) where {T<: Real } = _geq (x, zero (T))
60- _nonpos (x:: T ) where {T<: Real } = _leq (x, zero (T))
62+ _lt (x:: T , y:: T ; tol ) where {T<: Real } = x < y
63+ _lt (x:: T , y:: T ; tol ) where {T<: AbstractFloat } = x < y && ! _isapprox (x, y; tol )
64+ _lt (x:: S , y:: T ; tol ) where {S<: Real ,T<: Real } = _lt (promote (x, y)... ; tol )
65+ _gt (x:: S , y:: T ; tol ) where {S<: Real , T<: Real } = _lt (y, x; tol )
66+ _leq (x:: T , y:: T ; tol ) where {T<: Real } = x <= y
67+ _leq (x:: T , y:: T ; tol ) where {T<: AbstractFloat } = x <= y || _isapprox (x, y; tol )
68+ _leq (x:: S , y:: T ; tol ) where {S<: Real ,T<: Real } = _leq (promote (x, y)... ; tol )
69+ _geq (x:: T , y:: T ; tol ) where {T<: Real } = _leq (y, x; tol )
70+ _pos (x:: T ; tol ) where {T<: Real } = _gt (x, zero (T); tol )
71+ _neg (x:: T ; tol ) where {T<: Real } = _lt (x, zero (T); tol )
72+ _nonneg (x:: T ; tol ) where {T<: Real } = _geq (x, zero (T); tol )
73+ _nonpos (x:: T ; tol ) where {T<: Real } = _leq (x, zero (T); tol )
0 commit comments