From 63c33b777b199a05b1ceae54f157f857b3f635f5 Mon Sep 17 00:00:00 2001
From: Claude Zero dependencies · Rust 2021 · MIT Zero dependencies · Rust 2021 · MIT
- 6,365 public functions and methods across
- 71 modules, and not one of them ships on
- the strength of having run without panicking. Every routine here is written so
- that something about it can be checked — against a closed form, a
- conservation law, an independent implementation, or an exact identity over
- integers.
+ The aim is not breadth for its own sake. Every routine here is written so that
+ something about it can be checked — against a closed form, against a
+ conservation law, against an independent implementation of the same quantity, or
+ against an exact identity over integers. A test that only asserts a function ran
+ is not evidence, and the test suite is built around that distinction. Where a
+ result is approximate the error has a stated bound; where it is exact the
+ assertion uses
- The aim is not breadth for its own sake. Breadth is what you get when the
- thing you actually insist on — that every result has something to be
- measured against — turns out to be possible in one field after another.
-
- Where a result is approximate the tolerance comes from the method's own
- error term, not from a number tuned until the test went green. Where it is
- exact the assertion uses
- Solvers return
- Argument guards are written
- Physical constants come from
-
-
- The Rust snippet below is
-
+ This snippet is
+
- 71 public modules across
- 296 source files. Search by name or by
- subject — the summaries are the first line of each module's own
- documentation, and the figures are parsed from the sources rather than
- written down. Press
- Module data is generated at build time — see
+ Module data is generated at build time — see
the module map.
Every one asserts something checkable: a closed form, a conservation law, a
- known reference value, or an exact identity — with a tolerance derived from
- the method's error term.
+ known reference value, or an exact identity. Approximate results carry a
+ stated tolerance derived from the method's error term, not one tuned until
+ the test passed.
- Randomised tests over invariants that must hold for every input:
- transform round-trips, algebraic laws, leapfrog FDTD energy conservation,
- and agreement between two independent implementations.
+ Randomized tests over invariants that must hold for every input, not
+ for a chosen example. They are what catch the cases nobody thought to write
+ down: round-trips, algebraic laws, conservation, and agreement between two
+ independent implementations of the same quantity.
- Model checking with CBMC: over a bounded input domain it proves
- absence of panics, overflow and division by zero rather than sampling for
- them. Thirteen run in CI; seven slower ones sit behind a feature flag.
+ Kani model-checks with CBMC: for a bounded input domain it proves absence of
+ panics, overflow and division by zero, rather than sampling. Thirteen run in
+ CI; seven that CBMC cannot decide in a CI-sized budget sit behind the
+
- The crate contains no
Coverage says a line ran, not that anything checked what it did. Some of the
worst gaps this project has found were in lines with full coverage:
@@ -326,16 +298,55 @@
- Published to PyPI as numeria: 4,086 of the crate's 4,149
- free functions, 2,254 of its 2,277 methods, 416 of its 426 types and every
- constant. The bindings are generated from this crate's source, so they cannot
- fall behind it.
+ Published to PyPI as numeria: 4,086 of this crate's 4,149 free
+ functions, 2,254 of its 2,277 methods, 416 of its 426 types and every constant.
+ The bindings are generated from this crate's source, so they cannot fall behind
+ it.
Three doors, depending on what you came for.
- A walk through the library by doing things with it: putting a spacecraft in
- orbit, pulling a tone out of noise, solving a differential equation and
- proving the answer converges at the predicted rate. Every code block is a
- file CI compiles and runs.
+ Start here. A walk through the library by doing things with it: putting
+ a spacecraft in orbit, pulling a tone out of noise, solving a differential
+ equation and proving the answer converges at the predicted rate, and the tools
+ for not being wrong. Every code block is a file in
- A generated map of all 71 public modules
- and every file beneath them, with line counts, public-item counts and
- summaries. Produced from the sources; CI fails if it is out of date.
+ A generated map of every one of the 295 modules: a size-annotated tree, tables
+ by subject area, and a row per module with its line count, public item counts
+ and summary. Produced from the sources, so nothing in it is transcribed; CI
+ fails if it is out of date.
- Full rustdoc, built from this commit. Every module carries a summary, and
- CI builds the documentation with
The aim is not breadth for its own sake. Every routine here is written so that
- something about it can be checked — against a closed form, against a
+ something about it can be checked: against a closed form, against a
conservation law, against an independent implementation of the same quantity, or
against an exact identity over integers. A test that only asserts a function ran
is not evidence, and the test suite is built around that distinction. Where a
@@ -98,8 +98,8 @@
- Module data is generated at build time — see
+ Module data is generated at build time. See
the module map.
The crate contains no Physics and mathematics that
+
check their own answersA zero-dependency Rust library for physics,
+ mathematics and engineering computation
==.
Physics and mathematics that
check their own answers
A test that only asserts a function ran is not evidence
- At a glance
Stated error bounds
- ==.
- Failure you can tell apart
- Result rather than panicking on
- non-convergence, so a caller can distinguish “did not converge” from
- “converged, to this”.
- NaN is rejected, not ignored
- !(x > 0.0) rather than
- x <= 0.0, so a NaN fails the check instead of sliding
- through it.
- One table per constant
- math::constants; anything
- elsewhere is a re-export, and a test enforces the agreement. The values
- fixed by the 2019 SI redefinition are exact.
- Dimensions in the type
- units::quantity carries dimensions alongside the number, so
- adding a velocity to a time is a compile-time-shaped error rather than a
- plausible-looking float.
- Exactness where it matters
- f64 throughout, except where it would be wrong to be:
- exact works over arbitrary-precision integers and rationals,
- and dimensional null spaces are computed over Rational.
-
+
+
+ Public functions and methods
+ 6,365 (4,124 free functions, 2,241 methods)
+ Public types
+ 431 structs, enums and traits
+ Top-level modules
+ 71 public, across 296 source files — see the
+ module map
+ Source 266,122 lines of Rust
+ Unit tests 4,193
+ Property tests 577, across 49 files
+ Line coverage 97.89% (174,685 lines, 3,681 uncovered)
+ Function coverage 99.33% (20,200 functions, 136 uncovered)
+ Formal verification
+ 20 Kani harnesses (13 in CI, 7 behind kani-slow)
+ Undefined behaviour
+ Miri-clean; the crate contains no unsafe
+ API documentation
+ every module carries a //! summary; cargo doc is
+ warning-free, and CI denies rustdoc warnings
+ Dependencies
+ none — Cargo.lock holds exactly one package
+
+ Edition 2021, f64 throughoutExactness where it matters
Install and run something
- examples/readme_quickstart.rs,
- compiled and run by CI on every push, so it cannot drift out of date.
- Install
Install and run something
Nothing else comes with it
- Cargo.lock holds exactly one package: this crate. No
- transitive tree to audit, no version resolution to lose an afternoon to,
- and no build script.
- Quick start
+ examples/readme_quickstart.rs,
+ compiled and run by CI, so it cannot drift out of date.
+ Nothing else comes with it
// Quantities carry their dimensions, and addition checks them.
let v = Quantity::new(3.0, Dim::new(1, 0, -1, 0, 0, 0, 0)); // m/s
let t = Quantity::new(2.0, Dim::TIME);
-let d = v.mul(&t).unwrap(); // 6 m — a length, exactly
+let d = v.mul(&t).unwrap(); // 6 m, a length, exactly
assert!(v.add(&t).is_err()); // a velocity is not a time
// Exact rational arithmetic over arbitrary-precision integers.
@@ -227,17 +196,17 @@ Nothing else comes with it
What's in it
/ to jump to the filter.
+ 71 top-level modules, across
+ 296 source files. Summaries are the first
+ sentence of each module's //! documentation and the figures are
+ parsed from the sources, so nothing here is transcribed. Press /
+ to filter.
What's in it
How it's tested
Unit tests 4,193
Property tests 577
Kani 20 harnesses
+ Formal verification 20 harnesses
kani-slow feature.
Miri strict provenance
+ Miri no unsafe
unsafe, so Miri is a backstop rather
- than the primary check. It runs against core::, where index
- and slice reasoning is densest.
+ The crate contains no unsafe, so Miri is a backstop rather than
+ the primary check. It runs against core:: — the interval and
+ dual-number arithmetic, where index and slice reasoning is densest — under
+ -Zmiri-strict-provenance.
Why 97.89% coverage is not the point
+ Why the coverage number is not the point
return true and the entire suite stayed green.
- Composites are rejected by Miller–Rabin first, so the Lucas branch is
- essentially never reached. It is now tested directly against the strong
- Lucas pseudoprimes below 20,000, computed independently rather than read
- off the implementation.
+ The strong Lucas test — the second half of Baillie–PSW —
+ was replaced wholesale with return true, and the entire suite
+ stayed green. Composites are rejected by Miller–Rabin first, so the Lucas
+ branch is essentially never reached in practice. It is now tested directly
+ against the strong Lucas pseudoprimes below 20,000 (5459, 5777, 10877, 16109,
+ 18971), computed independently rather than read off the implementation.
BigInt division, taken
- for roughly two divisions in a billion.
+ Knuth's add-back correction in BigInt division, taken for
+ roughly two divisions in a billion.
Why 97.89% coverage is not the point
Design
+
+
+ Cargo.lock holds exactly one package:
+ this crate.
+ f64 throughout, except where exactness is the point —
+ exact works over arbitrary-precision integers and rationals, and
+ units::dimensional computes null spaces over Rational
+ because a group is exactly dimensionless or it is not.
+ Result
+ rather than panicking on non-convergence. The guards are written
+ !(x > 0.0) rather than x <= 0.0 so that NaN is
+ rejected too.
+ math::constants; duplicates elsewhere are re-exports, and a test
+ enforces the agreement. The values fixed by the 2019 SI redefinition are exact.
+ From Python
From Python
numeria.
Result errors become exceptions under one
- PhysicsError root.
+ Result errors become exceptions under one PhysicsError
+ root.
Vec3 argument accepts a plain (x, y, z) tuple.
+ A Vec3 argument accepts (x, y, z).
Complex, BigInt and Rational cross
- over as Python's own complex, int and
+ Complex, BigInt and Rational cross over
+ as Python's own complex, int and
fractions.Fraction.
&dyn Fn, a Python callable
- will do.
+ Anywhere the library takes a &dyn Fn, a Python callable will
+ do.
Where to go next
- Further reading
The guide →
+ The guide
examples/ that
+ CI compiles and runs, and the output shown is what it actually prints.
The module map →
+ The module map
The API →
+ The API documentation
-D warnings, so a broken
- intra-doc link fails the build rather than shipping.
+ The crate root carries an orientation page and every module has a summary.
+ Built here from the current commit with -D warnings, the same
+ flag CI uses, so a broken intra-doc link fails the build rather than shipping.
A zero-dependency Rust library for physics,
mathematics and engineering computation
At a glance
Public types
431 structs, enums and traits
+ Top-level modules
- 71 public, across 296 source files — see the
- module map 71 public, across 296 source files (see the
+ module map)
Source 266,122 lines of Rust Unit tests 4,193
@@ -113,7 +113,7 @@ Property tests 577, across 49 files At a glance
every module carries a
//! summary; cargo doc is
warning-free, and CI denies rustdoc warnings
+ Dependencies
- none — Cargo.lock holds exactly one packagenone.
Cargo.lock holds exactly one package
@@ -206,7 +206,7 @@ Edition 2021, f64 throughoutWhat's in it
What's in it
Formal verification 20 harnesses
Miri no unsafe
unsafe, so Miri is a backstop rather than
- the primary check. It runs against core:: — the interval and
- dual-number arithmetic, where index and slice reasoning is densest — under
- -Zmiri-strict-provenance.
+ the primary check. It runs under -Zmiri-strict-provenance against
+ core::, the interval and dual-number arithmetic, where index and
+ slice reasoning is densest.
Why the coverage number is not the point
return true, and the entire suite
+ The strong Lucas test, the second half of Baillie–PSW, was
+ replaced wholesale with return true, and the entire suite
stayed green. Composites are rejected by Miller–Rabin first, so the Lucas
branch is essentially never reached in practice. It is now tested directly
against the strong Lucas pseudoprimes below 20,000 (5459, 5777, 10877, 16109,
@@ -310,7 +310,7 @@ f64 throughout, except where exactness is the point —
+ f64 throughout, except where exactness is the point:
exact works over arbitrary-precision integers and rationals, and
units::dimensional computes null spaces over Rational
because a group is exactly dimensionless or it is not.
@@ -329,9 +329,9 @@ No module matches that. Try a subject — ' + + '
No module matches that. Try a subject: ' +
'wavelet, orbit, prime.