Repository navigation
Fix #790 - #791
Merged
Merged
Fix #790#791
Conversation
Any interval at least as wide as π contains a pole of tan and cot, so the result must be the whole line. The check used > instead of >=, so an interval of width exactly the upper bound of π, such as [-RU(π), 0], got a finite result that missed the pole. Part of JuliaIntervals#790. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
acot and acoth are computed as atan(1/x) and atanh(1/x). Both atan and atanh are increasing, so the lower bound needs 1/x rounded down and the upper bound needs 1/x rounded up. The two directions were swapped, so some results excluded the true value. Part of JuliaIntervals#790. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
acoth is defined for |x| > 1, so its result on an interval is the range over the part of the interval outside [-1, 1]. Intervals such as [0.5, 2] returned the empty set instead of [acoth(2), Inf), and intervals such as [-1, 2] returned the whole line although -1 is not in the domain. The tests that recorded the empty set are updated. Part of JuliaIntervals#790. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The interval enclosures of π, γ, catalan, ℯ and φ were computed at the current BigFloat precision. They are cached on first use, so a low precision at that moment, for example setprecision(BigFloat, 20), gave a loose Float64 π for the rest of the session. sin and cos rely on the tightest π and then returned wrong results. Part of JuliaIntervals#790. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Benchmark Results (Julia v1)Time benchmarks
Memory benchmarks
|
To find where x lies relative to multiples of π/2, 2x was computed in the type of x. For |x| > floatmax/2 this overflows to Inf and the functions threw an error. Now x is converted exactly to BigFloat and doubled there, which is exact and cannot overflow. Part of JuliaIntervals#790. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
π was taken with 256 bits to find where x lies relative to multiples of π/2. For large x this is not enough, and the result could be the whole range, for example tan(interval(0x1.117203831ce2fp+626)) with a BigFloat precision of 1000, or tan(interval(0x1.3c0ca428c59fbp+255)) at the default precision. The number of bits is now the exponent of x plus its precision plus 64, which is enough for every Float16, Float32 and Float64. Part of JuliaIntervals#790. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With set_zero_subnormals(true), tiny results become zero, so for example exp(interval(-745.0)) gives [0, 0] although exp(-745) > 0. This is a per-thread processor setting that IntervalArithmetic cannot check cheaply, so it is documented instead. Part of JuliaIntervals#790. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The enclosures of π, ℯ and the other constants are cached on first use.
This is fine for Float64 and similar types, whose precision is fixed,
but the bounds of a Rational{BigInt} constant come from a BigFloat at
the current precision. They stayed at the precision of the first call,
like BigFloat used to before it got its own method. Rational{BigInt}
now uses that method too.
Part of JuliaIntervals#790.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #790.
One commit per item of the issue:
tanandcotreturned a bounded result for an interval of width exactlysup(π)containing a pole (>→≥).secandcscwere already correct.acotandacothrounded1/xin the wrong direction, so some results excluded the true value.acothreturned∅for intervals partly inside[-1, 1](e.g.[0.5, 2]), and the whole line for[-1, 2]. The tests that recorded∅are updated.setprecisionat first use no longer gives a loose Float64 π, which madesin/coswrong. A second commit stops cachingRational{BigInt}constants, whose precision follows the global setting.set_zero_subnormals(true).sin,cos,tan,cot,secandcscthrew an error for|x| > floatmax/2, because2xoverflowed.xis now doubled exactly in BigFloat.exponent(x) + precision(x) + 64bits. That makes the reduction exact for every Float16, Float32 and Float64, checked against the closest case for each type.Follow-up (separate PR): reworking the trig range reduction, which still gives wrong results when the global BigFloat precision is low or when BigFloat bounds are more precise than the global setting;
cot/sec/cscmethods forInterval; andsinpi/cospiwith high-precision BigFloat bounds.🤖 Generated with Claude Code