📖 Documentation site — the portfolio narrative, the concepts, a full walkthrough, and what all of this proves (and does not).
Interval arithmetic that rounds outward, refuses out-of-domain input, and ships the self-check that proves its enclosures hold.
pip install git+https://github.com/nickharris808/interval-core.git
interval-core # run the self-checkNot yet on PyPI.
pip install interval-coreis the intended install once published; until then use the source install above.
>>> from interval_core import Interval
>>> x = Interval(0.1, 0.2)
>>> y = x.sqrt()
>>> y.contains(0.1 ** 0.5)
True
>>> Interval(-2.0, 1.0).sq() # the minimum is interior, not at an end
Interval(0.0, 4.000000000000001)That upper end is 4.0 nudged to the next representable float, and it is the
whole point: every operation rounds outward, so the returned interval is
guaranteed to contain the true one rather than to be pretty.
And the thing you should run before trusting any of it:
$ interval-core --trials 800
interval-core validation (mode=naive, seed=0)
[ok ] add 7200 containment checks
[ok ] sub 7200 containment checks
[ok ] mul 7200 containment checks
[ok ] div 7200 containment checks
[ok ] sq 7200 containment checks
[ok ] abs 7200 containment checks
[ok ] sqrt 7200 containment checks
[ok ] log 7200 containment checks
[ok ] exp 7200 containment checks
[ok ] arccosh 7200 containment checks
[ok ] imin_bounds_all
[ok ] imax_bounds_all
[ok ] idot_encloses_midpoints
[ok ] idot_encloses_endpoints
[ok ] distance_3_4_5
[ok ] point_times_point_is_tight
enclosures hold: TrueThat is 10 operations, each sampled and compared against exact scalar
evaluation at the endpoints and midpoint of every input interval. Exit 0 if
every enclosure held, 1 if any did not.
An interval library's entire claim is that the returned interval contains the real answer. That claim is cheap to state, easy to break — one rounding in the wrong direction, one missing case in a transcendental — and a broken library looks exactly like a working one until someone's proof turns out to be wrong.
So validate() is part of the package rather than only of its test suite. The
person who most needs to run it is the one who just installed it.
There is a test that deliberately makes multiplication round inward and
requires validate() to catch it. A validation suite that cannot fail is
decoration; this one has been shown to go red on the exact mistake that makes
every downstream proof unsound while looking tighter and better.
Directed outward rounding. Where floating point cannot represent a bound exactly, the lower end rounds down and the upper end rounds up. An enclosure is never narrower than the truth. Widths grow; they never shrink.
Two enclosure modes. naive evaluates each operation independently, which
is simple and can be loose when a variable appears more than once in an
expression — the dependency problem. centered uses mean-value forms where they
apply and intersects with the naive result, so it is never worse, and a test
asserts exactly that.
from interval_core import set_enclosure_mode
set_enclosure_mode("centered")Domain violations raise. Interval(-1, 1).sqrt() is an error, not [0, 1].
An interval library that quietly clamps is one whose enclosures cannot be
trusted, which defeats the purpose of using one.
| Object | What it is |
|---|---|
Interval(lo, hi) |
The core type. Rejects an inverted interval. |
Interval.point(x) |
A degenerate interval at x. |
.contains(x), .encloses(other) |
Point membership; interval containment. |
.width, .midpoint, .mag |
Size, centre, largest absolute value. |
+ - * / abs() |
Outward-rounded arithmetic. |
.sq() |
Squaring, correct across zero — not x * x. |
.sqrt(), .log(), .exp(), .arccosh() |
Transcendentals, with domain checks. |
imin(*ivs), imax(*ivs) |
Bounds over several intervals. |
idot(xs, ys) |
Dot product of interval vectors. |
interval_distance(x1, y1, x2, y2) |
Euclidean distance between interval points. |
interval_pairwise_distances(xs, ys) |
All pairwise distances. |
interval_neumann_inverse_bound(A, A_mid_inv=None) |
Rigorous bound on ‖A⁻¹‖ by a Neumann series. |
set_enclosure_mode(m), get_enclosure_mode() |
"naive" or "centered". |
validate(trials, seed, verbose) |
The self-check. report["ok"] is the verdict. |
IntervalError, IntervalDomainError, IntervalInclusionError |
All ValueError subclasses. |
This is the arithmetic behind a published impossibility result: a branch-and-
bound proof that every layout in a four-parameter family of conductor
arrangements satisfies k ≤ 10/11, which is only as sound as its enclosures.
The theorem, its certified regions and its counterexamples are published as
screening-ceiling.
This package is the arithmetic, not the application. The family-specific certifiers stayed behind deliberately — they are about one physics problem, and mixing them in would make a general-purpose library into a confused one.
Real intervals only. No complex intervals, no affine arithmetic, no Taylor
models. If you need to beat the dependency problem harder than centered mode
manages, those are the techniques and this is not them.
Rounding is done by nudging with math.nextafter rather than by setting the
hardware rounding mode, which is portable and costs a little tightness. The
guarantee is directional correctness, not the last ulp.
interval_neumann_inverse_bound is rigorous under the stated hypothesis that
the Neumann series converges; if it does not, the function says so rather than
returning a bound.
Intervals are finite by construction. Near the top of the double range,
outward rounding of an otherwise representable result overflows to infinity, and
rather than saturate at float_max — which would return something that is not
an enclosure — the constructor raises. So `Interval.point(1.7976931348623157e308)
- Interval.point(2.0)` is an error, not a number.
That is a real limitation and it is the sound side of the trade: an enclosure that has quietly stopped enclosing is the one failure this library cannot tolerate. If you need bounds that run to infinity, this is not the right tool yet. A stress test pins the refusal so nobody "fixes" it into saturation.
screening-ceiling |
The certified regions and counterexamples this arithmetic produced. |
maxwell-lint |
Does a coupling extractor predict impossible physics? |
sparam-lint |
Is an S-parameter model physically possible? |
touchstone-tools |
Read, write and convert N-port network files. |
physics-lint |
One command for the checkers. SARIF for CI. |
abstain-bench |
Does a model know when to shut up? |
sparam-conformance |
11 labelled networks with verified ground truth. |
| Try the checkers in your browser | No install. |
Apache-2.0. See LICENSE; copyright in NOTICE.
One non-negotiable rule here: every operation must round outward, and ship a containment check that would catch it if it did not. CONTRIBUTING.md has the detail. Each sibling repository states its own, and they differ — that is deliberate, and it is why each is trustworthy on its own terms.
CITATION.cff is machine-readable; GitHub renders a “Cite this repository” button from it.