axiolid_exact/
lib.rs

1#![forbid(unsafe_code)]
2
3//! Filtered exact arithmetic (ADR 0068).
4//!
5//! Exact *constructions* -- where two segments cross, where a line meets a
6//! circle -- produce numbers `f64` cannot hold. This crate answers each sign
7//! question in at most two passes over the same expression:
8//!
9//! 1. [`Interval`] arithmetic: `f64` with every operation rounded outward,
10//!    so the true value is provably inside `[lo, hi]`. If zero is outside,
11//!    the sign is proven. This decides almost every real input.
12//! 2. Otherwise [`Dyadic`] arithmetic: a big-integer mantissa (`num-bigint`)
13//!    times a power of two. Every finite `f64` is one, and `+ - *` stay
14//!    exact, so the sign is exact.
15//!
16//! There is no division, by design: constructions clear denominators, and a
17//! quotient's sign is `sign(numerator) * sign(denominator)`. Square roots
18//! appear only inside [`Root2`], the value `(a + b*sqrt(c)) / d`, whose sign
19//! and order are decided by squaring with case analysis, never by
20//! evaluating the root.
21//!
22//! Values no finite arithmetic holds -- `sin` and `cos` of a dyadic angle
23//! -- are enclosed in [`FixedInterval`]s whose precision the caller raises
24//! until a nonzero sign shows.
25//!
26//! Expressions are written once against the [`Arith`] trait and run in both
27//! tiers, so the fast path and the exact path cannot compute different
28//! polynomials.
29
30pub mod arith;
31pub mod certify;
32pub mod conic;
33pub mod construct;
34pub mod dyadic;
35pub mod fixed;
36pub mod interval;
37pub mod poly;
38pub mod root;
39pub mod tower;
40
41pub use arith::Arith;
42pub use certify::{certify, filter, require_finite, ExactError, SignExpr};
43pub use conic::{
44    conic_intersections, line_conic_hits, Conic, ConicIntersection, ConicLineHit, ConicLineHits,
45    ConicPoint,
46};
47pub use construct::{
48    compare_along, crossing_orientation, crossing_orientation_filter, line_circle_hits, Branch,
49    Circle, HitCount, Line, LineHit,
50};
51pub use dyadic::Dyadic;
52pub use fixed::FixedInterval;
53pub use interval::Interval;
54pub use poly::{IntPoly, RealRoot};
55pub use root::{sign_root, sign_two_roots, Root2};
56pub use tower::{Nested, Tower};