From c12ebedcb52a6f397cd57bf27fb33eea68fb1153 Mon Sep 17 00:00:00 2001 From: "David P. Sanders" Date: Thu, 7 May 2026 20:18:47 -0500 Subject: [PATCH] Deprecate IntervalContractors in favour of IntervalArithmetic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every reverse-mode function previously defined here now lives in `IntervalArithmetic.jl` (>= 1.1). This release replaces the per-domain implementations with deprecation shims that forward to their IA equivalents and emit `Base.depwarn`. The package will be archived after the 0.7.x deprecation cycle. Changes: - New `src/deprecations.jl` provides the shims: - `@deprecate` for tuple-rewriting reverses and singleton extras whose names and shapes match IA (`plus_rev`, `minus_rev`, `div_rev`, `power_rev`, `max_rev`, `min_rev`, `mul_rev_to_pair`, `pow_rev1`, `pow_rev2`). - `@deprecate mul_rev → IntervalArithmetic.times_rev` (rename — the IC tuple-rewrite collided with IA's IEEE 1788 `mul_rev(b, c, x)`). - `@deprecate mul_rev_IEEE1788 → IntervalArithmetic.mul_rev`. - Manual shims for the 2-arg reverses (`sqr_rev`, `abs_rev`, `sign_rev`, `sqrt_rev`, `inv_rev`, the exp/log/trig/hyperbolic families) that wrap IA's single-output result back into IC's `(c, x_new)` tuple shape and emit `Base.depwarn`. - `src/IntervalContractors.jl` reduced to module declaration, exports, the `IntervalType{T}` alias for backwards compat, and the include of `deprecations.jl`. - Per-domain source files (`arithmetic.jl`, `exponential.jl`, `extrema.jl`, `hyperbolic.jl`, `inverse_hyperbolic.jl`, `inverse_trig.jl`, `trig.jl`, `transformations.jl`, `powers.jl`, plus the long-orphaned `decorated.jl` and `pave.jl`) are deleted. Helpers that lived alongside the reverses (`integer_contractor`, `reflect_x`, `sin_main`, `exp!`, `log!`, etc.) were never exported and are dropped with this release; consumers can pin to 0.6.0 or copy from git history. - `Project.toml`: bumped to 0.7.0, dropped the unused `IntervalBoxes` dependency, and tightened the `IntervalArithmetic` compat to `1.1`. - `README.md`: deprecation banner with a migration table at the top. - `test/runtests.jl`: explicit `using IntervalContractors:` imports for every reverse name to disambiguate from `IntervalArithmetic`'s same-named exports. - Four tests are now `@test_broken` because IA's implementation is tighter or more correct than IC's old one (`cos_rev` ulp drift, `acosh_rev` clipping, `max_rev` / `min_rev` on empty `a`); each is annotated inline with the reason. Depends on the IntervalArithmetic PR adding the new reverse exports (JuliaIntervals/IntervalArithmetic.jl#756) being merged and released as 1.1.0. Local test runs use `Pkg.develop` against that branch. Co-Authored-By: Claude Opus 4.7 (1M context) --- Project.toml | 6 +- README.md | 25 +++ src/IntervalContractors.jl | 103 ++++----- src/arithmetic.jl | 329 ---------------------------- src/decorated.jl | 35 --- src/deprecations.jl | 73 ++++++ src/exponential.jl | 94 -------- src/extrema.jl | 46 ---- src/hyperbolic.jl | 58 ----- src/inverse_hyperbolic.jl | 27 --- src/inverse_trig.jl | 45 ---- src/pave.jl | 30 --- src/powers.jl | 39 ---- src/transformations.jl | 88 -------- src/trig.jl | 173 --------------- test/Non1788tests/extrema.jl | 8 +- test/Non1788tests/inv_hyperbolic.jl | 5 +- test/libieeep1788_rev.jl | 3 +- test/runtests.jl | 19 ++ 19 files changed, 170 insertions(+), 1036 deletions(-) delete mode 100644 src/arithmetic.jl delete mode 100644 src/decorated.jl create mode 100644 src/deprecations.jl delete mode 100644 src/exponential.jl delete mode 100644 src/extrema.jl delete mode 100644 src/hyperbolic.jl delete mode 100644 src/inverse_hyperbolic.jl delete mode 100644 src/inverse_trig.jl delete mode 100644 src/pave.jl delete mode 100644 src/powers.jl delete mode 100644 src/transformations.jl delete mode 100644 src/trig.jl diff --git a/Project.toml b/Project.toml index 1c1d0da..1110055 100644 --- a/Project.toml +++ b/Project.toml @@ -1,14 +1,12 @@ name = "IntervalContractors" uuid = "15111844-de3b-5229-b4ba-526f2f385dc9" -version = "0.6.0" +version = "0.7.0" [deps] IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -IntervalBoxes = "43d83c95-ebbb-40ec-8188-24586a1458ed" [compat] -IntervalArithmetic = "1" -IntervalBoxes = "0.3.0" +IntervalArithmetic = "1.1" julia = "1.10" [extras] diff --git a/README.md b/README.md index 7f0ff93..c66f89e 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,31 @@ IntervalContractors [![Build Status](https://github.com/JuliaIntervals/IntervalContractors.jl/workflows/CI/badge.svg)](https://github.com/JuliaIntervals/IntervalContractors.jl/actions/workflows/CI.yml) +## ⚠ Deprecated — use `IntervalArithmetic.jl` + +As of v0.7.0, every reverse-mode function previously provided by this +package now lives in [`IntervalArithmetic.jl`](https://github.com/JuliaIntervals/IntervalArithmetic.jl) +(v1.1+). The exports here remain available as deprecation shims that +forward to their `IntervalArithmetic` equivalents and emit a +`Base.depwarn`. Once you have migrated, drop the dependency on +`IntervalContractors`. The package will be archived after the 0.7.x +deprecation cycle. + +Migration: + +| Old | New | +| :-------------------------------------------------------- | :--------------------------------------------------- | +| `IntervalContractors.plus_rev(a, b, c)` | `IntervalArithmetic.plus_rev(a, b, c)` | +| `IntervalContractors.mul_rev(a, b, c)` | `IntervalArithmetic.times_rev(a, b, c)` | +| `IntervalContractors.f_rev(c, x)` returning `(c, x_new)` | `IntervalArithmetic.f_rev(c, x)` returning `x_new` | +| `IntervalContractors.mul_rev_IEEE1788` | `IntervalArithmetic.mul_rev` | +| (other reverse names) | same name in `IntervalArithmetic` | + +`using IntervalContractors` and `using IntervalArithmetic` together now +makes the reverse names ambiguous. Resolve by qualifying explicitly +(`IntervalArithmetic.plus_rev(...)`) or by removing `using IntervalContractors` +once your call sites are migrated. + ## About `IntervalContractors.jl` `IntervalContractors.jl` provides contractors and reverse functions (also called backward functions or relational functions) for interval arithmetic. diff --git a/src/IntervalContractors.jl b/src/IntervalContractors.jl index 404febf..2cb52af 100644 --- a/src/IntervalContractors.jl +++ b/src/IntervalContractors.jl @@ -1,72 +1,47 @@ +""" + IntervalContractors + +**Deprecated** — every reverse-mode function previously defined here now +lives in `IntervalArithmetic.jl`. This package's exports remain available +in the 0.7.x line as deprecation shims that forward to their +`IntervalArithmetic` equivalents and emit a `Base.depwarn`. + +Migration: + +| Old | New | +| :---------------------------------------- | :--------------------------------------- | +| `IntervalContractors.plus_rev(a, b, c)` | `IntervalArithmetic.plus_rev(a, b, c)` | +| `IntervalContractors.mul_rev(a, b, c)` | `IntervalArithmetic.times_rev(a, b, c)` | +| `IntervalContractors.f_rev(c, x)` returning `(c, x')` | `IntervalArithmetic.f_rev(c, x)` returning the tightened `x` directly | +| `IntervalContractors.mul_rev_IEEE1788` | `IntervalArithmetic.mul_rev` | +| (other names) | same name in `IntervalArithmetic` | + +Once you have migrated, drop the dependency on `IntervalContractors`. +The package will be archived after the 0.7.x deprecation cycle. +""" module IntervalContractors export plus_rev, minus_rev, inv_rev, mul_rev, div_rev, power_rev, sign_rev, max_rev, min_rev, - sqr_rev, sqrt_rev, abs_rev, - exp_rev, exp2_rev, exp10_rev, expm1_rev, - log_rev, log2_rev, log10_rev, log1p_rev, - sin_rev, cos_rev, tan_rev, - asin_rev, acos_rev, atan_rev, - sinh_rev, cosh_rev, tanh_rev, - asinh_rev, acosh_rev, atanh_rev, - mul_rev_IEEE1788, mul_rev_to_pair, - pow_rev1, pow_rev2 - -using IntervalArithmetic, IntervalArithmetic.Symbols -using IntervalBoxes - + sqr_rev, sqrt_rev, abs_rev, + exp_rev, exp2_rev, exp10_rev, expm1_rev, + log_rev, log2_rev, log10_rev, log1p_rev, + sin_rev, cos_rev, tan_rev, + asin_rev, acos_rev, atan_rev, + sinh_rev, cosh_rev, tanh_rev, + asinh_rev, acosh_rev, atanh_rev, + mul_rev_IEEE1788, mul_rev_to_pair, + pow_rev1, pow_rev2 + +import IntervalArithmetic +using IntervalArithmetic: BareInterval, Interval + +# Internal helper retained for backwards compatibility with code that did +# `using IntervalContractors: IntervalType`. Prefer +# `Union{Interval{T}, BareInterval{T}}` directly. const IntervalType{T} = Union{Interval{T}, BareInterval{T}} -# @generated -# half_pi(::Type{T}) where {T <: IntervalType} = :(exact(0.5) * convert($T, exact(pi))) -# @generated -# two_pi(::Type{T}) where {T <: IntervalType} = :(exact(2.0) * convert($T, exact(pi))) - -@generated function half_pi(x::T) where {T <: IntervalType} - return exact(0.5) * convert(T, exact(pi)) -end - -@generated function two_pi(x::T) where {T <: IntervalType} - return exact(2.0) * convert(T, exact(pi)) -end - -@generated function pi_interval(x::T) where {T <: IntervalType} - return convert(T, exact(pi)) -end - - -include("arithmetic.jl") -include("transformations.jl") -include("powers.jl") -include("exponential.jl") -include("trig.jl") -include("inverse_trig.jl") -include("hyperbolic.jl") -include("inverse_hyperbolic.jl") -include("extrema.jl") - -""" -Dictionary mapping functions to their reverse functions. -""" -const reverse_operations = Dict( - :+ => :plus_rev, - :- => :minus_rev, - :* => :mul_rev, - :/ => :div_rev, - :^ => :power_rev, - :() => :() # empty operation - ) - -for f in ( :sqrt, :sqr, :abs, - :exp, :exp2, :exp10, :expm1, - :log, :log2, :log10, :log1p, - :sin, :cos, :tan, - :asin, :acos, :atan, - :sinh, :cosh, :tanh, - :asinh, :acosh, :atanh, - :inv, :sign, :max, :min) - reverse_operations[f] = Symbol(f, "_rev") -end +include("deprecations.jl") -end +end # module diff --git a/src/arithmetic.jl b/src/arithmetic.jl deleted file mode 100644 index 819050a..0000000 --- a/src/arithmetic.jl +++ /dev/null @@ -1,329 +0,0 @@ - -""" - plus_rev(a::IntervalType, b::IntervalType[, c::IntervalType]) - -Reverse addition. Calculates the preimage of `a = b + c` for `b` and `c`. - -### Output - -The triplet `(a, b_new, c_new)` where - -- `a` remains unchanged -- `b_new` is the interval hull of the set ``{x ∈ b : ∃ y ∈ c, x + y ∈ a}`` -- `c_new` is the interval hull of the set ``{y ∈ c : ∃ x ∈ b, x + y ∈ a}`` -""" -function plus_rev(a::IntervalType, b::IntervalType, c::IntervalType) # a = b + c - # a = a ⊓ (b + c) # add this line for plus contractor (as opposed to reverse function) - b_new = b ⊓ (a - c) - c_new = c ⊓ (a - b) - - return a, b_new, c_new -end - -plus_rev(a,b,c) = plus_rev(promote(a,b,c)...) - -""" - minus_rev(a::IntervalType, b::IntervalType[, c::IntervalType]) - -Reverse subtraction. Calculates the preimage of `a = b - c` for `b` and `c`. - -### Output - -The triplet `(a, b_new, c_new)` where - -- `a` remains unchanged -- `b_new` is the interval hull of the set ``{x ∈ b : ∃ y ∈ c, x - y ∈ a}`` -- `c_new` is the interval hull of the set ``{y ∈ c : ∃ x ∈ b, x - y ∈ a}`` -""" -function minus_rev(a::IntervalType, b::IntervalType, c::IntervalType) # a = b - c - - b_new = b ⊓ (a + c) - c_new = c ⊓ (b - a) - - return a, b_new, c_new -end - -minus_rev(a,b,c) = minus_rev(promote(a,b,c)...) - -function minus_rev(a::IntervalType, b::IntervalType) # a = -b - b_new = b ⊓ (-a) - return (a, b_new) -end - - -""" -Reverse multiplication -""" -function mul_rev(a::IntervalType, b::IntervalType, c::IntervalType) # a = b * c - - # ((0.0 ∉ a) || (0.0 ∉ b)) && (c = c ⊓ (a / b)) - # ((0.0 ∉ a) || (0.0 ∉ c)) && (b = b ⊓ (a / c)) - - # a = a ⊓ (b * c) # ? - - if in_interval(0.0, b) - temp = extended_div(a, b) - c′ = hull(c ⊓ temp[1], c ⊓ temp[2]) - - else - c′ = c ⊓ (a / b) - end - - if in_interval(0.0, c) - temp = extended_div(a, c) - b′ = hull(b ⊓ temp[1], b ⊓ temp[2]) - - else - b′ = b ⊓ (a / c) - end - - return a, b′, c′ -end - -mul_rev(a,b,c) = mul_rev(promote(a,b,c)...) - -""" -Reverse division -""" -function div_rev(a::IntervalType, b::IntervalType, c::IntervalType) # a = b / c - - b = b ⊓ (a * c) - c = c ⊓ (b / a) - - return a, b, c -end - -div_rev(a,b,c) = div_rev(promote(a,b,c)...) - -""" - inv_rev(a::IntervalType, b::IntervalType) - -Reverse inverse. Calculates the interval hull of the preimage of a = b⁻¹ - -### Output - -Pair `(a, b_new)` where - -- `a` is unchanged -- `b_new` is the interval hull of the set ``{x ∈ b : x⁻¹ ∈ a}`` -""" -function inv_rev(a::IntervalType, b::IntervalType) # a = inv(b) - - b_new = b ⊓ inv(a) - - return a, b_new -end - -inv_rev(a,b) = inv_rev(promote(a,b)...) - -""" - power_rev(a::IntervalType, b::IntervalType, n::Integer) - -Reverse power. Calculates the preimage of `a = bⁿ`. See section 10.5.4 of the -IEEE 1788-2015 standard for interval arithmetic. - -### Output - -The triplet `(a, b_new, n)` where - -- `a` and `n` are unchanged -- `b_new` is the interval hull of the set ``{x ∈ b : xⁿ ∈ a}`` -""" -function power_rev(a::IntervalType{T}, b::IntervalType{T}, n::Integer) where T # a = b^n, log(a) = inf(n)g(b), b = a^(1/n) - - if iszero(n) - in_interval(1.0, a) && return (a, entireinterval(T) ⊓ b, n) - return (a, emptyinterval(T), n) - end - - if n == 2 # a = b^2 - root = √a - b1 = b ⊓ root - b2 = b ⊓ (-root) - - elseif iseven(n) - root = a^(1//n) - - b1 = b ⊓ root - b2 = b ⊓ (-root) - - elseif isodd(n) - pos_root = (a ⊓ interval(0, Inf)) ^ (1//n) - neg_root = -( ( (-a) ⊓ (interval(0, Inf)) ) ^ (1//n) ) - - b1 = b ⊓ pos_root - b2 = b ⊓ neg_root - - end - - b = hull(b1, b2) - - return (a, b, n) -end - -power_rev(a::IntervalType{T}, n::Integer) where {T} = power_rev(a, entireinterval(T), n) - -function power_rev(a::IntervalType, b::IntervalType, c::IntervalType) # a = b^c - - if isthininteger(c) - temp = power_rev(a, b, Int(inf(c))) # use version with integer - return (temp[1], temp[2], interval(temp[3])) - end - - b_new = b ⊓ ( a^(inv(c) )) - c_new = c ⊓ (log(a) / log(b)) - - return a, b_new, c_new -end - -power_rev(a, b, c) = power_rev(promote(a, b, c)...) - - -""" - sqrt_rev(a::IntervalType, b::IntervalType) - -Reverse square root. Calculates the preimage of `a = √b`. - -### Output - -The pair `(a, b_new)` where - -- `a` is unchanged -- `b_new` is the interval hull of the set ``{x ∈ b : √x ∈ a}`` -""" -function sqrt_rev(a::IntervalType, b::IntervalType) # a = sqrt(b) - - b_new = b ⊓ (a^2) - - return a, b_new -end - -sqrt_rev(a,b) = sqrt_rev(promote(a,b)...) - - -# IEEE-1788 style - -""" - sqr_rev(c::IntervalType[, x::IntervalType]) - -Reverse square. Calculates the preimage of `a = x²`. If `x` is not provided, then -byt default ``[-Inf, Inf]`` is used. See section 10.5.4 of the IEEE 1788-2015 standard for interval arithmetic. - -### Output - -The pair `(c, x_new)` where - -- `c` is unchanged -- `x_new` is the interval hull of the set ``{x ∈ b : x² ∈ a}`` -""" -function sqr_rev(c, x = entireinterval(c)) # c = x^2; refine x - - root = sqrt(c) - - x1 = x ⊓ root - x2 = x ⊓ (-root) - - return (c, hull(x1, x2)) -end - -""" - abs_rev(c::IntervalType[, x::IntervalType]) - -Reverse absolute value. Calculates the preimage of `a = |x|`. If `x` is not provided, then -byt default ``[-Inf, Inf]`` is used. See section 10.5.4 of the IEEE 1788-2015 standard for interval arithmetic. - -### Output - -The pair `(c, x_new)` where - -- `c` is unchanged -- `x_new` is the interval hull of the set ``{x ∈ b : |x| ∈ a}`` -""" -function abs_rev(y, x = entireinterval(y)) # y = abs(x); refine x - - y_new = y ⊓ (interval(0, Inf)) - - x1 = y_new ⊓ x - x2 = -(y_new ⊓ (-x)) - - return (y, hull(x1, x2)) -end -#= -""" -Reverse sign -""" -function sign_rev(a::IntervalType, b::IntervalType) # a = sqrt(b) - - (a == 1.0) && b = b ⊓ (interval(0, Inf)) - (a == 0.0) && b = b ⊓ (0.interval(0, 0).0) - (a == -1.0) && b = b ⊓ (-interval(Inf, 0).0) - - return a, b -end -sign_rev(a,b) = sign_rev(promote(a,b)...) -=# - -## IEEE-1788 versions: - -""" - mul_rev_IEEE1788(b::IntervalType, c::IntervalType[, x::IntervalType]) - -Reverse multiplication. Computes the preimage of ``c = x * b`` with respect to `x`. -If `x` is not provided, then by default ``[-Inf, Inf]`` is used. -See section 10.5.4 of the IEEE 1788-2015 standard for interval arithmetic. - -### Output - -- `x_new` the interval hull of the set ``{t ∈ x : ∃ y ∈ b, t*y ∈ c} -""" -mul_rev_IEEE1788(b, c, x = entireinterval(b)) = mul_rev(c, x, b)[2] - -""" - pow_rev1(b::IntervalType, c::IntervalType[, x::IntervalType]) - -Reverse power 1. Computes the preimage of ``c=xᵇ`` with respect to `x`. If `x` is not provided, -then byt default ``[-Inf, Inf]`` is used.. See section 10.5.4 of the -IEEE 1788-2015 standard for interval arithmetic. - -### Output - -- `x_new` the interval hull of the set ``{t ∈ x : ∃ y ∈ b, tʸ ∈ c} -""" -function pow_rev1(b, c, x) # c = x^b - return x ⊓ c^(1/b) # replace by 1//b -end - -""" - pow_rev2(b::IntervalType, c::IntervalType[, x::IntervalType]) - -Reverse power 2. Computes the preimage of ``c = aˣ`` with respect to `x`. If `x` is not provided, then -byt default ``[-Inf, Inf]`` is used. See section 10.5.4 of the IEEE 1788-2015 standard for interval arithmetic. - -### Output - -- `x_new` the interval hull of the set ``{t ∈ x : ∃ y ∈ b, tʸ ∈ c} -""" -function pow_rev2(a, c, x) # c = a^x - return x ⊓ (log(c) / log(a)) -end - -""" - mul_rev_to_pair(b::IntervalType, c::IntervalType) - -Computes the division c / b, but returns a pair of intervals instead of a single interval. -If the set corresponding to c / b is composed of two disjoint intervals, then it returns the -two intervals. If c / b is a single or empty interval, then the second interval in the pair -is set to empty. -See section 10.5.5 of the IEEE 1788-2015 standard for interval arithmetic. - -### Example - -```jldoctest -julia> mul_rev_to_pair(-interval(1, 1), interval(1, 2)) -([-Inf, -1], [1, Inf]) - -julia> mul_rev_to_pair(interval(1, 2), interval(3, 4)) -([1.5, 4], emptyinterval()) - -""" -mul_rev_to_pair(b::IntervalType, c::IntervalType) = extended_div(c, b) diff --git a/src/decorated.jl b/src/decorated.jl deleted file mode 100644 index 121b1d9..0000000 --- a/src/decorated.jl +++ /dev/null @@ -1,35 +0,0 @@ -entiredecorated(T) = Decoratedinterval(entireinterval(T)) - -for op in (:sqr_rev, :abs_rev, :sin_rev, :cos_rev, :tan_rev, :cosh_rev, :sinh_rev, :tanh_rev) - @eval begin - function $op(a::DecoratedInterval{T}, x::DecoratedInterval{T}) where T - ( isnai(a) || isnai(x) ) && return nai(T) - bare = $op(interval(a), interval(x)) - return (Decoratedinterval(bare[1], trv), Decoratedinterval(bare[2], trv)) - end - end - @eval $op(a::IntervalType{T}) where T = $op(a, entireinterval(T)) - @eval $op(a::DecoratedInterval{T}) where T = $op(a, entiredecorated(T)) -end - -function power_rev(a::DecoratedInterval{T}, x::DecoratedInterval{T}, n::Integer) where T - ( isnai(a) || isnai(x) ) && return nai(T) - bare = power_rev(interval(a), interval(x), n) - return (Decoratedinterval(bare[1], trv), Decoratedinterval(bare[2], trv), n) -end - -power_rev(a::DecoratedInterval{T}, n::Integer) where T = power_rev(a, entiredecorated(T), n) - -for op in (:mul_rev_IEEE1788, :pow_rev1, :pow_rev2) - @eval begin - function $op(b::DecoratedInterval{T}, c::DecoratedInterval{T}, x::DecoratedInterval{T}) where T - (isnai(b) || isnai(c) || isnai(x) ) && return nai(T) - bare = $op(interval(b), interval(c), interval(x)) - return Decoratedinterval(bare, trv) - end - end - - @eval $op(a::IntervalType{T}, b::IntervalType{T}) where T = $op(a, b, entireinterval(T)) - @eval $op(a::DecoratedInterval{T}, b::DecoratedInterval{T}) where T = $op(a, b, entiredecorated(T)) - -end \ No newline at end of file diff --git a/src/deprecations.jl b/src/deprecations.jl new file mode 100644 index 0000000..82a47c4 --- /dev/null +++ b/src/deprecations.jl @@ -0,0 +1,73 @@ +# Deprecation shims forwarding every reverse function to its +# `IntervalArithmetic` equivalent. This file is included last by the +# `IntervalContractors` module, so the definitions here override the +# implementations in the per-domain files (`arithmetic.jl`, +# `exponential.jl`, …). Method-redefinition warnings during precompile +# are expected. +# +# IC's API conventions diverge from IA's in two places, so the shims are +# split into three groups: +# +# 1. Names and shapes match IA → use `@deprecate`. +# 2. `mul_rev(a, b, c)` collides with IA's IEEE 1788 `mul_rev(b, c, x)`; +# the IC tuple-rewrite multiplication forwards to `IA.times_rev`. +# 3. The 2-argument reverses (`f_rev(c, x)`) returned `(c, x_new)` in IC +# but return just `x_new` in IA. Manual shims wrap the IA result back +# into IC's tuple shape and emit `Base.depwarn`. + +# ----- 1. Tuple-rewriting reverses with matching IA names ----- +@deprecate plus_rev(a, b, c) IntervalArithmetic.plus_rev(a, b, c) +@deprecate minus_rev(a, b, c) IntervalArithmetic.minus_rev(a, b, c) +@deprecate minus_rev(a, b) IntervalArithmetic.minus_rev(a, b) +@deprecate div_rev(a, b, c) IntervalArithmetic.div_rev(a, b, c) +@deprecate power_rev(a, b, n::Integer) IntervalArithmetic.power_rev(a, b, n) +@deprecate power_rev(a, n::Integer) IntervalArithmetic.power_rev(a, n) +@deprecate power_rev(a, b, c) IntervalArithmetic.power_rev(a, b, c) +@deprecate max_rev(a, b, c) IntervalArithmetic.max_rev(a, b, c) +@deprecate min_rev(a, b, c) IntervalArithmetic.min_rev(a, b, c) + +# ----- 2. Renamed: IC's `mul_rev` (3-arg) → IA's `times_rev` ----- +@deprecate mul_rev(a, b, c) IntervalArithmetic.times_rev(a, b, c) + +# Single-output extras, same name and shape on IA +@deprecate mul_rev_to_pair(b, c) IntervalArithmetic.mul_rev_to_pair(b, c) +@deprecate pow_rev1(b, c) IntervalArithmetic.pow_rev1(b, c) +@deprecate pow_rev1(b, c, x) IntervalArithmetic.pow_rev1(b, c, x) +@deprecate pow_rev2(a, c) IntervalArithmetic.pow_rev2(a, c) +@deprecate pow_rev2(a, c, x) IntervalArithmetic.pow_rev2(a, c, x) + +# IC's `mul_rev_IEEE1788` is exactly IA's IEEE 1788 `mul_rev` +@deprecate mul_rev_IEEE1788(b, c) IntervalArithmetic.mul_rev(b, c) +@deprecate mul_rev_IEEE1788(b, c, x) IntervalArithmetic.mul_rev(b, c, x) + +# ----- 3. 2-arg tuple-returning reverses where IA returns a single value ----- + +# IC's `inv_rev(a, b)` returned `(a, b ∩ inv(a))`; IA's returns just the +# tightened `x`. Manual shim preserves the tuple. +function inv_rev(a, b) + Base.depwarn( + "`IntervalContractors.inv_rev(a, b)` returning `(a, b')` is deprecated; " * + "use `IntervalArithmetic.inv_rev(c, x)` (returns the tightened `x` directly).", + :inv_rev) + return (a, IntervalArithmetic.inv_rev(a, b)) +end + +for name in ( + :sqr_rev, :abs_rev, :sign_rev, :sqrt_rev, + :exp_rev, :exp2_rev, :exp10_rev, :expm1_rev, + :log_rev, :log2_rev, :log10_rev, :log1p_rev, + :sin_rev, :cos_rev, :tan_rev, + :asin_rev, :acos_rev, :atan_rev, + :sinh_rev, :cosh_rev, :tanh_rev, + :asinh_rev, :acosh_rev, :atanh_rev, +) + msg = "`IntervalContractors.$(name)(c, x)` returning `(c, x')` is deprecated; " * + "use `IntervalArithmetic.$(name)(c, x)` (returns the tightened `x` directly)." + @eval begin + function $name(c, x) + Base.depwarn($msg, $(QuoteNode(name))) + return (c, IntervalArithmetic.$name(c, x)) + end + $name(c) = $name(c, IntervalArithmetic.entireinterval(typeof(c))) + end +end diff --git a/src/exponential.jl b/src/exponential.jl deleted file mode 100644 index 483b1fe..0000000 --- a/src/exponential.jl +++ /dev/null @@ -1,94 +0,0 @@ -function exp!(X::IntervalBox) - x, y = X - - y = y ⊓ exp(x) - x = x ⊓ log(y) - - return IntervalBox(x, y) -end - -""" -Reverse function for `exp`. -""" -function exp_rev(y::IntervalType, x::IntervalType) - y_new = y ⊓ (interval(0, Inf)) - x_new = x ⊓ log(y) - return y_new, x_new -end - -""" -Reverse function for `exp2`. -""" -function exp2_rev(y::IntervalType, x::IntervalType) - y_new = y ⊓ (interval(0, Inf)) - x_new = x ⊓ log2(y) - - return y_new, x_new -end - -""" -Reverse function for `exp10`. -""" -function exp10_rev(y::IntervalType, x::IntervalType) - y_new = y ⊓ (interval(0, Inf)) - x_new = x ⊓ log10(y) - - return y_new, x_new -end - -""" -Reverse function for `expm1`. -""" -function expm1_rev(y::IntervalType, x::IntervalType) - y_new = y ⊓ (interval(-1, Inf)) - x_new = x ⊓ log1p(y) - - return y_new, x_new -end - - -function log!(X::IntervalBox) # y = log(x) - x, y = X - - x = x ⊓ exp(y) - y = y ⊓ log(x) - - return IntervalBox(x, y) -end - -""" -Reverse function for `log`: ``y = \\log(x)`` -""" -function log_rev(y::IntervalType, x::IntervalType) - x_new = x ⊓ exp(y) - - return y, x_new -end - -""" -Reverse function for `log2`: ``y = \\log2(x)`` -""" -function log2_rev(y::IntervalType, x::IntervalType) - x_new = x ⊓ exp2(y) - - return y, x_new -end - - -""" -Reverse function for `log10`: ``y = \\log10(x)`` -""" -function log10_rev(y::IntervalType, x::IntervalType) - x_new = x ⊓ exp10(y) - - return y, x_new -end - -""" -Reverse function for `log1p`: ``y = \\log1p(x)`` -""" -function log1p_rev(y::IntervalType, x::IntervalType) - x_new = x ⊓ expm1(y) - - return y, x_new -end diff --git a/src/extrema.jl b/src/extrema.jl deleted file mode 100644 index 30263fc..0000000 --- a/src/extrema.jl +++ /dev/null @@ -1,46 +0,0 @@ -""" -Reverse max -""" -function max_rev(a::IntervalType, b::IntervalType, c::IntervalType) # a = max(b,c) - - B_lo = inf(b); B_hi = sup(b); - C_lo = inf(c); C_hi = sup(c); - - (inf(b) > sup(c)) && (B_lo = max(inf(b),inf(a))) - (inf(b) < inf(c)) && (C_lo = max(inf(c),inf(a))) - (sup(b) > sup(c)) && (B_hi = min(sup(b),sup(a))) - (sup(b) < sup(c)) && (C_hi = min(sup(c),sup(a))) - - if isempty_interval(b) - isempty_interval(c) && (return a, emptyinterval(), emptyinterval()) - return a, emptyinterval(), interval(C_lo,C_hi) - else - isempty_interval(c) && (return a, interval(B_lo,B_hi), emptyinterval()) - return a, interval(B_lo,B_hi), interval(C_lo,C_hi) - end -end -max_rev(a,b,c) = max_rev(promote(a,b,c)...) - -""" -Reverse min -""" -function min_rev(a::IntervalType, b::IntervalType, c::IntervalType) - - B_lo = inf(b); B_hi = sup(b); - C_lo = inf(c); C_hi = sup(c); - - (inf(b) > inf(c)) && (B_lo = max(inf(c),inf(a))) - (inf(b) < inf(c)) && (C_lo = max(inf(b),inf(a))) - (sup(b) > sup(c)) && (B_hi = min(sup(c),sup(a))) - (sup(b) < sup(c)) && (C_hi = min(sup(b),sup(a))) - - if isempty_interval(b) - isempty_interval(c) && (return a, emptyinterval(), emptyinterval()) - return a, emptyinterval(), interval(C_lo,C_hi) - else - isempty_interval(c) && (return a, interval(B_lo,B_hi), emptyinterval()) - return a, interval(B_lo,B_hi), interval(C_lo,C_hi) - end -end - -min_rev(a,b,c) = min_rev(promote(a,b,c)...) diff --git a/src/hyperbolic.jl b/src/hyperbolic.jl deleted file mode 100644 index b795f4d..0000000 --- a/src/hyperbolic.jl +++ /dev/null @@ -1,58 +0,0 @@ -""" - sinh_rev(c::IntervalType[, x::IntervalType]) - -Reverse hyperbolic sine. Calculates the preimage of `a = sinh(x)`. If `x` is not provided, then -byt default ``[-Inf, Inf]`` is used. See section 10.5.4 of the IEEE 1788-2015 standard for interval arithmetic. - -### Output - -The pair `(c, x_new)` where - -- `c` is unchanged -- `x_new` is the interval hull of the set ``{x ∈ b : sinh(x) ∈ a}`` -""" -function sinh_rev(y::IntervalType, x::IntervalType = entireinterval(y)) - x = x ⊓ asinh(y) - - return y, x -end - -""" - cosh_rev(c::IntervalType[, x::IntervalType]) - -Reverse square root. Calculates the preimage of `a = cosh(x)`. If `x` is not provided, then -byt default ``[-Inf, Inf]`` is used. See section 10.5.4 of the IEEE 1788-2015 standard for interval arithmetic. - -### Output - -The pair `(c, x_new)` where - -- `c` is unchanged -- `x_new` is the interval hull of the set ``{x ∈ b : cosh(x) ∈ a}`` -""" -function cosh_rev(y::IntervalType, x::IntervalType = entireinterval(y)) - y_new = y ⊓ interval(1.,Inf) - x = (x ⊓ acosh(y)) ⊔ (x ⊓ -acosh(y)) - - return y_new, x -end - -""" - tanh_rev(c::IntervalType[, x::IntervalType]) - -Reverse square root. Calculates the preimage of `a = tanh(x)`. If `x` is not provided, then -byt default ``[-Inf, Inf]`` is used. See section 10.5.4 of the IEEE 1788-2015 standard for interval arithmetic. - -### Output - -The pair `(c, x_new)` where - -- `c` is unchanged -- `x_new` is the interval hull of the set ``{x ∈ b : tanh(x) ∈ a}`` -""" -function tanh_rev(y::IntervalType, x::IntervalType = entireinterval(y)) - y_new = y ⊓ interval(-1.,1.) - x = x ⊓ atanh(y) - - return y_new, x -end diff --git a/src/inverse_hyperbolic.jl b/src/inverse_hyperbolic.jl deleted file mode 100644 index e1c182d..0000000 --- a/src/inverse_hyperbolic.jl +++ /dev/null @@ -1,27 +0,0 @@ -""" -Reverse function for `asinh`. -""" -function asinh_rev(y::IntervalType, x::IntervalType = entireinterval(y)) - x = x ⊓ sinh(y) - - return y, x -end - -""" -Reverse function for `acosh`. -""" -function acosh_rev(y::IntervalType, x::IntervalType = entireinterval(y)) - y_new = y ⊓ interval(0.0,Inf) - x = x ⊓ cosh(y) - - return y_new, x -end - -""" -Reverse function for `atanh`. -""" -function atanh_rev(y::IntervalType, x::IntervalType = entireinterval(y)) - x = x ⊓ tanh(y) - - return y, x -end diff --git a/src/inverse_trig.jl b/src/inverse_trig.jl deleted file mode 100644 index 7ea40d1..0000000 --- a/src/inverse_trig.jl +++ /dev/null @@ -1,45 +0,0 @@ -function asin!(X::IntervalBox) - x, y = X - - h = inf(half_pi(y)) - y_new = y ⊓ interval(-h, h) # range of asin - x_new = sin(y_new) - - return IntervalBox(x_new, y_new) -end - -""" -Reverse `asin`. -""" -function asin_rev(y::IntervalType, x::IntervalType = entireinterval(y)) # y = asin(x) - h = inf(half_pi(y)) - y_new = y ⊓ interval(-h, h) # range of asin - - x_new = sin(y_new) - - return y_new, x_new # return in order y, x -end - -""" -Reverse `acos`. -""" -function acos_rev(y::IntervalType, x::IntervalType = entireinterval(y)) - y_new = y ⊓ interval(0.0, sup(two_pi(y))) - x_new = x ⊓ cos(y_new) - - return y_new, x_new -end - -""" - atan_rev(y::IntervalType, x::IntervalType) - -Inverse of `y = atan(x)`. -Returns the new `y` and `x`. -""" -function atan_rev(y::IntervalType, x::IntervalType = entireinterval(y)) - h = sup(half_pi(y)) - y_new = y ⊓ interval(-h, h) - x_new = x ⊓ tan(y_new) - - return y_new, x_new -end diff --git a/src/pave.jl b/src/pave.jl deleted file mode 100644 index 1b6145f..0000000 --- a/src/pave.jl +++ /dev/null @@ -1,30 +0,0 @@ -"Outer paving with a contractor C" - -function outer_pave{N,T}(C, working::Vector{IntervalBox{N,T}}, ϵ) - - outer_list = SubPaving{N,T}() - - while !isempty_interval(working) - - X = pop!(working) - - contracted = C(X) - - if isempty_interval(contracted) - continue - end - - if diam(contracted) < ϵ - push!(outer_list, contracted) - - else - push!(working, bisect(contracted)...) - end - - end - - return outer_list - -end - -outer_pave(C, X, ϵ) = outer_pave(C, [X], ϵ) diff --git a/src/powers.jl b/src/powers.jl deleted file mode 100644 index 20db535..0000000 --- a/src/powers.jl +++ /dev/null @@ -1,39 +0,0 @@ - -function constant_contractor(X, y_val) - x, y = X - y = y ⊓ interval(y_val) - return IntervalBox(x, y) -end - - -"Contractor for y = x^2, x >= 0" -function square_pos(X::IntervalBox) - - x, y = X - - x = x ⊓ (interval(0, Inf)) - - y = y ⊓ (x^2) - x = x ⊓ √y - - return IntervalBox(x, y) -end - -square_neg = symmetrise(square_pos, reflect_x(zero)) -square!(X::IntervalBox) = square_pos(X) ⊔ square_neg(X) - - -function cube_pos(X::IntervalBox) # contractor for y=x^3, x>=0 - - x, y = X - - x = x ⊓ (interval(0, Inf)) - - y = y ⊓ (x ^ 3) - x = x ⊓ interval(inf(y) ^ (1/3), sup(y)^(1/3)) # not rigorous! - - return x × y -end - -cube_neg = symmetrise(cube_pos, odd) -cube!(X::IntervalBox) = cube_pos(X) ⊔ cube_neg(X) diff --git a/src/transformations.jl b/src/transformations.jl deleted file mode 100644 index d5bc818..0000000 --- a/src/transformations.jl +++ /dev/null @@ -1,88 +0,0 @@ - -""" - integer_contractor(x::IntervalType) - -Return the integers enclosed in the interval `x`. -""" - -function integer_contractor(x::IntervalType) - a = floor(inf(x)) + 1 - b = floor(sup(x)) - - a > b && return emptyinterval(x) - - return _build_interval(x, a, b) -end - - -### Transformations on IntervalBoxes - -"""Reflect in mirror at position x_mirror -x_mirror is a function that returns an interval giving the position of the mirror.""" -function reflect_x(x_mirror) - X -> begin - x, y = X - x = (exact(2) * x_mirror(x)) - x - - return IntervalBox(x, y) - end -end - - -""" - translate(α) - -Returns a function that shifts (translates) a 2D `IntervalBox` in `x` (the first coordinate). -""" -function translate(α) - X -> begin - x, y = X - return IntervalBox(x - α, y) - end -end - -odd(X::IntervalBox) = ( (x,y) = X; IntervalBox(-x, -y) ) - - - -## Transformations on Contractors - -""" -Translation of a Contractor `C` by `α`. -Uses `inv(op) ∘ C ∘ op` -""" -translate(C, α) = translate(-α) ∘ C ∘ translate(α) - - -""" -Symmetric part of a Contractor, via an involution `op` -(i.e. such that `inv(op) == op`). -""" -symmetrise(C, op) = op ∘ C ∘ op - - - - -"Periodize the contractor C. period is a function that returns an interval giving the period" -function periodise(C, period) - - X -> begin - x, y = X - - x2 = entireinterval(x) - x2, y = C(IntervalBox(x2, y)) - - isempty(IntervalBox(x2, y)) && return(IntervalBox(emptyinterval(x), emptyinterval(x))) - - # periods where the periodization of x intersects with x2: - periods = integer_contractor((x - x2) / period(x)) - - isempty_interval(periods) && return(IntervalBox(emptyinterval(x), emptyinterval(x))) - - x3 = x2 + periods * period(x) - x = x ⊓ x3 - - return IntervalBox(x, y) - end - -end diff --git a/src/trig.jl b/src/trig.jl deleted file mode 100644 index 77214c1..0000000 --- a/src/trig.jl +++ /dev/null @@ -1,173 +0,0 @@ - - -## sin contractor: alters x and y -""" -Contractor for "main branch" of sin, from x = -π/2 to π/2. -""" -function sin_main(X::IntervalBox) - - x, y = X - - h = sup(half_pi(x)) - - x_range = _build_interval(x, -h, h) - y_range = _build_interval(x, -1, 1) - - x = x ⊓ x_range - y = y ⊓ y_range - - isempty(IntervalBox(x, y)) && return IntervalBox(x, y) - - y = y ⊓ sin(x) - x = x ⊓ asin(y) - - return IntervalBox(x, y) - -end - -# TODO: Be careful with the pi constants if using e.g. BigFloats -sin_reverse = symmetrise(sin_main, reflect_x(half_pi)) - -""" - sin!(X::IntervalBox) - -Contractor for `sin`. -Takes an `IntervalBox` containing the `x` and `y` component intervals. -Returns an `IntervalBox` contracted down to the set ``y = \\sin(x)``. -""" -sin!(X::IntervalBox) = periodise(sin_main, two_pi)(X) ⊔ periodise(sin_reverse, two_pi)(X) - -# Reverse function for sin; does not alter y -""" - sin_rev(c::IntervalType[, x::IntervalType]) - -Reverse sine. Calculates the preimage of `a = sin(x)`. If `x` is not provided, then -byt default ``[-Inf, Inf]`` is used. See section 10.5.4 of the IEEE 1788-2015 standard for interval arithmetic. - -### Output - -The pair `(c, x_new)` where - -- `c` is unchanged -- `x_new` is the interval hull of the set ``{x ∈ b : sin(x) ∈ a}`` -""" -function sin_rev(y::IntervalType, x::IntervalType = entireinterval(y)) - - X = IntervalBox(x, y) - - X_new = sin!(X) - - return X_new[2], X_new[1] # return in order y, x -end - - -## cos contractor: alters x and y -""" -Contractor for main branch of cos, from x = 0 to π. -""" -function cos_main(X::IntervalBox) - - x, y = X - - x_range = _build_interval(x, 0, inf(pi_interval(x))) - y_range = _build_interval(x, -1, 1) - - x = x ⊓ x_range - y = y ⊓ y_range - - isempty(IntervalBox(x, y)) && return IntervalBox(x, y) - - y = y ⊓ cos(x) - x = x ⊓ acos(y) - - return IntervalBox(x, y) - -end - -# TODO: Be careful with the pi constants if using e.g. BigFloats -cos_reverse = symmetrise(cos_main, reflect_x(zero)) - -""" - cos!(X::IntervalBox) - -Contractor for `cos`. -Takes an `IntervalBox` containing the `x` and `y` component intervals. -Returns an `IntervalBox` contracted down to the set ``y = \\cos(x)``. -""" -cos!(X::IntervalBox) = periodise(cos_main, two_pi)(X) ⊔ periodise(cos_reverse, two_pi)(X) - - -# Reverse function for cos; does not alter y -""" - cos_rev(c::IntervalType[, x::IntervalType]) - -Reverse cosine. Calculates the preimage of `a = cos(x)`. If `x` is not provided, then -byt default ``[-Inf, Inf]`` is used. See section 10.5.4 of the IEEE 1788-2015 standard for interval arithmetic. - -### Output - -The pair `(c, x_new)` where - -- `c` is unchanged -- `x_new` is the interval hull of the set ``{x ∈ b : cos(x) ∈ a}`` -""" -function cos_rev(y::IntervalType, x::IntervalType = entireinterval(y)) - - X = IntervalBox(x, y) - - X_new = cos!(X) - - return X_new[2], X_new[1] # return in order y, x -end - - -""" -Contractor for "main branch" of tan, from x = -π/2 to π/2. -""" -function tan_main(X::IntervalBox) - - x, y = X - - h = sup(half_pi(x)) - - x_range = _build_interval(x, -h, h) - - x = x ⊓ x_range - - isempty_interval(x) && return IntervalBox(x, y) - - y = y ⊓ tan(x) - x = x ⊓ atan(y) - - return IntervalBox(x, y) - -end - -tan!(X::IntervalBox) = periodise(tan_main, pi_interval)(X) - -""" - tan_rev(c::IntervalType[, x::IntervalType]) - -Reverse tangent. Calculates the preimage of `a = tan(x)`. If `x` is not provided, then -byt default ``[-Inf, Inf]`` is used. See section 10.5.4 of the IEEE 1788-2015 standard for interval arithmetic. - -### Output - -The pair `(c, x_new)` where - -- `c` is unchanged -- `x_new` is the interval hull of the set ``{x ∈ b : tan(x) ∈ a}`` -""" -function tan_rev(y::IntervalType, x::IntervalType = entireinterval(y)) - - X = IntervalBox(x, y) - - X_new = tan!(X) - - return X_new[2], X_new[1] # return in order y, x -end - - -# build an interval of the corresponding type: -_build_interval(x::Interval, a, b) = interval(a, b) -_build_interval(x::BareInterval, a, b) = bareinterval(a, b) \ No newline at end of file diff --git a/test/Non1788tests/extrema.jl b/test/Non1788tests/extrema.jl index 3df56a0..30931f3 100644 --- a/test/Non1788tests/extrema.jl +++ b/test/Non1788tests/extrema.jl @@ -5,7 +5,10 @@ using IntervalArithmetic using IntervalContractors @testset "max_rev_test" begin - @test eq(max_rev(emptyinterval(), entireinterval(Float64),entireinterval(Float64))[2], interval(-Inf, Inf)) + # IC's old `max_rev(empty, entire, entire)` returned `(empty, entire, entire)`, + # i.e. `[2] == entire`. IA correctly returns `(empty, empty, empty)` since an + # empty `a` is an unsatisfiable constraint. + @test_broken eq(max_rev(emptyinterval(), entireinterval(Float64),entireinterval(Float64))[2], interval(-Inf, Inf)) @test eq(max_rev(interval(0.0, 1.0), emptyinterval(),interval(-2.0, -1.0))[2], emptyinterval()) @test eq(max_rev(emptyinterval(), interval(0.0, 1.0),interval(-2.0, -1.0))[2], emptyinterval()) @test eq(max_rev(interval(-2.0, -1.0), entireinterval(Float64),interval(-3.0, -2.0))[2], interval(-Inf, -1.0)) @@ -15,7 +18,8 @@ using IntervalContractors end @testset "min_rev_test" begin - @test eq(min_rev(emptyinterval(), entireinterval(Float64),entireinterval(Float64))[2], interval(-Inf, Inf)) + # See `max_rev_test` above: empty `a` ⇒ empty preimage, not entire. + @test_broken eq(min_rev(emptyinterval(), entireinterval(Float64),entireinterval(Float64))[2], interval(-Inf, Inf)) @test eq(min_rev(interval(0.0, 1.0), emptyinterval(), interval(-2.0, -1.0))[2], emptyinterval()) # should return empty?) @test eq(min_rev(emptyinterval(), interval(0.0, 1.0),interval(-2.0, -1.0))[2], emptyinterval()) @test eq(min_rev(interval(-2.0, -1.0), entireinterval(Float64),interval(-3.0, -2.0))[2], interval(-Inf, -2.0)) diff --git a/test/Non1788tests/inv_hyperbolic.jl b/test/Non1788tests/inv_hyperbolic.jl index 54369be..f035e2e 100644 --- a/test/Non1788tests/inv_hyperbolic.jl +++ b/test/Non1788tests/inv_hyperbolic.jl @@ -18,7 +18,10 @@ end @test eq(acosh_rev(interval(0.0, Inf), entireinterval())[2], interval(1.0, Inf)) @test approx_eq(acosh_rev(interval(0.0, 1.0), entireinterval())[2], interval(1.0, 1.54309)) @test approx_eq(acosh_rev(interval(-0.5, 1.0), entireinterval())[2], interval(1.0, 1.54309)) - @test eq(acosh_rev(interval(-1000.0, 1.0), entireinterval())[2], interval(1.0, Inf)) + # IA's `acosh_rev` clips `c` to `[0, ∞)` (acosh's range) before applying + # `cosh`, giving the correct (tight) preimage `[1, cosh(1)]`. IC's old + # impl was looser and returned `[1, ∞]`. + @test_broken eq(acosh_rev(interval(-1000.0, 1.0), entireinterval())[2], interval(1.0, Inf)) end @testset "atanh_rev_test" begin diff --git a/test/libieeep1788_rev.jl b/test/libieeep1788_rev.jl index 1110326..6741e19 100644 --- a/test/libieeep1788_rev.jl +++ b/test/libieeep1788_rev.jl @@ -1058,7 +1058,8 @@ end @test eq(cos_rev(interval(1.0,1.0), interval(-0.1,0.1))[2], interval(0.0,0.0)) - @test eq(cos_rev(interval(-1.0,-1.0), interval(3.14,3.15))[2], interval(0x1.921fb54442d18p+1,0x1.921fb54442d1ap+1)) + # IA's `cos_rev` returns a bound that differs by a few ulps from IC's old result. + @test_broken eq(cos_rev(interval(-1.0,-1.0), interval(3.14,3.15))[2], interval(0x1.921fb54442d18p+1,0x1.921fb54442d1ap+1)) @test eq(cos_rev(interval(0x1.1A62633145C06P-54,0x1.1A62633145C07P-54), interval(1.57,1.58))[2], interval(0x1.921FB54442D17P+0,0x1.921FB54442D19P+0)) diff --git a/test/runtests.jl b/test/runtests.jl index acbb686..d4504f4 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,6 +4,25 @@ using Test using IntervalContractors: IntervalType +# `IntervalContractors` and `IntervalArithmetic` now export the same reverse +# function names (every IC reverse forwards to its IA equivalent via a +# deprecation shim). `using` both makes those names ambiguous, so resolve +# them explicitly to the IC shims here in the test file. The shims emit +# `Base.depwarn` (silenced via `--depwarn=no` in the test driver). +using IntervalContractors: + plus_rev, minus_rev, inv_rev, + mul_rev, div_rev, power_rev, + sign_rev, max_rev, min_rev, + sqr_rev, sqrt_rev, abs_rev, + exp_rev, exp2_rev, exp10_rev, expm1_rev, + log_rev, log2_rev, log10_rev, log1p_rev, + sin_rev, cos_rev, tan_rev, + asin_rev, acos_rev, atan_rev, + sinh_rev, cosh_rev, tanh_rev, + asinh_rev, acosh_rev, atanh_rev, + mul_rev_IEEE1788, mul_rev_to_pair, + pow_rev1, pow_rev2 + # assume that default power mode is "fast" @assert IntervalArithmetic.default_power() == IntervalArithmetic.PowerMode{:fast}()