diff --git a/src/IntervalSets.jl b/src/IntervalSets.jl index b7374aa..89fdc39 100644 --- a/src/IntervalSets.jl +++ b/src/IntervalSets.jl @@ -337,6 +337,47 @@ maximum(d::TypedEndpointsInterval{L,:open}) where L = throw(ArgumentError("$d is extrema(I::TypedEndpointsInterval) = (infimum(I), supremum(I)) +function minimum(::typeof(abs), I::AbstractInterval) + a, b = abs.(endpoints(I)) + z = zero(promote_type(typeof(a), typeof(b))) + ac, bc = closedendpoints(I) + if isempty(I) + throw(ArgumentError("minimum(abs, $I) is undefined for empty intervals")) + elseif z ∈ I + return z + elseif a < b + ac && return a + throw(ArgumentError("$I is open on the left, no minimum(abs)")) + elseif a > b + bc && return b + throw(ArgumentError("$I is open on the right, no minimum(abs)")) + else + throw(ArgumentError("cannot determine minimum(abs, $I)")) + end +end + +function maximum(::typeof(abs), I::AbstractInterval) + a, b = abs.(endpoints(I)) + ac, bc = closedendpoints(I) + if isempty(I) + throw(ArgumentError("maximum(abs, $I) is undefined for empty intervals")) + elseif a == b + ac && return a + bc && return b + throw(ArgumentError("$I is open on both sides, no maximum(abs)")) + elseif a > b + ac && return a + throw(ArgumentError("$I is open on the left, no maximum(abs)")) + elseif a < b + bc && return b + throw(ArgumentError("$I is open on the right, no maximum(abs)")) + else + throw(ArgumentError("cannot determine maximum(abs, $I)")) + end +end + +extrema(::typeof(abs), I::AbstractInterval) = (minimum(abs, I), maximum(abs, I)) + # Open and closed at endpoints isleftclosed(d::TypedEndpointsInterval{:closed}) = true isleftclosed(d::TypedEndpointsInterval{:open}) = false diff --git a/test/base_methods.jl b/test/base_methods.jl index a21fd1a..75e9484 100644 --- a/test/base_methods.jl +++ b/test/base_methods.jl @@ -102,3 +102,23 @@ end IntervalSets.endpoints(::RandTestUnitInterval) = (-1.0, 1.0) @test rand(RandTestUnitInterval()) in -1.0..1.0 end + +@testset "min/maximum(abs)" begin + @test maximum(abs, 1..2) == 2 + @test maximum(abs, -3..2) == 3 + @test minimum(abs, 1..2) == 1 + @test minimum(abs, -3..2) == 0 + @test_throws Exception maximum(abs, iv"[1, 2)") + @test minimum(abs, iv"[1, 2)") == 1 + @test minimum(abs, iv"(-3, 2)") == 0 + + @test maximum(abs, 1u"m"..2u"m") == 2u"m" + @test maximum(abs, -3u"m"..2u"m") == 3u"m" + @test minimum(abs, 1u"m"..2u"m") == 1u"m" + @test minimum(abs, -3u"m"..2u"m") == 0u"m" + + @test extrema(abs, 1..2) == (1, 2) + @test extrema(abs, -3..2) == (0, 3) + @test_throws Exception extrema(abs, iv"[1, 2)") + @test extrema(abs, iv"[-3, 2)") == (0, 3) +end