Skip to content

Interval ​

Arithmetic over compute-engine's native Interval(a, b) -- extended in place by @enumeratio/analytic, since compute-engine declares it only as a real set with no arithmetic of its own. A result contains every value the operation takes on its inputs.

Interval(a, b)the real interval [a, b], carried through arithmetic and the elementary and special functions: each result encloses the true image.
SymPyAccumBounds(a, b)
Typed signatures
TypePackageApplies
(number, number) -> set<real>compute-enginealways

Domain: Interval arithmetic

Details
  • Rigorous containment, as Wolfram's Interval promises: an exact endpoint is exactly right, and an inexact one is rounded outward -- a lower bound down, an upper bound up. Decimal arithmetic is exact in compute-engine, so Interval(1.4, 1.5) + 1 is exactly Interval(2.4, 2.5); a function value at an inexact point is rounded one double outward from its value at working precision.
  • A function's image is its least and greatest value at the endpoints and at every critical point inside. Sin, Cos, Tan, Cot, Sec and Csc enumerate theirs period by period; Arcsin, Arccos, Arctan, Sinh, Cosh, Tanh, Exp, Ln, Log, Sqrt, Erf, Erfc and ErfInv, Gamma, GammaLn, LogGamma and Digamma on the positive reals, and Zeta right of its pole, have a known shape (monotonic, or a single minimum: Cosh's at 0, Γ's at 1.4616…), so their images are exact when the endpoints are.
  • Across a pole the image comes in unbounded pieces, returned as a Union of intervals: Cot(Interval(-π/4, π/4)) is (-∞, -1] ∪ [1, ∞), and pieces that meet merge, so Tan(Interval(0, π)) is all of ℝ.
  • Proven over balls: BarnesG and LogBarnesG, and PolyLog in z inside the unit disk, at exact arguments and ends. Their critical points aren't known, but their values and first two derivatives have certified kernels (see N). The interval is cut into pieces: where the derivative provably keeps one sign, a piece's image is its values at its ends, and elsewhere a second-order Taylor bound closes in on the turning point. The image is tight to about 1e-13 and rounded outward to 15 digits. Where the proof can't settle it (an inexact end, an interval reaching G's zeros or |z| = 1, a series too loose over a wide interval), the image is sampled as below.
  • Not rigorous: DirichletEta, DirichletBeta, CatalanNumber, Zeta left of its pole, and the multi-argument StieltjesGamma, HarmonicNumber, DirichletL, PolyGamma, GammaRegularized, BetaRegularized and Binomial, along with the proven heads wherever their proof declines. Their images come from sampling the derivative's sign, which can miss a pair of extrema between two samples.
  • The 'dependency problem' is not modeled: Interval(1,2) − Interval(1,2) is Interval(-1,1), not Interval(0,0), because the two copies are treated as independent quantities, exactly as Wolfram's own interval arithmetic does.

Examples

1 more kept as data, checked against the oracles
Basic #

Endpoints add

live ↗
InInterval(1,2)+Interval(3,4)\mathrm{Interval}(1, 2)+\mathrm{Interval}(3, 4)OutInterval(4,6)\mathrm{Interval}(4, 6)

Decimal arithmetic is exact, so nothing needs rounding

live ↗
InInterval(1.4,1.5)+1\mathrm{Interval}(1.4, 1.5)+1OutInterval(2.4,2.5)\mathrm{Interval}(2.4, 2.5)

A product takes the extreme endpoint products

live ↗
InInterval(1,2)Interval(−1,3)\mathrm{Interval}(1, 2)\mathrm{Interval}(-1, 3)OutInterval(−2,6)\mathrm{Interval}(-2, 6)
Scope #

At an inexact endpoint the value is rounded outward: sin⁡1.4=0.98544972998846018…\sin 1.4 = 0.98544972998846018\ldots lies inside

live ↗
Insin⁡(Interval(1.4,1.5))\sin(\mathrm{Interval}(1.4, 1.5))OutInterval(0.985 449 729 988 46,0.997 494 986 604 054 6)\mathrm{Interval}(0.985\,449\,729\,988\,46, 0.997\,494\,986\,604\,054\,6)

Γ\Gamma's minimum at 1.4616…1.4616\ldots lies inside, so it is the lower bound, rounded down; the upper bound, Γ(1)=Γ(2)=1\Gamma(1) = \Gamma(2) = 1, stays exact

live ↗
InΓ(Interval(1,2))Γ(\mathrm{Interval}(1, 2))OutInterval(0.885 603 194 410 888 6,1)\mathrm{Interval}(0.885\,603\,194\,410\,888\,6, 1)

