diff --git a/NEWS.md b/NEWS.md index 7dc672caa..66ae524cb 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,7 +6,7 @@ - The package now supports only Julia v1.3 and later. ### Breaking changes -- Changed from using `FastRounding.jl` to `RoundingEmulator.jl` for the defalt rounding mode. [#370](https://github.com/JuliaIntervals/IntervalArithmetic.jl/pull/370) +- Changed from using `FastRounding.jl` to `RoundingEmulator.jl` for the default rounding mode. [#370](https://github.com/JuliaIntervals/IntervalArithmetic.jl/pull/370) ## v0.15 @@ -293,7 +293,7 @@ v0.1 is the first public release of the package. ### Interval arithmetic - Two methods for interval rounding are available: - (i) narrow/slow (which uses hardward rounding mode changes for `Float64` intervals, and (ii) wide/fast (which does not change the rounding mode) + (i) narrow/slow (which uses hardware rounding mode changes for `Float64` intervals, and (ii) wide/fast (which does not change the rounding mode) - The current interval precision and rounding mode are stored in the `parameters` object - The macro `@interval` generates intervals based on the current interval precision - Trigonometric functions are "nearly" rigorous (for `Float64` intervals, correct rounding is not currently guaranteed) diff --git a/Project.toml b/Project.toml index 4e0f34ef4..73751e3d7 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "IntervalArithmetic" uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" repo = "https://github.com/JuliaIntervals/IntervalArithmetic.jl.git" -version = "0.21.0" +version = "0.21.1" [deps] CRlibm = "96374032-68de-5a5b-8d9e-752f78720389" diff --git a/docs/src/input_output.md b/docs/src/input_output.md index 8ac10dc3b..bd7874e0d 100644 --- a/docs/src/input_output.md +++ b/docs/src/input_output.md @@ -73,7 +73,7 @@ 'u' Returns the interval with midpoint as lower bound and radius taken in upward direction. 'C' Returns upper case for Empty, Entire and Nai 'c' Returns lower case for Empty, Entire and Nai - '+' Returns postitve numbers with '+' sign before the number + '+' Returns positive numbers with '+' sign before the number '0' Left-pads the numbers with zeros instead of spaces within the field width - The field width specifies the length of midpoint string. diff --git a/examples/Range of 2-dimensional functions.ipynb b/examples/Range of 2-dimensional functions.ipynb index d1827efc9..6c5e83601 100644 --- a/examples/Range of 2-dimensional functions.ipynb +++ b/examples/Range of 2-dimensional functions.ipynb @@ -356,7 +356,7 @@ "\t\tconsole.log.apply(console, arguments);\n", "\t }\n", "\t},\n", - "\t// a central way to initalize communication\n", + "\t// a central way to initialize communication\n", "\t// for widgets.\n", "\tcommInitializer: function (widget) {\n", "\t widget.sendUpdate = function () {};\n", @@ -435,7 +435,7 @@ " });\n", "\t });\n", "\n", - "\t // coordingate with Comm and redraw Signals\n", + "\t // coordinate with Comm and redraw Signals\n", "\t // XXX: Test using Reactive here to improve performance\n", "\t $([IPython.events]).on(\n", "\t\t'output_appended.OutputArea', function (event, type, value, md, toinsert) {\n", diff --git a/src/IntervalArithmetic.jl b/src/IntervalArithmetic.jl index ec52d4973..1673b2be2 100644 --- a/src/IntervalArithmetic.jl +++ b/src/IntervalArithmetic.jl @@ -17,7 +17,7 @@ export ×, dot import Base: - +, -, *, /, //, fma, + +, -, *, /, //, muladd, fma, <, >, ==, !=, ⊆, ^, <=, >=, in, zero, one, eps, typemin, typemax, abs, abs2, min, max, sqrt, exp, log, exp2, exp10, log2, log10, inv, cbrt, hypot, diff --git a/src/intervals/arithmetic/basic.jl b/src/intervals/arithmetic/basic.jl index fd825384e..2218b3213 100644 --- a/src/intervals/arithmetic/basic.jl +++ b/src/intervals/arithmetic/basic.jl @@ -95,7 +95,7 @@ end *(a::Interval, b::Interval) = *(promote(a, b)...) function *(a::Interval{T}, b::T) where {T<:NumTypes} - (isempty(a) || isthinzero(a) || iszero(b)) && return a + (isempty(a) || isthinzero(a) || isone(b)) && return a if b ≥ 0 return @round(T, inf(a) * b, sup(a) * b) else @@ -211,6 +211,20 @@ min_ignore_nans(args...) = minimum(filter(x -> !isnan(x), args)) max_ignore_nans(args...) = maximum(filter(x -> !isnan(x), args)) + + +muladd(a::F, b::F, c::F) where {F<:Interval} = a * b + c + +muladd(a::Interval, b::Interval, c::Interval) = muladd(promote(a, b, c)...) + +muladd(a::Interval{T}, b::Interval{S}, c::Number) where {T<:NumTypes,S<:NumTypes} = muladd(promote(a, b, interval(promote_numtype(T, S), c))...) +muladd(a::Interval{T}, b::Number, c::Interval{S}) where {T<:NumTypes,S<:NumTypes} = muladd(promote(a, interval(promote_numtype(T, S), b), c)...) +muladd(a::Number, b::Interval{T}, c::Interval{S}) where {T<:NumTypes,S<:NumTypes} = muladd(promote(interval(promote_numtype(T, S), a), b, c)...) + +muladd(a::Interval{T}, b::Number, c::Number) where {T<:NumTypes} = muladd(a, interval(T, b), interval(T, c)) +muladd(a::Number, b::Interval{T}, c::Number) where {T<:NumTypes} = muladd(interval(T, a), b, interval(T, c)) +muladd(a::Number, b::Number, c::Interval{T}) where {T<:NumTypes} = muladd(interval(T, a), interval(T, b), c) + """ fma(a::Interval, b::Interval, c::Interval) diff --git a/src/intervals/arithmetic/trigonometric.jl b/src/intervals/arithmetic/trigonometric.jl index 25815be07..04ae3250d 100644 --- a/src/intervals/arithmetic/trigonometric.jl +++ b/src/intervals/arithmetic/trigonometric.jl @@ -64,7 +64,7 @@ function sin(a::Interval{T}) where {T<:NumTypes} diam(a) > inf(two_pi(T)) && return whole_range - # The following is equiavlent to doing temp = a / half_pi and + # The following is equivalent to doing temp = a / half_pi and # taking floor(inf(a)), floor(sup(a)) alo, ahi = bounds(a) lo_quadrant = minimum(find_quadrants(T, alo)) diff --git a/src/multidim/intervalbox.jl b/src/multidim/intervalbox.jl index 48179e65e..05cfdbd26 100644 --- a/src/multidim/intervalbox.jl +++ b/src/multidim/intervalbox.jl @@ -61,7 +61,7 @@ length(::IntervalBox{N}) where {N} = N Return a vector of the `mid` of each interval composing the `IntervalBox`. -See `mid(X::Interval, α=0.5)` for more informations. +See `mid(X::Interval, α=0.5)` for more information. """ mid(X::IntervalBox) = mid.(X) scaled_mid(X::IntervalBox, α) = scaled_mid.(X, α) diff --git a/test/interval_tests/numeric.jl b/test/interval_tests/numeric.jl index bcb136075..21bdd6f71 100644 --- a/test/interval_tests/numeric.jl +++ b/test/interval_tests/numeric.jl @@ -70,7 +70,18 @@ end @test extended_div(interval(-2.0, -1.0), interval(-2.0, 4.0)) ≛ ((-∞.. -0.25), (0.5..∞)) @test extended_div(interval(0.0, 0.0), interval(-1.0, 1.0)) ≛ (entireinterval(c), emptyinterval(c)) - @test (0..∞) * (-1..∞) ≛ -∞..∞ + @test interval(0, Inf) * interval(-1, Inf) ≛ interval(-Inf, Inf) + + result = interval(1.1) * interval(2) + interval(3) + @test muladd(interval(1.1), interval(2), interval(3)) ≛ result + @test muladd(interval(1.1), interval(Float32, 2), interval(3)) ≛ result + @test muladd(interval(1.1), interval(2), 3) ≛ result + @test muladd(interval(1.1), 2, interval(3)) ≛ result + @test muladd(1.1, interval(2), interval(3)) ≛ result + @test muladd(interval(1.1), 2, 3) ≛ result + @test muladd(1.1, interval(2), 3) ≛ result + @test muladd(1.1, 2, interval(3)) ≛ result + end @testset "Arithmetic with constants" begin @@ -79,8 +90,9 @@ end @test 0.1 + x ≛ interval(1.0999999999999999, 2.1) @test 3.0 - x ≛ 1..2 @test 3.1 - x ≛ interval(1.1, 2.1) - @test 0.1 * (1..1) ≛ interval(0.1, 0.1) - @test (1..1) / 10.0 ≛ interval(0.09999999999999999, 0.1) + @test 0.1 * interval(1) ≛ interval(0.1, 0.1) + @test 0.0 * interval(1) ≛ interval(0.0, 0.0) + @test interval(1) / 10.0 ≛ interval(0.09999999999999999, 0.1) end @testset "Arithmetic with irrational" begin @@ -385,4 +397,4 @@ end @test nthroot(interval(BigFloat, -27, 27), -3) ≛ interval(BigFloat, -Inf, Inf) @test nthroot(interval(BigFloat, -81, -16), -4) ≛ ∅ @test nthroot(interval(BigFloat, -81, -16), 1) ≛ interval(BigFloat, -81, -16) -end +end \ No newline at end of file