Repository

lib-math

Kinogaki's math library, kinogaki-math: vectors, points, matrices, quaternions, affine maps, frames, and deterministic elementary functions.

GitHub
kinogaki/lib-math (private)
Folder
libs/lib-math/
Crates
1
Rust lines
5,513 in src, 2,034 in tests
depends on (an edge implied by others shows when you point at a box)used by tests alone

Crates

CrateWhat it isFilesLinesTest lines
kinogaki-mathKinogaki's vectors, points, matrices, quaternions and deterministic elementary functions.235,5132,034

README

lib-math

Kinogaki's math library, kinogaki-math: vectors, points, matrices, quaternions, affine maps, frames, and deterministic elementary functions. It replaces glam across Studio and its libraries, and it is the base the CAD kernel's kinogaki-cad-math builds on.

Types

f64 is the default. The f32 types carry an f suffix and exist for the GPU boundary; converting is always explicit (as_f32, as_f64).

f64f32
Vec2, Vec3, Vec4Vec2f, Vec3f, Vec4fvectors
Mat3, Mat4Mat4fcolumn-major matrices; a * b applies b first
Quat, EulerOrderunit quaternions; intrinsic XYZ and ZYX Euler orders
Point2, Point3positions: point − point = vector, point ± vector = point, no point + point
Affine3general 3×3 plus translation; a.compose(&b) applies b, then a; inverse() -> Option, is_rigid(slack), determinant()
Frameright-handed orthonormal frame; Gram–Schmidt with a second pass

LengthUnit, UpAxis and Units say what a document's numbers mean (millimeters, Y up, …); Units::conversion is the exact matrix from one document's units to another's (an axis quarter turn, then the length ratio; never mirrors).

Mask<N> holds per-component comparisons (cmplt, cmpge, …) for select, all, any.

Semantics

  • Plain IEEE arithmetic in a fixed order: no fused multiply-add, no reassociation, no SIMD that changes rounding.
  • The vector, matrix and quaternion formulas are glam 0.30's, so Studio's results are bit-identical to before the switch. tests/glam_parity.rs holds golden checksums recorded from glam over 20 000 random inputs per operation (the recording harness compared 1 000 000 bit for bit).
  • length() and distance() are glam's plain sqrt(v · v): they overflow beyond about 1e154 and underflow below about 1e-154. length_scaled() and distance_scaled() rescale by the largest component when the square overflows, underflows or is NaN, so 1e200 and 1e-200 come out right. In the ordinary range they are the same bits. The plain forms are the default because the range check costs 5–15% in hot loops (docs/PERFORMANCE.md).
  • normalized() returns None for a zero or non-finite vector and handles every magnitude. The glam-style forms keep their names and behavior: normalize_or(fallback), normalize_or_zero(), and normalize_or_nan() (glam's normalize, which gives NaN for a zero vector).
  • lerp is exact at t = 0 and t = 1.
  • Mat4::inverse and Mat3::inverse do not check (infinite or NaN entries for a singular matrix), as glam's; Affine3::inverse returns None.
  • Trigonometry in the vector, matrix and quaternion types (from_axis_angle, from_euler, to_euler, …) is the platform's std, as glam's was.

Elementary functions

kinogaki_math::elementary: sin, cos, sin_cos, tan, asin, acos, atan, atan2, exp, exp_m1, ln, ln_1p, log2, log10, cbrt, hypot, powi, to_radians, to_degrees. Built only from IEEE + − × ÷ sqrt, bit manipulation and integer arithmetic, so the bits are the same on macOS, Linux and Windows; faithfully rounded with documented bounds (at most 0.557 ulp measured). They cost 1.2–3× std, so Studio's display code keeps std unless a benchmark shows a hot path can afford them.

  • tools/elementary_tables.py derives the constants, tables and polynomial coefficients from first principles and writes src/elementary/tables.rs.
  • tools/elementary_vectors.py writes the reference vectors in tests/elementary_vectors/ from an independent 100-digit decimal oracle.
  • tests/elementary/ checks the vectors against the documented bounds, special values, symmetries, monotonicity, golden output checksums, and greps the module for platform calls.
  • The one fused multiply-add (the exact error of a product in dd::two_prod) has a Dekker fallback that gives the same bits; run the tests with RUSTFLAGS="--cfg kinogaki_no_fma" to check that path.

Gates

cargo fmt --all -- --check, cargo clippy --workspace --all-targets -- -D warnings and cargo test --workspace. Studio's tools/check_all.py runs them. Performance against glam: docs/PERFORMANCE.md.

Its documents

The repository's architecture document as written there (code blocks and links left out), and the opening of each other document.

Performance against glam (libs/lib-math/docs/PERFORMANCE.md)

kinogaki-math replaced glam 0.30.10 in Studio. The bar is no speed regression. This page records how that was measured and what came out.