Across the pole at π/2\pi/2 the two pieces cover every real, so they merge

live ↗
Intan⁡(Interval(0,π))\tan(\mathrm{Interval}(0, π))OutInterval(−∞,∞)\mathrm{Interval}(-∞, ∞)

Reciprocal of an interval not containing 0

live ↗
In1Interval(2,4)\frac{1}{\mathrm{Interval}(2, 4)}OutInterval(14,12)\mathrm{Interval}(\frac{1}{4}, \frac{1}{2})

An even power of an interval straddling 0 starts at 0, not at 1

live ↗
InInterval(−1,2)2\mathrm{Interval}(-1, 2)^2OutInterval(0,4)\mathrm{Interval}(0, 4)

The dependency problem: interval arithmetic doesn't know both operands are the same quantity

live ↗
InInterval(1,2)−Interval(1,2)\mathrm{Interval}(1, 2)-\mathrm{Interval}(1, 2)OutInterval(−1,1)\mathrm{Interval}(-1, 1)

Through an elementary function

live ↗
Insin⁡(Interval(−π6,π6))\sin(\mathrm{Interval}(-\frac{π}{6}, \frac{π}{6}))OutInterval(−12,12)\mathrm{Interval}(-\frac{1}{2}, \frac{1}{2})

The absolute value of an interval straddling 0

live ↗
In∣Interval(−3,2)∣\vert\mathrm{Interval}(-3, 2)\vertOutInterval(0,3)\mathrm{Interval}(0, 3)

A periodic head over an interval that contains a full swing covers its whole range

live ↗
Incos⁡(Interval(−1,4))\cos(\mathrm{Interval}(-1, 4))OutInterval(−1,1)\mathrm{Interval}(-1, 1)

An interior maximum at π/2\pi/2 becomes the upper end

live ↗
Insin⁡(Interval(1,2))\sin(\mathrm{Interval}(1, 2))OutInterval(sin⁡(1),1)\mathrm{Interval}(\sin(1), 1)

Γ\Gamma dips to its minimum 0.8856…0.8856\ldots inside [0.5,3][0.5, 3]

live ↗
InN(Γ(Interval(0.5,3)))N(Γ(\mathrm{Interval}(0.5, 3)))OutInterval(0.885 603 194 410 888 805 432,2)\mathrm{Interval}(0.885\,603\,194\,410\,888\,805\,432, 2)

ζ\zeta is decreasing on [2,3][2, 3], so the ends swap

live ↗
Inζ(Interval(2,3))ζ(\mathrm{Interval}(2, 3))OutInterval(ζ(3),π26)\mathrm{Interval}(ζ(3), \frac{π^2}{6})
live ↗
Inarctan⁡(Interval(−1,3))\arctan(\mathrm{Interval}(-1, 3))OutInterval(−π4,arctan⁡(3))\mathrm{Interval}(-\frac{π}{4}, \arctan(3))
live ↗
IneInterval(−1,ln⁡(2))e^{\mathrm{Interval}(-1, \ln(2))}OutInterval(1e,2)\mathrm{Interval}(\frac{1}{e}, 2)
live ↗
Inmax⁡(Interval(1,3),Interval(−3,5))\max(\mathrm{Interval}(1, 3), \mathrm{Interval}(-3, 5))OutInterval(1,5)\mathrm{Interval}(1, 5)

A quotient across zero is the union of two rays, as Wolfram returns it

live ↗
InInterval(1,2)Interval(−1,1)\frac{\mathrm{Interval}(1, 2)}{\mathrm{Interval}(-1, 1)}Out[−∞,−1]∪[1,∞]\lbrack-∞, -1\rbrack∪\lbrack1, ∞\rbrack

Sums add endpoint by endpoint

live ↗
InInterval(1,2)+Interval(3,5)\mathrm{Interval}(1, 2)+\mathrm{Interval}(3, 5)OutInterval(4,7)\mathrm{Interval}(4, 7)
About
Examples21
Checked againstWolfram Language 16 agree5 differSymPy 15 agree6 differ
CrosswalkSymPy

Implementation

mappedsympypackages/oracle/src/mappings.ts

AccumBounds is SymPy's interval arithmetic for real endpoints, but it is mapped for every Interval, a set use included: a Union of AccumBounds raises, AccumBounds(a, a) collapses to the scalar a, and reversed bounds raise. It holds accumulation bounds, not a rigorous enclosure: an inexact endpoint is not rounded outward, and a function over it is not built from its critical points as ours is, so the rows on rigour agree on endpoints only. Abs over an Interval is emitted as abs() (emit.ts), since Abs() leaves an AccumBounds held.

See also: CenteredInterval, Around