From 32030a3f2d8a0dd1741edaa6311424d5345b97fa Mon Sep 17 00:00:00 2001 From: Luis Benet Date: Tue, 24 Apr 2018 21:20:13 -0500 Subject: [PATCH 1/6] Implement mod(a,y) --- src/IntervalArithmetic.jl | 1 + src/intervals/functions.jl | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/IntervalArithmetic.jl b/src/IntervalArithmetic.jl index 910ca1b48..e2383f2ee 100644 --- a/src/IntervalArithmetic.jl +++ b/src/IntervalArithmetic.jl @@ -27,6 +27,7 @@ import Base: in, zero, one, eps, typemin, typemax, abs, abs2, real, min, max, sqrt, exp, log, sin, cos, tan, inv, exp2, exp10, log2, log10, + mod, asin, acos, atan, atan2, sinh, cosh, tanh, asinh, acosh, atanh, union, intersect, isempty, diff --git a/src/intervals/functions.jl b/src/intervals/functions.jl index e810afc0a..08eaf6ee0 100644 --- a/src/intervals/functions.jl +++ b/src/intervals/functions.jl @@ -266,3 +266,23 @@ for f in (:log, :log2, :log10, :log1p) end end + +# mod +function mod(a::Interval, y::T) where {T<:Real} + yy = abs(y) + fld_lo = fld(a.lo, yy) + fld_hi = fld(a.hi, yy) + z = zero(fld_lo) + + if fld_lo != fld_hi + # `a` includes a discontinuity of `mod` + if y > 0 + return interval(z, y) + else + return interval(y, z) + end + else + # no discontinuity crossed within `a` + return interval(mod(a.lo, y), mod(a.hi, y)) + end +end From ee8a95b1da6e42eee8ca6174a415f51c1c1ca763 Mon Sep 17 00:00:00 2001 From: Luis Benet Date: Thu, 3 May 2018 13:14:12 -0500 Subject: [PATCH 2/6] Add tests --- test/interval_tests/numeric.jl | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/interval_tests/numeric.jl b/test/interval_tests/numeric.jl index 82c321e88..75f22b185 100644 --- a/test/interval_tests/numeric.jl +++ b/test/interval_tests/numeric.jl @@ -284,3 +284,30 @@ end end =# end + +@testset "`mod`" begin + r = 0.0625 + a = r..(1+r) + @test mod(a, 1) == mod(a, 1.0) == interval(0,1) + @test mod(a, 2) == mod(a, 2.0) == a + @test mod(a, 2.5) == a + @test mod(a, -1) == mod(a, -1.0) == interval(-1,0) + @test mod(a, -2) == mod(a, -2.0) == -2+a + @test mod(a, -2.5) == -2.5+a + + a = (-1+r) .. -r + @test mod(a, 1) == mod(a, 1.0) == 1+a + @test mod(a, 2) == mod(a, 2.0) == 2+a + @test mod(a, 2.5) == 2.5+a + @test mod(a, -1) == mod(a, -1.0) == a + @test mod(a, -2) == mod(a, -2.0) == a + @test mod(a, -2.5) == a + + a = -r .. 1-r + @test mod(a, 1) == mod(a, 1.0) == interval(0,1) + @test mod(a, 2) == mod(a, 2.0) == interval(0,2) + @test mod(a, 2.5) == interval(0,2.5) + @test mod(a, -1) == mod(a, -1.0) == interval(-1,0) + @test mod(a, -2) == mod(a, -2.0) == interval(-2,0) + @test mod(a, -2.5) == interval(-2.5,0) +end From b27263aea9cecae96b501bc6e5f7faa6cfe7f6e1 Mon Sep 17 00:00:00 2001 From: Luis Benet Date: Fri, 4 May 2018 10:43:32 -0500 Subject: [PATCH 3/6] Add extended_mod(a, y), with tests --- src/IntervalArithmetic.jl | 2 +- src/intervals/functions.jl | 30 ++++++++++++++++++ test/interval_tests/numeric.jl | 56 +++++++++++++++++++++++++++++----- 3 files changed, 79 insertions(+), 9 deletions(-) diff --git a/src/IntervalArithmetic.jl b/src/IntervalArithmetic.jl index e2383f2ee..3639e8924 100644 --- a/src/IntervalArithmetic.jl +++ b/src/IntervalArithmetic.jl @@ -62,7 +62,7 @@ export RoundTiesToEven, RoundTiesToAway, cancelminus, cancelplus, isunbounded, .., @I_str, ±, - pow, extended_div, + pow, extended_div, extended_mod, setformat, @format export diff --git a/src/intervals/functions.jl b/src/intervals/functions.jl index 08eaf6ee0..534c68746 100644 --- a/src/intervals/functions.jl +++ b/src/intervals/functions.jl @@ -286,3 +286,33 @@ function mod(a::Interval, y::T) where {T<:Real} return interval(mod(a.lo, y), mod(a.hi, y)) end end + + +function extended_mod(a::Interval, y::T) where {T<:Real} + yy = abs(y) + fld_lo = fld(a.lo, yy) + fld_hi = fld(a.hi, yy) + z = zero(fld_lo) + S = typeof( z ) + ee = emptyinterval(S) + + if fld_lo + 1 == fld_hi + # `a` includes one discontinuity + if y > 0 + return interval(mod(a.lo, y), y), interval(z, mod(a.hi, y)), ee + else + return interval(mod(a.lo, y), z), interval(y, mod(a.hi, y)), ee + end + elseif fld_lo +1 < fld_hi + # `a` includes more discontinuities + if y > 0 + return interval(mod(a.lo, y), y), interval(z, y), interval(z, mod(a.hi, y)) + else + return interval(mod(a.lo, y), z), interval(y, z), interval(y, mod(a.hi, y)) + end + else + # no discontinuity crossed within `a` + return interval(mod(a.lo, y), mod(a.hi, y)), ee, ee + end + +end diff --git a/test/interval_tests/numeric.jl b/test/interval_tests/numeric.jl index 75f22b185..2655a04de 100644 --- a/test/interval_tests/numeric.jl +++ b/test/interval_tests/numeric.jl @@ -288,26 +288,66 @@ end @testset "`mod`" begin r = 0.0625 a = r..(1+r) - @test mod(a, 1) == mod(a, 1.0) == interval(0,1) + @test mod(a, 1) == mod(a, 1.0) == 0..1 @test mod(a, 2) == mod(a, 2.0) == a @test mod(a, 2.5) == a - @test mod(a, -1) == mod(a, -1.0) == interval(-1,0) + @test mod(a, 0.5) == 0..0.5 + @test mod(a, -1) == mod(a, -1.0) == -1..0 @test mod(a, -2) == mod(a, -2.0) == -2+a @test mod(a, -2.5) == -2.5+a + @test mod(a, -0.5) == -0.5..0 a = (-1+r) .. -r @test mod(a, 1) == mod(a, 1.0) == 1+a @test mod(a, 2) == mod(a, 2.0) == 2+a @test mod(a, 2.5) == 2.5+a + @test mod(a, 0.5) == 0..0.5 @test mod(a, -1) == mod(a, -1.0) == a @test mod(a, -2) == mod(a, -2.0) == a @test mod(a, -2.5) == a + @test mod(a, -0.5) == -0.5..0 a = -r .. 1-r - @test mod(a, 1) == mod(a, 1.0) == interval(0,1) - @test mod(a, 2) == mod(a, 2.0) == interval(0,2) - @test mod(a, 2.5) == interval(0,2.5) - @test mod(a, -1) == mod(a, -1.0) == interval(-1,0) - @test mod(a, -2) == mod(a, -2.0) == interval(-2,0) - @test mod(a, -2.5) == interval(-2.5,0) + @test mod(a, 1) == mod(a, 1.0) == 0..1 + @test mod(a, 2) == mod(a, 2.0) == 0..2 + @test mod(a, 2.5) == 0..2.5 + @test mod(a, 0.5) == 0..0.5 + @test mod(a, -1) == mod(a, -1.0) == -1..0 + @test mod(a, -2) == mod(a, -2.0) == -2..0 + @test mod(a, -2.5) == -2.5..0 + @test mod(a, -0.5) == -0.5..0 +end + +@testset "`extended_mod`" begin + r = 0.0625 + a = r..(1+r) + ee = emptyinterval(Float64) + @test extended_mod(a, 1) == (r..1, 0..r, ee) + @test extended_mod(a, 2) == (a, ee, ee) + @test extended_mod(a, 2.5) == (a, ee, ee) + @test extended_mod(a, 0.5) == (r..0.5, 0..0.5, 0..r) + @test extended_mod(a, -1) == ((-1+r)..0, -1..(-1+r), ee) + @test extended_mod(a, -2) == ((-2+r)..(-1+r), ee, ee) + @test extended_mod(a, -2.5) == ((-2.5+r)..(-1.5+r), ee, ee) + @test extended_mod(a, -0.5) == ((-0.5+r)..0, -0.5..0, -0.5..(-0.5+r)) + + a = (-1+r) .. -r + @test extended_mod(a, 1) == (1+a, ee, ee) + @test extended_mod(a, 2) == (2+a, ee, ee) + @test extended_mod(a, 2.5) == (2.5+a, ee, ee) + @test extended_mod(a, 0.5) == (r..0.5, 0..(0.5-r), ee) + @test extended_mod(a, -1) == ((-1+r) .. -r, ee, ee) + @test extended_mod(a, -2) == ((-1+r) .. -r, ee, ee) + @test extended_mod(a, -2.5) == ((-1+r) .. -r, ee, ee) + @test extended_mod(a, -0.5) == ((-0.5+r)..0, -0.5 .. -r, ee) + + a = -r .. 1-r + @test extended_mod(a, 1) == ((1-r)..1, 0..(1-r), ee) + @test extended_mod(a, 2) == ((2-r)..2, 0..(1-r), ee) + @test extended_mod(a, 2.5) == ((2.5-r)..2.5, 0..(1-r), ee) + @test extended_mod(a, 0.5) == ((0.5-r)..0.5, 0..0.5, 0..(0.5-r)) + @test extended_mod(a, -1) == (-r..0, -1..(-r), ee) + @test extended_mod(a, -2) == (-r..0, -2..(-1-r), ee) + @test extended_mod(a, -2.5) == (-r..0, (-2.5)..(-1.5-r), ee) + @test extended_mod(a, -0.5) == (-r..0, -0.5..0, -0.5..(-r)) end From 1061f2240b499e9e7239858ce48a22ba813f9e1f Mon Sep 17 00:00:00 2001 From: Luis Benet Date: Fri, 29 Jun 2018 10:49:44 -0500 Subject: [PATCH 4/6] Change fld(a,b) -> floor(a,b) --- src/intervals/functions.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/intervals/functions.jl b/src/intervals/functions.jl index 534c68746..84de1fb4c 100644 --- a/src/intervals/functions.jl +++ b/src/intervals/functions.jl @@ -270,8 +270,8 @@ end # mod function mod(a::Interval, y::T) where {T<:Real} yy = abs(y) - fld_lo = fld(a.lo, yy) - fld_hi = fld(a.hi, yy) + fld_lo = floor(a.lo/yy) + fld_hi = floor(a.hi/yy) z = zero(fld_lo) if fld_lo != fld_hi @@ -290,8 +290,8 @@ end function extended_mod(a::Interval, y::T) where {T<:Real} yy = abs(y) - fld_lo = fld(a.lo, yy) - fld_hi = fld(a.hi, yy) + fld_lo = floor(a.lo/yy) + fld_hi = floor(a.hi/yy) z = zero(fld_lo) S = typeof( z ) ee = emptyinterval(S) From 0b9d01b6a01e38be128eba2f9f01861c2b43c558 Mon Sep 17 00:00:00 2001 From: Luis Benet Date: Fri, 29 Jun 2018 20:19:02 -0500 Subject: [PATCH 5/6] Add tests involving pi --- test/interval_tests/numeric.jl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/interval_tests/numeric.jl b/test/interval_tests/numeric.jl index 2655a04de..1f4b4450d 100644 --- a/test/interval_tests/numeric.jl +++ b/test/interval_tests/numeric.jl @@ -316,6 +316,12 @@ end @test mod(a, -2) == mod(a, -2.0) == -2..0 @test mod(a, -2.5) == -2.5..0 @test mod(a, -0.5) == -0.5..0 + + a = pi_interval() + @test mod(a, pi) == interval(0.0, a.hi-pi) + @test mod(2a, pi) == interval(0.0, 2*(a.hi-pi)) + @test mod(1.5a, pi) == interval(0.5a.lo, 1.5a.hi-pi) + @test mod(interval(0.25,3pi), pi) == interval(0.0, a.lo) end @testset "`extended_mod`" begin @@ -350,4 +356,13 @@ end @test extended_mod(a, -2) == (-r..0, -2..(-1-r), ee) @test extended_mod(a, -2.5) == (-r..0, (-2.5)..(-1.5-r), ee) @test extended_mod(a, -0.5) == (-r..0, -0.5..0, -0.5..(-r)) + + a = pi_interval(Float64) + @test extended_mod(a, pi) == (mod(a, pi), ee, ee) + @test extended_mod(2a, pi) == (interval(0.0, 2*(a.hi-pi)), ee, ee) + @test extended_mod(1.5a, pi) == (interval(0.5a.lo, 1.5a.hi-pi), ee, ee) + @test extended_mod(interval(0.25,3pi), pi) == (interval(0.25, a.lo), + interval(0.0, a.lo), interval(0.0)) + @test extended_mod(@interval(0.25,3pi), pi) == (interval(0.25, a.lo), + interval(0.0, a.lo), mod(@interval(3pi), pi)) end From e0eaa54e61ee9d22bd0d9f7cf626fcf5c092dfaf Mon Sep 17 00:00:00 2001 From: Luis Benet Date: Fri, 29 Jun 2018 20:25:38 -0500 Subject: [PATCH 6/6] Fix tests --- test/interval_tests/numeric.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/interval_tests/numeric.jl b/test/interval_tests/numeric.jl index 1f4b4450d..18c39ff12 100644 --- a/test/interval_tests/numeric.jl +++ b/test/interval_tests/numeric.jl @@ -317,7 +317,7 @@ end @test mod(a, -2.5) == -2.5..0 @test mod(a, -0.5) == -0.5..0 - a = pi_interval() + a = pi_interval(Float64) @test mod(a, pi) == interval(0.0, a.hi-pi) @test mod(2a, pi) == interval(0.0, 2*(a.hi-pi)) @test mod(1.5a, pi) == interval(0.5a.lo, 1.5a.hi-pi)