stdlib.math¶
Math Library
Generated from
v0.65.7. 57 source files, 1025 documented symbols.
algebra.xi¶
fn gcd(a: Int, b: Int) -> Int¶
Greatest common divisor of a and b; always non-negative (gcd(0, 0) == 0). Delegates to xiom.math.arithmetic.gcd, which saturates the one unrepresentable case gcd(INT_MIN, k) = 2^63 to INT_MAX (documented). Complexity: O(log min(|a|, |b|)).
- Postcondition:
result >= 0
fn lcm(a: Int, b: Int) -> Int¶
Least common multiple of |a| and |b|; always non-negative. 0 when either input is 0 and 0 (documented overflow) when the true lcm exceeds Int range. Delegates to xiom.math.arithmetic.lcm. Complexity: O(gcd).
- Postcondition:
result >= 0
fn egcd(a: Int, b: Int) -> (Int, Int, Int)¶
Extended Euclid: (g, x, y) with ax + by == g == gcd(a, b), g >= 0. For a == b == 0 returns (0, 1, 0). Delegates to xiom.math.arithmetic.gcd_extended. Complexity: O(log min(|a|, |b|)).
- Postcondition:
result._0 >= 0
fn mod_inverse(a: Int, m: Int) -> Option[Int]¶
Multiplicative inverse of a modulo m: x with (a * x) % m == 1. Returns None when gcd(a, m) != 1 (no inverse), when m == 0 (no modulus), and Some(0) for m == 1 (everything is 0 mod 1). Delegates to xiom.math.arithmetic.mod_inverse. Complexity: O(log min(|a|, |m|)).
- Postcondition:
(m == 0) => (result.is_none == true) - Postcondition:
(m == 1) => (result is Some(_) && result.value == 0) - Postcondition:
(m > 1 && result is Some(_)) => (result.value >= 0 && result.value < m) - Postcondition:
(m > 1 && a >= 0 && result is Some(_)) => ((a * result.value) % m == 1)
fn crt(remainders: &Vec[Int], moduli: &Vec[Int]) -> Option[Int]¶
Chinese remainder theorem solution x with x % m_i == r_i for every i. Returns None when the moduli are not pairwise coprime, when the two slices differ in length, or when any slice is empty. The combination x = sum(r_i * M_i * inv(M_i mod m_i, m_i)) is built over M = prod(m_i); intermediate products can overflow Int for large moduli (documented; for pairwise-coprime small moduli the result is exact and in [0, M)). Complexity: O(n^2 * log max(m_i)) for the coprimality check plus O(n log) for the inverses.
- Postcondition:
(remainders.len() != moduli.len() || moduli.len() == 0) => (result.is_none == true)
fn legendre_symbol(a: Int, p: Int) -> Int¶
Legendre symbol (a/p) for odd prime p: 1 when a is a quadratic residue modulo p, -1 when it is a non-residue, 0 when p divides a. Uses Euler's criterion a^((p-1)/2) mod p via modular exponentiation. p == 2 is handled directly (1 for odd a, 0 for even a); p <= 1 returns 0 (documented, no modulus). Complexity: O(log p).
- Postcondition:
(result == -1) || (result == 0) || (result == 1)
fn jacobi_symbol(a: Int, n: Int) -> Int¶
Jacobi symbol (a/n) for odd positive n; generalizes the Legendre symbol to composite odd n. Returns 0 for even or non-positive n (documented; the Jacobi symbol is undefined there) and 0 when gcd(a, n) != 1. Uses the standard quadratic-reciprocity reduction over the binary expansion. Complexity: O(log^2 n) worst case.
- Postcondition:
(result == -1) || (result == 0) || (result == 1)
fn binomial(n: Int, k: Int) -> Int¶
Binomial coefficient C(n, k). Returns 0 for invalid input (k < 0, k > n, n < 0) and 0 on overflow. Computed by the multiplicative form with an overflow guard on every step (result * (n - i + 1) / i stays in range). Complexity: O(min(k, n - k)).
- Postcondition:
result >= 0
fn factorial(n: Int) -> Int¶
Factorial of n (n!). Returns 0 for n < 0 and 0 on overflow (n >= 21 exceeds Int range). Complexity: O(n).
- Postcondition:
result >= 0
fn primorial(n: Int) -> Int¶
Product of the first n primes (p_n#). Returns 0 for n <= 0 and 0 (documented overflow) when the product exceeds Int range (n > 15). Complexity: O(n * sqrt(p_n)) trial division.
- Postcondition:
result >= 0
fn nth_prime(n: Int) -> Int¶
The n-th prime, 1-indexed (nth_prime(1) == 2). Returns 0 for n <= 0. Trial-division sieve walking odd candidates. Complexity: O(n * sqrt(p_n)).
- Postcondition:
result >= 0
fn integer_sqrt(n: Int) -> Int¶
floor(sqrt(n)) for n >= 0 via integer Newton iteration (no float, no overflow). Returns -1 for n < 0 (documented). Delegates to xiom.math.roots.integer_sqrt. Complexity: O(log n) iterations.
- Postcondition:
result >= -1
fn next_power_of_two(n: Int) -> Int¶
Smallest power of two >= n. Returns 1 for n <= 0 and 0 (documented overflow) when the next power of two exceeds Int range (n > 2^62). Delegates to xiom.math.arithmetic.next_power_of_two. Complexity: O(log n).
- Postcondition:
result >= 0
fn is_power_of_two(n: Int) -> Bool¶
True iff n is a positive power of two (is_power_of_two(0) == false, is_power_of_two(1) == true). Delegates to xiom.math.arithmetic.is_power_of_two. Complexity: O(log n).
- Postcondition:
(result == false) || (n > 0)
fn is_perfect_square(n: Int) -> Bool¶
True iff n is a perfect square (0 and 1 are squares). Returns false for n < 0. Uses the exact integer floor-sqrt check. Complexity: O(log n).
- Postcondition:
(result == false) || (n >= 0)
algebra_extended.xi¶
fn group_theory(operation: fn(Int, Int) -> Int, elements: &Vec[Int], identity: Int) -> Bool¶
Validates the group axioms of (elements, operation, identity): closure, associativity, the two-sided identity law, and the existence of a two-sided inverse for every element. An empty carrier is vacuously a group of order zero. Complexity: O(|G|^3) plus inverse search O(|G|^3).
- Postcondition:
(elements.len() == 0) => (result == true)
fn ring_theory(op_add: fn(Int, Int) -> Int, op_mul: fn(Int, Int) -> Int, elements: &Vec[Int], zero: Int, one: Int) -> Bool¶
Validates the ring axioms of (elements, op_add, op_mul, zero, one): the abelian group (elements, op_add, zero), the monoid (elements, op_mul, one), and both distributive laws. Multiplication is not required to commute (non-commutative rings are accepted). NOTE: the parameter names avoid the compiler's built-in operator identifiers (
add/mulresolve to Int/Float64 +/* regardless of the parameter, a name-resolution bug). Complexity: O(|R|^4).
- Postcondition:
(elements.len() == 0) => (result == true)
fn field_theory(op_add: fn(Float64, Float64) -> Float64, op_mul: fn(Float64, Float64) -> Float64, elements: &Vec[Float64], zero: Float64, one: Float64) -> Bool¶
Validates the field axioms of (elements, op_add, op_mul, zero, one): the ring axioms plus a commutative multiplication and a multiplicative inverse for every element other than zero. Parameter names avoid the compiler's built-in operator identifiers (see ring_theory). Complexity: O(|F|^4).
- Postcondition:
(elements.len() == 0) => (result == true)
fn module_theory(action: fn(Int, Int) -> Int, ring: &Vec[Int], module_set: &Vec[Int]) -> Bool¶
Validates the module axioms of (ring, module, action): the ring set is treated as the scalars and the module set as the vectors. Given the frozen signature (no scalar/vector addition functions), the check covers closure of the action (r*v in module for every r, v) and the unital law assuming ring[0] is the multiplicative identity of the ring (documented convention). Complexity: O(|R| * |M|).
- Postcondition:
(module_set.len() == 0) => (result == true)
fn galois_theory(polynomial: &Vec[Int], prime: Int) -> Bool¶
True iff the polynomial (coefficients from the constant term) is separable over the field F_p: gcd(p, p') == 1 modulo p. Returns false for prime <= 1 (no field), or an empty/constant polynomial. Complexity: O(deg^2) modular Euclid.
- Postcondition:
(prime <= 1) => (result == false)
fn algebraic_number(alpha: Float64, polynomial: &Vec[Float64]) -> Bool¶
True iff alpha is a root of the polynomial (coefficients from the constant term) within 1e-9 tolerance. Returns false for an empty polynomial. Complexity: O(deg).
fn commutative_algebra(ideal: &Vec[Int], ring: &Vec[Int], op_mul: fn(Int, Int) -> Int) -> Bool¶
True iff the ideal is closed and absorbing in the ring under op_mul: the ideal is a subset of the ring, mul-closed on itself, and absorbing (r * i in the ideal for every ring element r and ideal element i). The frozen signature omits the ring addition, so the additive ideal laws are not checked (documented). Parameter name avoids the built-in operator identifiers (see ring_theory). Complexity: O(|R| * |I|).
- Postcondition:
(ideal.len() == 0) => (result == true)
fn homological_algebra(chain: &Vec[Vec[Int]], maps: &Vec[fn(&Vec[Int]) -> Vec[Int]]) -> Bool¶
True iff the chain complex squares to zero: for every chain group element v at stage i, mapsi+1 is the zero element (an empty vector or a vector of zeros) of stage i+2. Each chain row is a set of elements; a single element is wrapped in a one-element vector before applying the corresponding map. Complexity: O(stages * |chain| * cost(map)).
- Postcondition:
(chain.len() == 0) => (result == true)
fn category_theory(objects: &Vec[Int], morphisms: &Vec[(Int, Int)]) -> Bool¶
True iff (objects, morphisms) is a category: morphism endpoints lie in objects, an identity morphism (x, x) exists for every object, and the composition of any composable pair (a, b) and (b, c) exists as a morphism (a, c). With the pair representation composition is then automatically associative (documented). Complexity: O(|M|^2).
- Postcondition:
(objects.len() == 0 && morphisms.len() == 0) => (result == true)
fn universal_algebra(operation: fn(&Vec[Int]) -> Int, arity: Int, elements: &Vec[Int]) -> Bool¶
Validates an equational algebra signature with one operation of the given arity: the operation is closed on elements (the result of every arity- tuple of elements is itself an element). Returns false for arity <= 0 (documented). Complexity: O(|A|^arity).
- Postcondition:
(arity > 0 && elements.len() == 0) => (result == true)
fn representation_theory(group: &Vec[Int], op_mul: fn(Int, Int) -> Int, matrices: &Vec[Vec[Vec[Float64]]]) -> Bool¶
True iff the matrix assignment preserves group multiplication: assuming matrices[i] is the image of group[i] (documented correspondence), every pair (i, j) satisfies M[op_mul(g_i, g_j)] == M[i] * M[j] within 1e-9 tolerance. Parameter name avoids the built-in operator identifiers (see ring_theory). Returns false when the assignment does not cover the group. Complexity: O(|G|^3 * dim^3).
- Postcondition:
(group.len() == 0) => (result == true)
fn lie_algebra(bracket: fn((Int, Int), (Int, Int)) -> (Int, Int), basis: &Vec[(Int, Int)]) -> Bool¶
True iff the bilinear alternating bracket satisfies the Jacobi identity on the basis (vectors over Z, represented as (Int, Int) pairs): anticommutativity bracket(x, x) == (0, 0), bilinearity in both arguments (using pair addition), and bracket(x, bracket(y, z)) + bracket(y, bracket(z, x)) + bracket(z, bracket(x, y)) == (0, 0). Complexity: O(|B|^3).
- Postcondition:
(basis.len() == 0) => (result == true)
fn clifford_algebra(metric: &Vec[Vec[Float64]], dim: Int) -> Vec[Vec[Float64]]¶
Basis of the Clifford algebra for the diagonal metric: returns the 2^dim x 2^dim scalar table M with M[i][j] the coefficient such that blade_i * blade_j = M[i][j] * blade_{i xor j} (basis blades indexed by their generator bitmask, 1 = e_1e_2...). The metric is the quadratic form of the underlying space; only its diagonal is used (documented). Returns the empty matrix for dim < 0 (documented). Complexity: O(4^dim).
- Postcondition:
(dim < 0) => (result.len() == 0) - Postcondition:
(dim >= 0) => (result.len() == _pow2(dim))
angular.xi¶
fn to_radians(deg: Float64) -> Float64¶
Degrees to radians: deg * (pi/180).
- Postcondition:
(((deg >= 0) && (result >= 0)) || ((deg <= 0) && (result <= 0))) || (deg != deg)
fn to_degrees(rad: Float64) -> Float64¶
Radians to degrees: rad * (180/pi).
- Postcondition:
(((rad >= 0) && (result >= 0)) || ((rad <= 0) && (result <= 0))) || (rad != rad)
fn to_gradians(deg: Float64) -> Float64¶
Degrees to gradians (400 gradians per full circle): deg * (10/9).
- Postcondition:
(((deg >= 0) && (result >= 0)) || ((deg <= 0) && (result <= 0))) || (deg != deg)
fn from_gradians(grad: Float64) -> Float64¶
Gradians to degrees: grad * (9/10).
- Postcondition:
(((grad >= 0) && (result >= 0)) || ((grad <= 0) && (result <= 0))) || (grad != grad)
fn to_mils(deg: Float64) -> Float64¶
Degrees to milliradians (6400 mils per full circle): deg * (160/9).
- Postcondition:
(((deg >= 0) && (result >= 0)) || ((deg <= 0) && (result <= 0))) || (deg != deg)
fn from_mils(mil: Float64) -> Float64¶
Milliradians to degrees: mil * (9/160).
- Postcondition:
(((mil >= 0) && (result >= 0)) || ((mil <= 0) && (result <= 0))) || (mil != mil)
fn to_arcmin(deg: Float64) -> Float64¶
Degrees to arcminutes: deg * 60.
- Postcondition:
(((deg >= 0) && (result >= 0)) || ((deg <= 0) && (result <= 0))) || (deg != deg)
fn from_arcmin(arcmin: Float64) -> Float64¶
Arcminutes to degrees: arcmin / 60.
- Postcondition:
(((arcmin >= 0) && (result >= 0)) || ((arcmin <= 0) && (result <= 0))) || (arcmin != arcmin)
fn to_arcsec(deg: Float64) -> Float64¶
Degrees to arcseconds: deg * 3600.
- Postcondition:
(((deg >= 0) && (result >= 0)) || ((deg <= 0) && (result <= 0))) || (deg != deg)
fn from_arcsec(arcsec: Float64) -> Float64¶
Arcseconds to degrees: arcsec / 3600.
- Postcondition:
(((arcsec >= 0) && (result >= 0)) || ((arcsec <= 0) && (result <= 0))) || (arcsec != arcsec)
fn normalize_angle(rad: Float64) -> Float64¶
Wrap radians into (-pi, pi]. normalize_angle(-pi) == pi, normalize_angle(3*pi) == pi. Infinities pass through unchanged. Complexity: O(1).
- Postcondition:
(((result > -3.141592653589793) && (result <= 3.141592653589793)) || (result == 1 / 0)) || (result == -1 / 0) || (result != result)
fn normalize_angle_deg(deg: Float64) -> Float64¶
Wrap degrees into (-180, 180]. normalize_angle_deg(-180) == 180, normalize_angle_deg(540) == 180. Complexity: O(1).
- Postcondition:
(((result > -180) && (result <= 180)) || (result == 1 / 0)) || (result == -1 / 0) || (result != result)
fn angle_diff(a: Float64, b: Float64) -> Float64¶
Signed angular difference a - b (radians), wrapped into (-pi, pi]. angle_diff(pi/2, 0) == pi/2. Complexity: O(1).
- Postcondition:
(((result > -3.141592653589793) && (result <= 3.141592653589793)) || (result == 1 / 0)) || (result == -1 / 0) || (result != result)
fn angle_lerp(a: Float64, b: Float64, t: Float64) -> Float64¶
Shortest-path linear interpolation between angles a and b at parameter t: a + normalize_angle(b - a) * t. t in [0, 1] interpolates; angle_lerp(0, pi, 0.5) == pi/2. Complexity: O(1).
- Postcondition:
(t != 0) || (result == a)
approximation.xi¶
fn interpolation(x: &Vec[Float64], y: &Vec[Float64], point: Float64) -> Float64¶
Interpolated value at point through the data (x, y): a natural cubic spline (the default smooth interpolant). Delegates to math.numerical.interp_cubic. Returns NaN for empty, mismatched, or fewer-than-2-points input. Complexity: O(n).
- Postcondition:
(x.len() >= 2 && y.len() == x.len()) || (result != result)
fn extrapolation(x: &Vec[Float64], y: &Vec[Float64], point: Float64) -> Float64¶
Extrapolated value at point outside the sample range [x[0], x[n-1]]: the linear extension of the two nearest end segments. Points inside the range are interpolated (cubic spline). Returns NaN for empty, mismatched, or fewer-than-2-points input. Complexity: O(n).
- Postcondition:
(x.len() >= 2 && y.len() == x.len()) || (result != result)
fn polynomial_approx(x: &Vec[Float64], y: &Vec[Float64], degree: Int) -> Vec[Float64]¶
Least-squares polynomial fit of degree degree through (x, y): solves the (A^T A) c = A^T y normal equations over the Vandermonde basis. Returns the coefficient vector [c0, c1, ..., c_degree] with c0 the constant term; the empty vector for empty/mismatched input or degree < 0 (documented). Complexity: O(n * d^2 + d^3).
- Postcondition:
(result.len() == 0) || (result.len() == degree + 1)
fn rational_approx(x: &Vec[Float64], y: &Vec[Float64], m: Int, n: Int) -> Vec[Float64]¶
Rational approximation (num degree m, den degree n) of the data (x, y) by linearized least squares: y ~= (p0 + p1 x + ... + pm x^m) / (1 + q1 x + ... + qn x^n). Returns [p0..pm, q1..qn] (the leading denominator coefficient is fixed at 1); the empty vector for empty/mismatched input or m, n < 0 (documented). Complexity: O(k * (m+n)^2 + (m+n)^3).
- Postcondition:
(result.len() == 0) || (result.len() == m + n + 1)
fn trigonometric_approx(x: &Vec[Float64], y: &Vec[Float64], harmonics: Int) -> Vec[Float64]¶
Fourier series coefficients of the sampled data (x, y) with harmonics sine/cosine terms (the sample points are treated as uniformly spaced over one period). Returns [a0, a1..aH, b1..bH] where a0 is the DC term and a_k/b_k the cosine/sine amplitudes; the empty vector for empty/mismatched input or harmonics < 0 (documented). Complexity: O(k * H).
- Postcondition:
(result.len() == 0) || (result.len() == 1 + 2 * harmonics)
fn exponential_approx(x: &Vec[Float64], y: &Vec[Float64]) -> Vec[Float64]¶
Fitted exponential model y ~= a * e^(b x) of the data (x, y) by least squares on the linearized problem ln y = ln a + b x. Returns [a, b]. Non-positive y values are skipped; the empty vector is returned when no valid samples remain or the inputs mismatch (documented). Complexity: O(k).
- Postcondition:
(result.len() == 0) || (result.len() == 2)
fn chebyshev_approx(f: fn(Float64) -> Float64, a: Float64, b: Float64, degree: Int) -> Vec[Float64]¶
Chebyshev series coefficients of f on [a, b] up to degree: the Chebyshev-Gauss quadrature c_k = (2/N) sum_i f(c) T_k over the N mapped Chebyshev nodes (c_0 averaged). Returns [c0, c1, ..., c_degree]. The empty vector for degree < 0 (documented). Complexity: O(N * degree).
- Postcondition:
(degree < 0) || (result.len() == degree + 1)
fn least_squares(a: &Vec[Vec[Float64]], b: &Vec[Float64]) -> Vec[Float64]¶
Normal-equation least-squares solution of A x = b: solves (A^T A) x = A^T b by Gaussian elimination. Returns the empty vector for empty or mismatched input (documented). Complexity: O(m * n^2 + n^3). The nested matrix is first repaired into a local matrix (copy row handles into a fresh
Vec[Vec[Float64]], then index that): the inner Vec headers of a by-ref nested Float64 matrix arrive corrupted on the current compiler (BUG 26 #1), while a locally built matrix is readable -- the recipe proven in geom/matrix.xi and re-verified on v0.61.3 (row-local copies alone are NOT enough for the Float64 case; the full local-matrix copy is required).
- Postcondition:
(a.len() == 0) || (result.len() == 0) || (result.len() == a[0].len())
fn minimax(f: fn(Float64) -> Float64, a: Float64, b: Float64, degree: Int) -> Vec[Float64]¶
Minimax polynomial coefficients of degree degree for f on [a, b]. Computed by the Remez exchange algorithm (see remez); the returned vector holds power-basis coefficients from the constant term. Complexity: O(iters * degree^3).
- Postcondition:
(degree < 0) || (result.len() == 0) || (result.len() == degree + 1)
fn pade_approx(f: fn(Float64) -> Float64, m: Int, n: Int, x0: Float64) -> Vec[Float64]¶
Pade approximant of order (m, n) of f at x0: builds the Taylor coefficients c0..c_{m+n} by central finite differences, then solves the Pade equations for the denominator q1..qn (q0 = 1) and folds the numerators p0..pm. Returns [p0..pm, q1..qn]; the empty vector for m, n < 0 (documented). NOTE: finite-difference Taylor coefficients limit accuracy (h = 1e-3); the approximation is most reliable for modest orders. Complexity: O((m+n) * cost(f)).
- Postcondition:
(m < 0) || (n < 0) || (result.len() == m + n + 1)
fn remez(f: fn(Float64) -> Float64, a: Float64, b: Float64, degree: Int) -> Vec[Float64]¶
Remez exchange algorithm producing the degree-degree minimax polynomial of f on [a, b]. Iterates reference points (initialised at the Chebyshev nodes) by solving the alternation linear system and exchanging with the largest deviation on a dense grid. Returns power-basis coefficients from the constant term; the empty vector for degree < 0 (documented). Complexity: O(iters * degree^3).
- Postcondition:
(degree < 0) || (result.len() == 0) || (result.len() == degree + 1)
fn spline_approx(x: &Vec[Float64], y: &Vec[Float64]) -> Vec[Vec[Float64]]¶
Cubic spline segment coefficients through the data (x, y): for n points the result holds n - 1 rows, each [a, b, c, d] describing p(x) = a + bt + ct^2 + d*t^3 with t = x - x_i (natural spline). The empty matrix for fewer than 2 points or mismatched input (documented). Complexity: O(n).
- Postcondition:
(x.len() < 2) || (y.len() != x.len()) || (result.len() == x.len() - 1)
fn best_approx(f: fn(Float64) -> Float64, basis: &Vec[fn(Float64) -> Float64], a: Float64, b: Float64) -> Vec[Float64]¶
Best least-squares coefficients of f in the given basis functions over [a, b]: samples f and the basis on a 64-point uniform grid and solves the normal equations. Returns the coefficient vector; the empty vector for an empty basis (documented). Complexity: O(64 * m^2 + m^3). Least-squares fit of f over [a, b] in the given function basis, via the normal equations sampled at 64 points. Returns the empty vector for an empty basis or when the basis is read through a
&Vec[fn]parameter (TODO(compiler): BUG 26 #2 -- Vec[fn] element reads return garbage).
- Postcondition:
(basis.len() == 0) || (result.len() == 0) || (result.len() == basis.len())
arithmetic.xi¶
fn gcd(a: Int, b: Int) -> Int¶
Greatest common divisor of a and b; always non-negative. gcd(0, 0) == 0. The one unrepresentable case gcd(INT_MIN, k) = 2^63 saturates to INT_MAX (documented). Complexity: O(log min(|a|,|b|)).
- Postcondition:
result >= 0
fn lcm(a: Int, b: Int) -> Int¶
Least common multiple of |a| and |b|; always non-negative. 0 when either input is 0, and 0 (documented overflow) when the true lcm exceeds Int range. Complexity: O(gcd).
- Postcondition:
result >= 0
fn is_power_of_two(n: Int) -> Bool¶
True iff n is a positive power of two. is_power_of_two(0) == false, is_power_of_two(1) == true. Complexity: O(log n).
- Postcondition:
result == false || n >= 1
fn next_power_of_two(n: Int) -> Int¶
Smallest power of two >= n. Returns 1 for n <= 0. When the next power of two would exceed Int range (n > 2^62) returns 0 (documented overflow). Complexity: O(log n).
- Postcondition:
result == 0 || result >= n
fn prev_power_of_two(n: Int) -> Int¶
Largest power of two <= n. Returns 0 for n <= 0 (no positive power fits). Complexity: O(log n).
- Postcondition:
n <= 0 || (result >= 1 && result <= n)
fn gcd_extended(a: Int, b: Int) -> (Int, Int, Int)¶
Extended Euclid: returns (g, x, y) with ax + by == g == gcd(a, b). g is non-negative. For a == b == 0 returns (0, 1, 0). Complexity: O(log).
- Postcondition:
result._0 >= 0
fn mod_inverse(a: Int, m: Int) -> Option[Int]¶
Multiplicative inverse of a mod m: x with (a * x) % m == 1. Returns None when gcd(a, m) != 1 (no inverse exists), when m == 0 (no modulus), and Some(0) for m == 1 (everything is 0 mod 1). Complexity: O(log min(a, m)).
- Postcondition:
(m == 0) => (result.is_none == true) - Postcondition:
(m == 1) => (result is Some(_) && result.value == 0) - Postcondition:
(m > 1 && result is Some(_)) => (result.value >= 0 && result.value < m) - Postcondition:
(m > 1 && a >= 0 && result is Some(_)) => ((a * result.value) % m == 1)
fn pow_mod(base: Int, exp: Int, m: Int) -> Int¶
base^exp mod m via exponentiation by squaring. Result in [0, m). exp < 0 returns 0 (documented; only non-negative exponents are supported), m == 1 returns 0, m == 0 returns 0 (documented, division by zero guard). Complexity: O(log exp).
- Postcondition:
result >= 0 && (m <= 1 || result < m)
fn is_odd(n: Int) -> Bool¶
True iff n is odd (sign-aware: -3 is odd).
- Postcondition:
result == (n % 2 != 0)
fn is_even(n: Int) -> Bool¶
True iff n is even (sign-aware: -4 is even).
- Postcondition:
result == (n % 2 == 0)
fn div_ceil(a: Int, b: Int) -> Int¶
Integer division rounded toward positive infinity (ceiling). ceil(-7, 2) == -3. Division by zero returns 0; INT_MIN / -1 returns INT_MIN (unrepresentable +2^63). Complexity: O(1).
- Postcondition:
(b == 0) => (result == 0) - Postcondition:
(b > 0) => (result == a / b || (a % b != 0 && result == a / b + 1))
fn div_floor(a: Int, b: Int) -> Int¶
Integer division rounded toward negative infinity (floor). floor(-7, 2) == -4. Division by zero returns 0; INT_MIN / -1 returns INT_MIN. Complexity: O(1).
- Postcondition:
(b == 0) => (result == 0) - Postcondition:
(b > 1) => (result == a / b || (a % b != 0 && result == a / b - 1))
fn div_trunc(a: Int, b: Int) -> Int¶
Integer division truncated toward zero (native semantics). trunc(-7, 2) == -3. Division by zero returns 0; INT_MIN / -1 returns INT_MIN. Complexity: O(1).
- Postcondition:
(b == 0) => (result == 0) - Postcondition:
(b == 1) => (result == a)
fn mod_floor(a: Int, b: Int) -> Int¶
Modulus with result matching the divisor sign. mod_floor(-7, 2) == 1, mod_floor(7, -2) == -1. Division by zero returns 0. Complexity: O(1).
- Postcondition:
b == 0 || result == 0 || (result < 0) == (b < 0)
fn mod_trunc(a: Int, b: Int) -> Int¶
Modulus with result matching the dividend sign (native semantics). mod_trunc(-7, 2) == -1, mod_trunc(7, -2) == 1. Division by zero returns 0. Complexity: O(1).
- Postcondition:
b == 0 || result == 0 || (result < 0) == (a < 0)
calculus.xi¶
fn derivative(f: fn(Float64) -> Float64, x: Float64, h: Float64) -> Float64¶
First derivative of f at x with step h (central difference). Delegates to xiom.math.differential.derivative. Complexity: O(1).
- Postcondition:
(h != 0) || (result == 0)
fn derivative_2nd(f: fn(Float64) -> Float64, x: Float64, h: Float64) -> Float64¶
Second derivative of f at x with step h. Delegates to xiom.math.differential.derivative2. Complexity: O(1).
- Postcondition:
(h != 0) || (result == 0)
fn derivative_3rd(f: fn(Float64) -> Float64, x: Float64, h: Float64) -> Float64¶
Third derivative of f at x with step h. Delegates to xiom.math.differential.derivative3. Complexity: O(1).
- Postcondition:
(h != 0) || (result == 0)
fn integrate(f: fn(Float64) -> Float64, a: Float64, b: Float64) -> Float64¶
Default high-accuracy definite integral of f over [a, b]. Delegates to xiom.math.integral.definite_integral. Complexity: depends on the integrand.
- Postcondition:
(a != b) || (result == 0)
fn integrate_trapezoid(f: fn(Float64) -> Float64, a: Float64, b: Float64, n: Int) -> Float64¶
Composite trapezoidal rule with n subintervals. Delegates to xiom.math.integral.integrate_trapezoid. Complexity: O(n).
- Postcondition:
(n > 0) || (result == 0)
fn integrate_simpson(f: fn(Float64) -> Float64, a: Float64, b: Float64, n: Int) -> Float64¶
Composite Simpson's rule with n subintervals (odd n reduced to n - 1). Delegates to xiom.math.integral.integrate_simpson. Complexity: O(n).
- Postcondition:
(n > 0) || (result == 0)
fn integrate_romberg(f: fn(Float64) -> Float64, a: Float64, b: Float64, tol: Float64) -> Float64¶
Romberg integration of f over [a, b] to tolerance tol: builds the trapezoid Richardson table with up to 12 refinements and returns the best diagonal estimate. Returns 0.0 for tol <= 0 (documented). Complexity: O(2^refinements). TODO(compiler): NOT IMPLEMENTABLE in this compiler build - the Romberg Richardson-table loops emit AVX-512 and crash with 0xC000001D (BUG 20) on Zen 2. Keep the frozen signature; revisit when the loops are not vectorized.
- Postcondition:
(tol > 0) || (result == 0)
fn integrate_gauss(f: fn(Float64) -> Float64, a: Float64, b: Float64, n: Int) -> Float64¶
n-point Gauss quadrature over [a, b] (Gauss-Legendre, n in 1..8, otherwise the 8-point rule). Delegates to xiom.math.integral.integrate_gauss_legendre. Complexity: O(n). Re-verified on v0.61.3 (2026-09-24): the cross-module delegation works; the old BUG-20 crash claim was stale.
- Postcondition:
(a != b) || (result != result) || (result == 0)
fn limit(f: fn(Float64) -> Float64, x: Float64) -> Float64¶
Two-sided limit of f as the argument approaches x, estimated by Richardson extrapolation of the symmetric averages at h = 1e-4 and h = 1e-5. A discontinuous or singular integrand yields an undefined (NaN or infinite) result. Complexity: O(1). TODO(compiler): NOT IMPLEMENTABLE in this compiler build - crashes at startup with 0xC000001D (BUG 20 AVX-512 codegen on Zen 2). Keep the frozen signature; revisit when the extrapolation arithmetic is not vectorized.
fn limit_left(f: fn(Float64) -> Float64, x: Float64) -> Float64¶
One-sided limit of f from below (x approached from the left), estimated by linear Richardson extrapolation of f(x - h) at h = 1e-4 and h = 1e-5. Complexity: O(1). TODO(compiler): NOT IMPLEMENTABLE - same crash as limit (0xC000001D).
fn limit_right(f: fn(Float64) -> Float64, x: Float64) -> Float64¶
One-sided limit of f from above (x approached from the right), estimated by linear Richardson extrapolation of f(x + h) at h = 1e-4 and h = 1e-5. Complexity: O(1). TODO(compiler): NOT IMPLEMENTABLE - same crash as limit (0xC000001D).
fn is_continuous(f: fn(Float64) -> Float64, x: Float64, tol: Float64) -> Bool¶
True iff f is continuous at x within tol: the two-sided limit estimate and the value f(x) must both be defined and agree within tol. Returns false when either is NaN or infinite. Complexity: O(1). TODO(compiler): NOT IMPLEMENTABLE - depends on limit, which crashes with 0xC000001D (see limit). Keep the frozen signature.
fn gradient(f: fn(&Vec[Float64]) -> Float64, x: &Vec[Float64]) -> Vec[Float64]¶
Gradient vector of the scalar field f at x (central partial differences, h = 1e-6). Delegates to xiom.math.differential.gradient. Complexity: O(n * f). TODO(compiler): NOT IMPLEMENTABLE in this compiler build - the central partial-difference loops build and read Vec[Float64] perturbations, which crash with 0xC0000005 (BUG 12 family Vec[Float64] element reads) and 0xC000001D (BUG 20 loops). Keep the frozen signature; revisit when Vec[Float64] element reads and float loops are codegen-correct.
fn partial_derivative(f: fn(&Vec[Float64]) -> Float64, x: &Vec[Float64], i: Int, h: Float64) -> Float64¶
Partial derivative of f with respect to x[i] at x with step h. Delegates to xiom.math.differential.partial_derivative. Complexity: O(f). TODO(compiler): NOT IMPLEMENTABLE - same Vec[Float64]/loop crash as gradient (0xC0000005 / 0xC000001D). Keep the frozen signature.
fn jacobian(fs: &Vec[fn(&Vec[Float64]) -> Float64], x: &Vec[Float64]) -> Vec[Vec[Float64]]¶
Jacobian matrix of the function vector fs at x. Delegates to xiom.math.differential.jacobian. Complexity: O(|fs| * n * f). TODO(compiler): NOT IMPLEMENTABLE - same Vec[Float64]/loop crash as gradient (0xC0000005 / 0xC000001D). Keep the frozen signature.
fn hessian(f: fn(&Vec[Float64]) -> Float64, x: &Vec[Float64]) -> Vec[Vec[Float64]]¶
Hessian matrix of second partials of the scalar field f at x: entry (i, j) is the mixed central difference with h = 1e-5. Complexity: O(n^2 * f). TODO(compiler): NOT IMPLEMENTABLE - same Vec[Float64]/loop crash as gradient (0xC0000005 / 0xC000001D). Keep the frozen signature.
fn laplacian(f: fn(&Vec[Float64]) -> Float64, x: &Vec[Float64]) -> Float64¶
Laplacian of the scalar field f at x: sum of the second partials via the central difference, h = 1e-5. Complexity: O(n * f). TODO(compiler): NOT IMPLEMENTABLE - same Vec[Float64]/loop crash as gradient (0xC0000005 / 0xC000001D). Keep the frozen signature.
fn curl(f: fn(&Vec[Float64]) -> Vec[Float64], x: &Vec[Float64]) -> Vec[Float64]¶
Curl of a 3D vector field f at x: (dFz/dy - dFy/dz, dFx/dz - dFz/dx, dFy/dx - dFx/dy) via central differences with h = 1e-5. Returns the empty vector when x has fewer than 3 components (documented). Complexity: O(f). TODO(compiler): NOT IMPLEMENTABLE - same Vec[Float64]/loop crash as gradient (0xC0000005 / 0xC000001D). Keep the frozen signature.
fn divergence(f: fn(&Vec[Float64]) -> Vec[Float64], x: &Vec[Float64]) -> Float64¶
Divergence of the vector field f at x: sum of dF_i/dx_i via central differences with h = 1e-5. Complexity: O(n * f). TODO(compiler): NOT IMPLEMENTABLE - same Vec[Float64]/loop crash as gradient (0xC0000005 / 0xC000001D). Keep the frozen signature.
chaos.xi¶
fn logistic_map(r: Float64, x0: Float64, n: Int) -> Vec[Float64]¶
Logistic map x_{k+1} = r x (1 - x) iterated n steps from x0. Returns the orbit (x0, x1, ..., x_{n-1}); empty for n <= 0. Complexity: O(n).
- Postcondition:
(n <= 0) => (result.len() == 0) - Postcondition:
(n > 0) => (result.len() == n)
fn lorenz_system(sigma: Float64, rho: Float64, beta: Float64, x0: &Vec[Float64], steps: Int, dt: Float64) -> Vec[Vec[Float64]]¶
Lorenz system dx/dt = sigma(y-x), dy/dt = x(rho-z) - y, dz/dt = xy - beta z integrated by explicit Euler. Returns steps + 1 rows of 3 components; empty for steps <= 0. Complexity: O(steps).
- Postcondition:
(steps <= 0 || x0.len() != 3) => (result.len() == 0) - Postcondition:
(steps > 0 && x0.len() == 3) => (result.len() == steps + 1)
fn rossler_system(a: Float64, b: Float64, c: Float64, x0: &Vec[Float64], steps: Int, dt: Float64) -> Vec[Vec[Float64]]¶
Rossler system dx/dt = -y - z, dy/dt = x + a y, dz/dt = b + z(x - c) integrated by explicit Euler. Returns steps + 1 rows of 3 components; empty for steps <= 0. Complexity: O(steps).
- Postcondition:
(steps <= 0 || x0.len() != 3) => (result.len() == 0) - Postcondition:
(steps > 0 && x0.len() == 3) => (result.len() == steps + 1)
fn henon_map(a: Float64, b: Float64, x0: Float64, y0: Float64, n: Int) -> Vec[(Float64, Float64)]¶
Henon map x' = 1 - a x^2 + y, y' = b x iterated n steps. Returns the orbit as (x, y) pairs; empty for n <= 0. Complexity: O(n).
- Postcondition:
(n <= 0) => (result.len() == 0) - Postcondition:
(n > 0) => (result.len() == n)
fn bifurcation_diagram(r_min: Float64, r_max: Float64, steps: Int, transients: Int) -> Vec[(Float64, Float64)]¶
Bifurcation-diagram points of the logistic map: for
stepsparameter values uniformly spread over [r_min, r_max], discardtransientsiterations then capture 10 orbit points as (r, x) pairs. Empty for degenerate input. Complexity: O(steps * (transients + 10)).
- Postcondition:
(steps <= 0 || r_max < r_min) => (result.len() == 0) - Postcondition:
(steps > 0 && r_max >= r_min) => (result.len() == steps * 10)
fn lyapunov_exponent(orbit: &Vec[Float64]) -> Float64¶
Estimated largest Lyapunov exponent of a 1-D time series from the mean log expansion ratio |x_{k+1} - x_k| / |x_k - x_{k-1}|. NaN for fewer than 3 points or a zero difference (documented). Complexity: O(n).
- Postcondition:
(orbit.len() < 3) => (result != result)
fn strange_attractor(dynamics: fn(&Vec[Float64]) -> Vec[Float64], x0: &Vec[Float64], n: Int) -> Vec[Vec[Float64]]¶
Trajectory of a chaotic attractor under the discrete dynamics map x <- dynamics(x), n steps. Returns n + 1 states; empty for n <= 0. Complexity: O(n * cost(dynamics)).
- Postcondition:
(n < 0) => (result.len() == 0) - Postcondition:
(n >= 0) => (result.len() == n + 1)
fn fractal_dimension(points: &Vec[(Float64, Float64)]) -> Float64¶
Box-counting fractal dimension of a 2-D point set: for four box sizes the occupied-box counts are fit by least squares on log-log scales. NaN for fewer than 2 points. Complexity: O(4 * n).
- Postcondition:
(points.len() < 2) => (result != result)
fn mandelbrot_set(c_re: Float64, c_im: Float64, max_iter: Int) -> Int¶
Escape iterations of c under z <- z^2 + c from z = 0; max_iter means the point is inside the set. Complexity: O(max_iter).
- Postcondition:
(max_iter >= 0) => (result >= 0 && result <= max_iter) - Postcondition:
(c_re == 0 && c_im == 0 && max_iter > 0) => (result == max_iter)
fn julia_set(c_re: Float64, c_im: Float64, z_re: Float64, z_im: Float64, max_iter: Int) -> Int¶
Escape iterations of z0 under z <- z^2 + c for fixed parameter c; max_iter means the point is inside the Julia set. Complexity: O(max_iter).
- Postcondition:
(max_iter >= 0) => (result >= 0 && result <= max_iter) - Postcondition:
(c_re == 0 && c_im == 0 && z_re == 0 && z_im == 0 && max_iter > 0) => (result == max_iter)
fn burning_ship(c_re: Float64, c_im: Float64, max_iter: Int) -> Int¶
Burning-ship fractal escape count: z <- (|re z| + i |im z|)^2 + c. Complexity: O(max_iter).
- Postcondition:
(max_iter >= 0) => (result >= 0 && result <= max_iter) - Postcondition:
(c_re == 0 && c_im == 0 && max_iter > 0) => (result == max_iter)
fn newton_fractal(coeffs: &Vec[Float64], z: Float64, max_iter: Int) -> Int¶
Index of the root that a point converges to under Newton iteration on the polynomial a x^2 + b x + c (given as coeffs [a, b, c]). Returns 0 or 1 for a non-degenerate quadratic (documented restriction to degree <= 2). Complexity: O(iters).
- Postcondition:
result == 0 || result == 1 - Postcondition:
(coeffs.len() < 3) => (result == 0)
fn tent_map(mu: Float64, x0: Float64, n: Int) -> Vec[Float64]¶
Tent map x_{k+1} = mu * min(x, 1 - x) iterated n steps from x0. Returns the orbit; empty for n <= 0. Complexity: O(n).
- Postcondition:
(n <= 0) => (result.len() == 0) - Postcondition:
(n > 0) => (result.len() == n)
combinatorics.xi¶
fn permutations(n: Int, k: Int) -> Int¶
Number of k-permutations of n distinct items: n!/(n-k)!. Delegates to xiom.math.factorial.falling_factorial (returns 0 for invalid input and on overflow). Complexity: O(k).
- Postcondition:
(k < 0) => (result == 0) - Postcondition:
(k == 0) => (result == 1) - Postcondition:
(n == 0 && k > 0) => (result == 0)
fn combinations(n: Int, k: Int) -> Int¶
Number of k-combinations of n distinct items: C(n, k). Delegates to xiom.math.factorial.binomial. Complexity: O(min(k, n-k)).
- Postcondition:
(n < 0 || k < 0 || k > n) => (result == 0) - Postcondition:
(n >= 0 && (k == 0 || k == n)) => (result == 1) - Postcondition:
result >= 0
fn permutations_with_repetition(n: Int, k: Int) -> Int¶
Number of ordered k-selections from n items with repetition: n^k. Returns 0 for n < 0 or k < 0 (documented), 1 for k == 0, and 0 (documented overflow) when n^k exceeds Int range. Complexity: O(k).
- Postcondition:
(n < 0 || k < 0) => (result == 0) - Postcondition:
(n >= 0 && k == 0) => (result == 1) - Postcondition:
(n == 0 && k > 0) => (result == 0) - Postcondition:
result >= 0
fn combinations_with_repetition(n: Int, k: Int) -> Int¶
Number of unordered k-selections from n items with repetition: C(n + k - 1, k). Returns 0 for n < 0 or k < 0 and on overflow (documented). Complexity: O(min(k, n-1)).
- Postcondition:
(n < 0 || k < 0) => (result == 0) - Postcondition:
(n == 0 && k == 0) => (result == 1) - Postcondition:
(n == 0 && k > 0) => (result == 0) - Postcondition:
(n >= 1 && k == 0) => (result == 1) - Postcondition:
result >= 0
fn derangements(n: Int) -> Int¶
Number of derangements of n items (fixed-point-free permutations). Delegates to xiom.math.factorial.subfactorial. Complexity: O(n).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n == 0) => (result == 1) - Postcondition:
(n >= 21) => (result == 0) - Postcondition:
result >= 0
fn bell_numbers(n: Int) -> Int¶
Bell number B(n): partitions of an n-set. Delegates to xiom.math.factorial.bell. Complexity: O(n^2).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n == 0 || n == 1) => (result == 1) - Postcondition:
result >= 0
fn catalan_numbers(n: Int) -> Int¶
Catalan number C_n. Delegates to xiom.math.factorial.catalan. Complexity: O(n).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n == 0) => (result == 1) - Postcondition:
(n >= 34) => (result == 0) - Postcondition:
result >= 0
fn eulerian_numbers(n: Int, k: Int) -> Int¶
Eulerian number A(n, k): permutations of n items with exactly k ascents. Delegates to xiom.math.factorial.eulerian. Complexity: O(n*k).
- Postcondition:
(n < 0 || k < 0 || k > n) => (result == 0) - Postcondition:
(n == 0 && k == 0) => (result == 1) - Postcondition:
(n >= 1 && k == 0) => (result == 1) - Postcondition:
(n >= 1 && k == n) => (result == 0) - Postcondition:
result >= 0
fn stirling_numbers_1(n: Int, k: Int) -> Int¶
Signed Stirling numbers of the first kind s(n, k). Derived from the unsigned numbers: s(n,k) = (-1)^(n-k) * |s(n,k)|. Delegates to xiom.math.factorial.stirling_first. Complexity: O(n*k).
- Postcondition:
(n < 0 || k < 0 || k > n) => (result == 0) - Postcondition:
(n == 0 && k == 0) => (result == 1) - Postcondition:
(n >= 1 && k == n) => (result == 1) - Postcondition:
(n >= 1 && k == 0) => (result == 0)
fn stirling_numbers_2(n: Int, k: Int) -> Int¶
Stirling numbers of the second kind S(n, k): partitions of an n-set into k blocks. Delegates to xiom.math.factorial.stirling_second. Complexity: O(n*k).
- Postcondition:
(n < 0 || k < 0 || k > n) => (result == 0) - Postcondition:
(n == 0 && k == 0) => (result == 1) - Postcondition:
(n >= 1 && k == n) => (result == 1) - Postcondition:
(n >= 1 && k == 0) => (result == 0) - Postcondition:
result >= 0
fn lah_numbers(n: Int, k: Int) -> Int¶
Lah numbers L(n, k). Delegates to xiom.math.factorial.lah. Complexity: O(min(k, n-k) + (n-k)).
- Postcondition:
(n <= 0 || k <= 0 || k > n) => (result == 0) - Postcondition:
(n >= 1 && k == n) => (result == 1) - Postcondition:
result >= 0
fn narayana_numbers(n: Int, k: Int) -> Int¶
Narayana numbers N(n, k). Delegates to xiom.math.factorial.narayana. Complexity: O(min(k, n-k)).
- Postcondition:
(n <= 0 || k <= 0 || k > n) => (result == 0) - Postcondition:
(n >= 1 && k == 1) => (result == 1) - Postcondition:
result >= 0
fn fibonacci(n: Int) -> Int¶
Fibonacci number F(n), 0-indexed: F(0) = 0, F(1) = 1. Returns 0 for n < 0 and 0 (documented overflow) when F(n) exceeds Int range (n > 92). Complexity: O(n).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n >= 0 && n <= 1) => (result == n) - Postcondition:
(n >= 93) => (result == 0) - Postcondition:
result >= 0
fn fibonacci_start(a: Int, b: Int, n: Int) -> Int¶
Term n of the Fibonacci-like sequence beginning with a and b (term 0 is a, term 1 is b, each later term is the sum of the previous two). Returns 0 for n < 0 and 0 (documented overflow) when the term exceeds Int range. Complexity: O(n).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n == 0) => (result == a) - Postcondition:
(n == 1) => (result == b)
fn lucas(n: Int) -> Int¶
Lucas number L(n): L(0) = 2, L(1) = 1, L(n) = L(n-1) + L(n-2). Returns 0 for n < 0 and 0 (documented overflow) when L(n) exceeds Int range. Complexity: O(n).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n == 0) => (result == 2) - Postcondition:
(n == 1) => (result == 1) - Postcondition:
(n >= 91) => (result == 0) - Postcondition:
result >= 0
fn tribonacci(n: Int) -> Int¶
Tribonacci number T(n): T(0) = T(1) = 0, T(2) = 1, T(n) = T(n-1) + T(n-2) + T(n-3). Returns 0 for n < 0 and 0 (documented overflow) when T(n) exceeds Int range. Complexity: O(n).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n <= 1) => (result == 0) - Postcondition:
(n == 2) => (result == 1) - Postcondition:
result >= 0
fn tetranacci(n: Int) -> Int¶
Tetranacci number T(n): T(0) = T(1) = T(2) = 0, T(3) = 1, and each later term is the sum of the previous four. Returns 0 for n < 0 and 0 (documented overflow) when T(n) exceeds Int range. Complexity: O(n).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n <= 2) => (result == 0) - Postcondition:
(n == 3) => (result == 1) - Postcondition:
result >= 0
fn partitions(n: Int) -> Int¶
Number of integer partitions p(n). Delegates to xiom.math.factorial.partition_count. Complexity: O(n * sqrt(n)).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n == 0) => (result == 1) - Postcondition:
result >= 0
fn integer_partitions(n: Int) -> Vec[Vec[Int]]¶
All integer partitions of n as lists. Delegates to xiom.math.factorial.integer_partitions. Complexity: O(p(n) * n).
- Postcondition:
(n < 0) => (result.len() == 0) - Postcondition:
(n == 0) => (result.len() == 1) - Postcondition:
(n > 0) => (result.len() >= 1)
fn compositions(n: Int, k: Int) -> Int¶
Number of compositions of n into exactly k positive parts: C(n-1, k-1). Returns 0 for n < 0, k <= 0, and k > n; n == 0, k == 0 yields 1 (the empty composition) and n == 0 with k > 0 yields 0. Complexity: O(min(k, n-k)).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n == 0 && k == 0) => (result == 1) - Postcondition:
(n == 0 && k != 0) => (result == 0) - Postcondition:
(n > 0 && (k <= 0 || k > n)) => (result == 0) - Postcondition:
(n >= 1 && k == n) => (result == 1) - Postcondition:
result >= 0
fn compositions_all(n: Int) -> Int¶
Total number of compositions of n: 2^(n-1) for n >= 1, 1 for n == 0. Returns 0 for n < 0 and 0 (documented overflow) when 2^(n-1) exceeds Int range (n > 63). Complexity: O(n).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n == 0) => (result == 1) - Postcondition:
(n >= 64) => (result == 0) - Postcondition:
result >= 0
fn surjections(n: Int, k: Int) -> Int¶
Number of onto (surjective) functions from an n-set to a k-set: k! * S(n, k). Returns 0 for n < 0, k < 0, k > n, and 0 (documented overflow) when the count exceeds Int range. Complexity: O(n*k + k).
- Postcondition:
(n < 0 || k < 0 || k > n) => (result == 0) - Postcondition:
(n >= 1 && k == 1) => (result == 1) - Postcondition:
result >= 0
fn involutions(n: Int) -> Int¶
Number of involutions on n elements (self-inverse permutations). Uses the recurrence I(n) = I(n-1) + (n-1)*I(n-2), I(0) = I(1) = 1. Returns 0 for n < 0 and 0 (documented overflow) when I(n) exceeds Int range. Complexity: O(n).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n >= 0 && n <= 1) => (result == 1) - Postcondition:
result >= 0
fn derangements_enum(n: Int) -> Vec[Vec[Int]]¶
All fixed-point-free permutations of 1..n as lists. Returns the empty list for n < 0; n == 0 yields a single empty permutation. Complexity: O(!n * n).
- Postcondition:
(n < 0) => (result.len() == 0) - Postcondition:
(n == 0) => (result.len() == 1) - Postcondition:
(n == 1) => (result.len() == 0) - Postcondition:
(n >= 2) => (result.len() >= 1)
fn permutations_enum(elems: &Vec[Int]) -> Vec[Vec[Int]]¶
All permutations of elems as lists (n! results). Returns an empty list for an empty input. Complexity: O(n! * n).
- Postcondition:
(elems.len() == 0) => (result.len() == 1) - Postcondition:
(elems.len() > 0) => (result.len() >= 1)
fn combinations_enum(elems: &Vec[Int], k: Int) -> Vec[Vec[Int]]¶
All k-combinations of elems as lists (C(n, k) results). Returns an empty list for k < 0 or k > n. Complexity: O(C(n, k) * k).
- Postcondition:
(k < 0 || k > elems.len()) => (result.len() == 0) - Postcondition:
(k == 0 && k <= elems.len()) => (result.len() == 1) - Postcondition:
(k > 0 && k <= elems.len()) => (result.len() >= 1)
fn subsets_enum(elems: &Vec[Int], k: Int) -> Vec[Vec[Int]]¶
All k-element subsets of elems as lists. Alias of combinations_enum. Complexity: O(C(n, k) * k).
- Postcondition:
(k < 0 || k > elems.len()) => (result.len() == 0) - Postcondition:
(k == 0 && k <= elems.len()) => (result.len() == 1) - Postcondition:
(k > 0 && k <= elems.len()) => (result.len() >= 1)
fn powerset_enum(elems: &Vec[Int]) -> Vec[Vec[Int]]¶
All subsets of elems as lists (2^n results). Returns an empty list when n > 20 (documented guard against an impractical 2^n result set). Complexity: O(2^n * n).
- Postcondition:
(elems.len() > 20) => (result.len() == 0) - Postcondition:
(elems.len() == 0) => (result.len() == 1) - Postcondition:
(elems.len() <= 20) => (result.len() >= 1)
complex.xi¶
type Complex¶
Complex number in Cartesian form: re + im * i.
| Field | Type |
|---|---|
re |
Float64 |
im |
Float64 |
fn complex_new(re: Float64, im: Float64) -> Complex¶
Create a complex number from real and imaginary parts. O(1).
- Postcondition:
((result.re == re) || (result.re != result.re)) && ((result.im == im) || (result.im != result.im))
fn complex_from_polar(r: Float64, theta: Float64) -> Complex¶
Create a complex number from polar form (magnitude r, phase theta). O(1). z = r * (cos(theta) + i * sin(theta))
- Postcondition:
((result.re * result.re + result.im * result.im >= 0) || (result.re != result.re)) || (result.im != result.im)
fn complex_add(a: Complex, b: Complex) -> Complex¶
Add two complex numbers: (a+bi) + (c+di) = (a+c) + (b+d)i. O(1).
- Postcondition:
((result.re == a.re + b.re) || (result.re != result.re)) && ((result.im == a.im + b.im) || (result.im != result.im))
fn complex_sub(a: Complex, b: Complex) -> Complex¶
Subtract b from a: (a+bi) - (c+di) = (a-c) + (b-d)i. O(1).
- Postcondition:
((result.re == a.re - b.re) || (result.re != result.re)) && ((result.im == a.im - b.im) || (result.im != result.im))
fn complex_mul(a: Complex, b: Complex) -> Complex¶
Multiply two complex numbers: (a+bi)(c+di) = (ac-bd) + (ad+bc)i. O(1).
- Postcondition:
((result.re == a.re * b.re - a.im * b.im) || (result.re != result.re)) && ((result.im == a.re * b.im + a.im * b.re) || (result.im != result.im))
fn complex_div(a: Complex, b: Complex) -> Complex¶
Divide a by b: (a+bi)/(c+di) = (ac+bd)/(c2+d2) + i*(bc-ad)/(c2+d2). O(1).
- Postcondition:
(result.re == (a.re * b.re + a.im * b.im) / (b.re * b.re + b.im * b.im)) || (result.re != result.re) - Postcondition:
(result.im == (a.im * b.re - a.re * b.im) / (b.re * b.re + b.im * b.im)) || (result.im != result.im)
fn complex_scale(z: Complex, s: Float64) -> Complex¶
Multiply a complex number by a real scalar. O(1).
- Postcondition:
((result.re == z.re * s) || (result.re != result.re)) && ((result.im == z.im * s) || (result.im != result.im))
fn complex_conj(z: Complex) -> Complex¶
Conjugate: conj(a+bi) = a - bi. O(1).
- Postcondition:
((result.re == z.re) || (result.re != result.re)) && ((result.im == -z.im) || (result.im != result.im))
fn complex_abs(z: Complex) -> Float64¶
Absolute value (magnitude, modulus): |z| = sqrt(re2 + im2). O(1).
- Postcondition:
(result >= 0) || (result != result)
fn complex_arg(z: Complex) -> Float64¶
Argument (phase, angle): atan2(im, re) in radians (-pi, pi]. O(1).
- Postcondition:
((result >= -3.1416) && (result <= 3.1416)) || (result != result)
fn complex_equals(a: Complex, b: Complex, eps: Float64) -> Bool¶
Check if the complex number is approximately equal to another within epsilon. Uses absolute tolerance comparison. O(1).
- Postcondition:
(eps <= 0) => (result == false)
fn complex_is_zero(z: Complex, eps: Float64) -> Bool¶
Check if the complex number is approximately zero within epsilon. O(1).
- Postcondition:
(eps <= 0) => (result == false)
fn complex_exp(z: Complex) -> Complex¶
Complex exponential: exp(a+bi) = e^a * (cos(b) + isin(b)). O(1). Euler's formula: e^(ib) = cos(b) + i*sin(b).
- Postcondition:
((result.re * result.re + result.im * result.im >= 0) || (result.re != result.re)) || (result.im != result.im)
fn complex_log(z: Complex) -> Complex¶
Complex natural logarithm (principal branch). ln(z) = ln(|z|) + i * arg(z), where arg(z) in (-pi, pi]. O(1).
- Postcondition:
((result.im >= -3.1416) && (result.im <= 3.1416)) || (result.im != result.im)
fn complex_pow(z: Complex, w: Complex) -> Complex¶
Complex power: z^w = exp(w * ln(z)). Uses the principal branch of the logarithm. O(1).
- Postcondition:
((result.re * result.re + result.im * result.im >= 0) || (result.re != result.re)) || (result.im != result.im)
fn complex_sqrt(z: Complex) -> Complex¶
Complex square root (principal branch). Formula: sqrt(z) = sqrt(r) * (cos(theta/2) + i*sin(theta/2)) where r=|z|, theta=arg(z). Also handles negative re branch properly. O(1).
- Postcondition:
((z.im == 0) && (z.re >= 0)) => ((result.im == 0) && (result.re >= 0))
fn complex_sin(z: Complex) -> Complex¶
Complex sine: sin(a+bi) = sin(a)cosh(b) + icos(a)*sinh(b). O(1).
- Postcondition:
((result.re * result.re + result.im * result.im >= 0) || (result.re != result.re)) || (result.im != result.im)
fn complex_cos(z: Complex) -> Complex¶
Complex cosine: cos(a+bi) = cos(a)cosh(b) - isin(a)*sinh(b). O(1).
- Postcondition:
((result.re * result.re + result.im * result.im >= 0) || (result.re != result.re)) || (result.im != result.im)
fn complex_tan(z: Complex) -> Complex¶
Complex tangent: tan(z) = sin(z) / cos(z). Uses tan(a+bi) = (sin(2a) + i*sinh(2b)) / (cos(2a) + cosh(2b)). O(1).
- Postcondition:
((result.re * result.re + result.im * result.im >= 0) || (result.re != result.re)) || (result.im != result.im)
fn complex_to_string(z: Complex) -> Str¶
Convert a complex number to a human-readable string "a + bi". Uses built-in to_string and manual decimal string building. O(n) in digits.
- Postcondition:
result != ""
constants.xi¶
fn infinity() -> Float64¶
Positive infinity. Constructor fn (no literal syntax; BUG 3 -- see header).
- Postcondition:
result > 1
fn neg_infinity() -> Float64¶
Negative infinity. Constructor fn (no literal syntax; BUG 3 -- see header).
- Postcondition:
result < -1
fn nan() -> Float64¶
NAN (not-a-number) -- constructor fn (no NaN literal syntax exists; a const initializer can't hold the
0.0 / 0.0expression -- const-fold handles literals only). IEEE semantics verified:nan() != nan()is true and math.is_nan(nan()) is true since BUG 19's fcmp-one/Str+Float64-concat defects were fixed (2026-08-11,9c3a2f9e/88f924ea).
- Postcondition:
result != result
control_theory.xi¶
fn pid_controller(kp: Float64, ki: Float64, kd: Float64, error: Float64, dt: Float64, integral: Float64) -> (Float64, Float64)¶
PID output and updated integral: the derivative term requires a previous error sample, which the frozen signature does not carry, so the output is the proportional + integral action kpe + kiI_new. Returns (output, integral_new) with integral_new = integral + error*dt. Complexity: O(1).
- Postcondition:
result._1 == integral + error * dt - Postcondition:
(dt != 0) || (result._1 == integral)
fn transfer_function(num: &Vec[Float64], den: &Vec[Float64], s: Float64) -> Float64¶
Rational transfer function evaluated at s: num(s) / den(s) by Horner's scheme. NaN when the denominator vanishes. Complexity: O(degree).
- Precondition:
num.len() > 0 - Precondition:
den.len() > 0
fn state_space(a: &Vec[Vec[Float64]], b: &Vec[Vec[Float64]], c: &Vec[Vec[Float64]], d: &Vec[Vec[Float64]]) -> (Vec[Vec[Float64]], Vec[Vec[Float64]], Vec[Vec[Float64]], Vec[Vec[Float64]])¶
Canonical state-space realization. TODO(compiler): NOT IMPLEMENTABLE in this compiler build - the matrices are Vec[Vec[Float64]] whose element reads return garbage (BUG 23 #1 residual; verified by minimal probe). Keep the frozen signature; revisit when nested float Vec reads land.
fn observability(a: &Vec[Vec[Float64]], c: &Vec[Vec[Float64]]) -> Bool¶
Whether the pair (A, C) is observable: the rank of the stacked observability matrix [C; CA; ...; C*A^(n-1)] equals n. Returns false for empty or non-square A, empty C, width mismatches, or a multiply failure. Complexity: O(n^4) dense rank.
- Postcondition:
!result || a.len() > 0
fn controllability(a: &Vec[Vec[Float64]], b: &Vec[Vec[Float64]]) -> Bool¶
Whether the pair (A, B) is controllable: the rank of the stacked transpose-form controllability matrix [B^T; B^T A^T; ...; B^T (A^T)^(n-1)] equals n. Returns false for empty or non-square A, empty B, B with zero columns, width mismatches, or a multiply failure. Complexity: O(n^4) dense rank.
- Postcondition:
!result || a.len() > 0
fn stability_routh_hurwitz(den: &Vec[Float64]) -> Bool¶
Routh-Hurwitz stability test on the denominator polynomial (coefficients highest power first). Returns false for an empty or non-positive leading coefficient. Routh table rows hold at most 4 entries (degree <= 8). Complexity: O(n^2).
- Precondition:
den.len() > 0 - Postcondition:
(den[0] > 0) || (den[0] != den[0]) || (result == false)
fn nyquist_plot(tf: fn(Float64) -> Float64, freqs: &Vec[Float64]) -> Vec[(Float64, Float64)]¶
Nyquist curve points for a transfer function: the function is evaluated at each frequency and returned as (real, imag) with imag = 0 (a real-valued tf(omega) cannot carry phase in this signature; documented). Complexity: O(freqs * cost(tf)).
- Postcondition:
result.len() == freqs.len()
fn bode_plot(tf: fn(Float64) -> Float64, freqs: &Vec[Float64]) -> Vec[(Float64, Float64)]¶
Bode plot points: (frequency, magnitude) with the magnitude supplied by tf(omega). Complexity: O(freqs * cost(tf)).
- Postcondition:
result.len() == freqs.len()
fn root_locus(num: &Vec[Float64], den: &Vec[Float64], gains: &Vec[Float64]) -> Vec[(Float64, Float64)]¶
Closed-loop pole locations (real, imag) over a list of gains for the loop transfer num/den: the closed-loop characteristic polynomial den + K num is solved for each gain (exact for degree <= 2; empty otherwise, documented). Complexity: O(gains * degree).
- Postcondition:
result.len() <= 2 * gains.len()
fn pole_placement(a: &Vec[Vec[Float64]], b: &Vec[Vec[Float64]], poles: &Vec[Float64]) -> Vec[Vec[Float64]]¶
State-feedback gain K that places the poles. TODO(compiler): NOT IMPLEMENTABLE - the matrices are Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn lqr(a: &Vec[Vec[Float64]], b: &Vec[Vec[Float64]], q: &Vec[Vec[Float64]], r: &Vec[Vec[Float64]]) -> (Vec[Vec[Float64]], Vec[Vec[Float64]])¶
LQR gain and value matrix. TODO(compiler): NOT IMPLEMENTABLE - the matrices are Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn lqg(a: &Vec[Vec[Float64]], b: &Vec[Vec[Float64]], c: &Vec[Vec[Float64]], q: &Vec[Vec[Float64]], r: &Vec[Vec[Float64]]) -> Vec[Vec[Float64]]¶
LQG controller combining LQR with a Kalman filter. TODO(compiler): NOT IMPLEMENTABLE - the matrices are Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn kalman_filter(a: &Vec[Vec[Float64]], b: &Vec[Vec[Float64]], c: &Vec[Vec[Float64]], y: &Vec[Float64], x_hat: &Vec[Float64]) -> Vec[Float64]¶
One Kalman filtering step updating the state estimate. The measurement y and the prior estimate x_hat are used directly; the system matrices are not readable in this compiler build, so the update degenerates to a documented identity step (estimate unchanged). TODO(compiler): matrix inputs (A, B, C) unreadable (BUG 23 #1 residual).
- Postcondition:
result.len() == x_hat.len()
fn h_infinity(p: &Vec[Vec[Float64]]) -> Vec[Vec[Float64]]¶
H-infinity optimal controller synthesis from a plant. TODO(compiler): NOT IMPLEMENTABLE - the plant is a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn robust_control(nominal: fn(Float64) -> Float64, uncertainty: Float64) -> Bool¶
Small-gain robust stability check: the loop is robustly stable when max_omega |nominal(i omega)| * uncertainty < 1 over a log-spaced sweep of omega in [0.01, 100]. Complexity: O(50 * cost(nominal)).
decompose.xi¶
enum FloatClass¶
IEEE-754 bit decomposition and float classification (concrete Float64). frexp uses the [0.5, 1) fraction convention; ilogb/exponent use the [1, 2) mantissa convention (ilogb(8.0) == 3). NaN cannot be produced by this compiler (BUG 19); classify still detects a NaN input if one ever arrives. nextafter/nexttoward delegate to the exact arithmetic walk in math.primitives (exact for all finite normal/subnormal values). NOTE: requires/ensures clauses are runtime-enforced in this compiler and crash on violation, so all domain handling is guarded inside the bodies.
NaNInfinityNormalSubnormalZero
fn frexp(x: Float64) -> (Float64, Int)¶
Split x into (fraction, exponent) with x == fraction * 2^exponent and fraction in [0.5, 1). frexp(8.0) == (0.5, 4), frexp(0.0) == (0.0, 0). Exact. Complexity: O(1074) worst case.
- Postcondition:
(x == 0) => (result._0 == 0 && result._1 == 0) - Postcondition:
(x == 8) => (result._0 == 0.5 && result._1 == 4)
fn ldexp(x: Float64, n: Int) -> Float64¶
x * 2^n with a single rounding. For n beyond the representable exponent range the result is +-inf (n > 1100) or 0.0 (n < -1100); subnormal results flush correctly. Exact for all finite representable outcomes. Complexity: O(1074 + 1024).
- Postcondition:
(x == 0) => (result == 0) - Postcondition:
(n > 1100 && x != 0) => (result > 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 || result < -100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) - Postcondition:
(n < -1100 && x != 0) => (result == 0)
fn ilogb(x: Float64) -> Int¶
Binary exponent of x: the e with |x| == m * 2^e and 1 <= m < 2. ilogb(8.0) == 3, ilogb(0.5) == -1. For x == 0 returns INT_MIN (C FP_ILOGB0), for +-inf returns INT_MAX (C FP_ILOGB... convention). Complexity: O(1074) worst case.
- Postcondition:
(x == 0) => (result == -9223372036854775808) - Postcondition:
(x == 8) => (result == 3) - Postcondition:
(x == 0.5) => (result == -1)
fn logb(x: Float64) -> Float64¶
Binary exponent of x as a float: logb(8.0) == 3.0. For x == 0 returns -inf, for +-inf returns +inf (C semantics). Complexity: O(1074) worst case.
- Postcondition:
(x == 0) => (result < -100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) - Postcondition:
(x == 8) => (result == 3)
fn scalbn(x: Float64, n: Int) -> Float64¶
x * 2^n (FLT_RADIX == 2). Same semantics as ldexp. Complexity: O(ldexp).
- Postcondition:
(x == 1.5 && n == 1) => (result == 3) - Postcondition:
(x == 0) => (result == 0)
fn scalbln(x: Float64, n: Int64) -> Float64¶
x * 2^n with a long (Int64) exponent. Same semantics as ldexp. Complexity: O(ldexp).
- Postcondition:
(x == 1.5 && n == 1) => (result == 3) - Postcondition:
(x == 0) => (result == 0)
fn significand(x: Float64) -> Float64¶
Normalized fraction of x in [0.5, 1), sign preserved (frexp fraction). significand(8.0) == 0.5, significand(0.0) == 0.0; +-inf pass through. Complexity: O(1074) worst case.
- Postcondition:
(x == 0) => (result == 0) - Postcondition:
(x == 8) => (result == 0.5)
fn exponent(x: Float64) -> Int¶
Binary exponent of x. Alias of ilogb: exponent(8.0) == 3, exponent(0) == INT_MIN, exponent(+-inf) == INT_MAX. Complexity: O(ilogb).
- Postcondition:
(x == 8) => (result == 3)
fn frexp_pure(x: Float64) -> (Float64, Int)¶
frexp without libm. Identical semantics to frexp (the algorithm is exact integer scaling; no libm involved). Complexity: O(1074) worst case.
- Postcondition:
(x == 0) => (result._0 == 0 && result._1 == 0) - Postcondition:
(x == 8) => (result._0 == 0.5 && result._1 == 4)
fn ldexp_pure(x: Float64, n: Int) -> Float64¶
ldexp without libm. x * 2^n via exact frexp decomposition and power-of-two scaling (all intermediate steps are exact or correctly flushed). For n > 1100 returns +-inf, for n < -1100 returns 0.0. Complexity: O(1074).
- Postcondition:
(x == 0) => (result == 0) - Postcondition:
(n > 1100 && x != 0) => (result > 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 || result < -100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) - Postcondition:
(n < -1100 && x != 0) => (result == 0) - Postcondition:
(x == 1.5 && n == 1) => (result == 3)
fn is_normal(x: Float64) -> Bool¶
True iff x is a normal (non-subnormal, non-zero, finite) Float64: 2^-1022 <= |x| < +inf. Complexity: O(1).
- Postcondition:
(x == 0) => (result == false) - Postcondition:
(x == 1) => (result == true) - Postcondition:
(x == 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001) => (result == false)
fn is_subnormal(x: Float64) -> Bool¶
True iff x is a subnormal Float64: 0 < |x| < 2^-1022. Complexity: O(1).
- Postcondition:
(x == 0) => (result == false) - Postcondition:
(x == 1) => (result == false) - Postcondition:
(x == 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001) => (result == true)
fn classify(x: Float64) -> FloatClass¶
Classify x into the FloatClass taxonomy: NaN, Infinity, Normal, Subnormal, Zero. NaN classification is unreachable from code compiled by this compiler (BUG 19 cannot produce NaN), but is detected if one arrives. Complexity: O(1).
- Postcondition:
(x == 0) => (result == FloatClass.Zero) - Postcondition:
(x == 1) => (result == FloatClass.Normal)
fn nextafter(x: Float64, y: Float64) -> Float64¶
Next representable Float64 from x toward y. Exact for all finite normal and subnormal values; delegates to math.primitives.nextafter (the same arithmetic ulp walk). nextafter(max, +inf) == +inf. TODO(compiler): an exact implementation normally uses a float<->int bitcast; the arithmetic form is exact for finite values (see primitives).
- Postcondition:
(x == y) => (result == x) - Postcondition:
(x < y) => (result > x) - Postcondition:
(x > y) => (result < x)
fn nexttoward(x: Float64, y: Float64) -> Float64¶
Next representable Float64 from x toward y. Float64 has no distinct long double, so this is the same operation as nextafter.
- Postcondition:
(x == y) => (result == x) - Postcondition:
(x < y) => (result > x)
differential.xi¶
fn derivative(f: fn(Float64) -> Float64, x: Float64, h: Float64) -> Float64¶
First derivative of f at x by the central difference (f(x+h) - f(x-h))/2h. Returns 0.0 for h == 0 (documented). Complexity: O(1).
- Postcondition:
(h != 0) || (result == 0)
fn derivative2(f: fn(Float64) -> Float64, x: Float64, h: Float64) -> Float64¶
Second derivative of f at x by the central difference (f(x+h) - 2f(x) + f(x-h))/h^2. Returns 0.0 for h == 0 (documented). Complexity: O(1).
- Postcondition:
(h != 0) || (result == 0)
fn derivative3(f: fn(Float64) -> Float64, x: Float64, h: Float64) -> Float64¶
Third derivative of f at x by the four-point central difference (f(x+2h) - 2f(x+h) + 2f(x-h) - f(x-2h))/2h^3. Returns 0.0 for h == 0 (documented). Complexity: O(1).
- Postcondition:
(h != 0) || (result == 0)
fn finite_difference(f: fn(Float64) -> Float64, x: Float64, h: Float64) -> Float64¶
Central finite-difference approximation of the first derivative. Alias of derivative. Returns 0.0 for h == 0 (documented). Complexity: O(1).
- Postcondition:
(h != 0) || (result == 0)
fn richardson(f: fn(Float64) -> Float64, x: Float64, h: Float64, tol: Float64) -> Float64¶
Richardson-extrapolated first derivative of f at x: repeatedly halves h and combines D(h) and D(h/2) as (4*D(h/2) - D(h))/3 until consecutive estimates agree within tol. Returns 0.0 for tol <= 0 (documented). Complexity: O(halvings). Implemented iteratively on v0.61.3 (2026-09-24); the old BUG-20 crash claim was stale.
- Postcondition:
(tol > 0) || (tol != tol) || (result == 0)
fn gradient(f: fn(&Vec[Float64]) -> Float64, x: &Vec[Float64]) -> Vec[Float64]¶
Gradient vector of the scalar field f at x: each component is the central partial difference (f(x + h e_i) - f(x - h e_i))/2h with h = 1e-6. Complexity: O(n * f). Implemented on v0.61.3 (2026-09-24) with push-only perturbation vectors (no indexed writes); Vec[Float64] reads and float loops are codegen-correct.
- Postcondition:
result.len() == x.len()
fn jacobian(fs: &Vec[fn(&Vec[Float64]) -> Float64], x: &Vec[Float64]) -> Vec[Vec[Float64]]¶
Jacobian matrix of the function vector fs at x: entry (i, j) is the central partial difference of fs[i] with respect to x[j] (step h = 1e-6). Complexity: O(|fs| * n * f). TODO(compiler): NOT IMPLEMENTABLE - same Vec[Float64]/loop crash as gradient (0xC0000005 / 0xC000001D). Keep the frozen signature.
fn partial_derivative(f: fn(&Vec[Float64]) -> Float64, x: &Vec[Float64], i: Int, h: Float64) -> Float64¶
Partial derivative of f with respect to x[i] at x by the central difference. Returns 0.0 for h == 0 and for i out of [0, len(x)) (documented). Complexity: O(f). Implemented on v0.61.3 (2026-09-24) with push-only perturbations.
- Postcondition:
((i >= 0) && (i < x.len()) && (h != 0)) || (result == 0)
differential_equations.xi¶
fn solve_ode_euler(f: fn(Float64, Float64) -> Float64, y0: Float64, t0: Float64, t1: Float64, n: Int) -> Vec[Float64]¶
Explicit Euler steps of y' = f(t, y) from t0 to t1 in n steps. Returns n + 1 values (y(t0), ..., y(t1)); empty for n <= 0. Complexity: O(n).
- Postcondition:
(n <= 0) || (result.len() == n + 1)
fn solve_ode_rk4(f: fn(Float64, Float64) -> Float64, y0: Float64, t0: Float64, t1: Float64, n: Int) -> Vec[Float64]¶
Classical fourth-order Runge-Kutta integration of y' = f(t, y) in n steps. Returns n + 1 values; empty for n <= 0. Complexity: O(n).
- Postcondition:
(n <= 0) || (result.len() == n + 1)
fn solve_ode_rk45(f: fn(Float64, Float64) -> Float64, y0: Float64, t0: Float64, t1: Float64, tol: Float64) -> Vec[Float64]¶
Adaptive Dormand-Prince (RK45) integration of y' = f(t, y) to tolerance tol. Returns the accepted trajectory (including the initial value) with step-size doubling/halving; at most 100000 internal steps. NaN for tol <= 0. Complexity: O(steps * cost(f)).
- Postcondition:
(tol <= 0) || (result.len() >= 1)
fn solve_ode_adaptive(f: fn(Float64, Float64) -> Float64, y0: Float64, t0: Float64, t1: Float64, tol: Float64) -> Vec[Float64]¶
Generic adaptive step-size integrator of y' = f(t, y) to tolerance tol. Uses the Dormand-Prince pair (same trajectory semantics as solve_ode_rk45). Complexity: O(steps * cost(f)).
- Postcondition:
(tol <= 0) || (result.len() >= 1)
fn solve_ode_bdf(f: fn(Float64, Float64) -> Float64, y0: Float64, t0: Float64, t1: Float64, n: Int) -> Vec[Float64]¶
Backward differentiation formula of order 1 (implicit backward Euler): y_{n+1} = y_n + h f(t_{n+1}, y_{n+1}) solved by fixed-point iteration (8 iterations per step). Returns n + 1 values; empty for n <= 0. Complexity: O(n * iters * cost(f)).
- Postcondition:
(n <= 0) || (result.len() == n + 1)
fn solve_pde_fd(f: fn(Float64, Float64) -> Float64, t0: Float64, t1: Float64, nx: Int, nt: Int) -> Vec[Vec[Float64]]¶
Explicit finite-difference (FTCS) solution of the 1-D heat equation u_t = u_xx + f(t, x) on x in [0, 1], u(x, 0) = sin(pi x), zero boundary conditions. Returns nt + 1 rows of nx + 1 spatial samples. Empty for degenerate input. Complexity: O(nt * nx).
- Postcondition:
(nx <= 1) || (nt <= 0) || (result.len() == nt + 1)
fn solve_pde_fem(f: fn(Float64, Float64) -> Float64, t0: Float64, t1: Float64, nx: Int, nt: Int) -> Vec[Vec[Float64]]¶
Linear finite-element (Galerkin, hat functions, lumped mass) solution of u_t = u_xx + f(t, x) on x in [0, 1] with zero boundaries and initial u = sin(pi x). Returns nt + 1 rows of nx + 1 samples. Empty for degenerate input. Complexity: O(nt * nx).
- Postcondition:
(nx <= 1) || (nt <= 0) || (result.len() == nt + 1)
exponential.xi¶
fn exp(x: Float64) -> Float64¶
e^x. Returns +inf for x > 700 (overflow) and 0.0 for x < -745 (underflow) via libm. Complexity: O(1), libm exp.
- Postcondition:
result >= 0 || result != result
fn exp2(x: Float64) -> Float64¶
2^x. Complexity: O(1), libm pow.
- Postcondition:
result >= 0 || result != result
fn exp10(x: Float64) -> Float64¶
10^x. Complexity: O(1), libm pow.
- Postcondition:
result >= 0 || result != result
fn expm1(x: Float64) -> Float64¶
e^x - 1, accurate for small x. Uses the Taylor series x + x^2/2! + ... for |x| <= 1e-4 (where exp(x) - 1.0 suffers catastrophic cancellation) and libm exp - 1.0 otherwise. Returns -1.0 for x < -700 and +inf for x > 700. Complexity: O(20) series terms / O(1) libm.
- Postcondition:
result >= -1 || result != result
fn ln(x: Float64) -> Float64¶
Natural logarithm of x. Requires x > 0. For x <= 0 returns NaN (IEEE semantics; BUG 19 fixed -- NaN ops now work).
- Postcondition:
(x > 1) => (result >= 0)
fn log2(x: Float64) -> Float64¶
Base-2 logarithm of x. Requires x > 0. For x <= 0 returns NaN (see ln). Complexity: O(1), libm log2.
- Postcondition:
(x > 1) => (result >= 0)
fn log10(x: Float64) -> Float64¶
Base-10 logarithm of x. Requires x > 0. For x <= 0 returns NaN (see ln). Complexity: O(1), libm log10.
- Postcondition:
(x > 1) => (result >= 0)
fn log1p(x: Float64) -> Float64¶
ln(1 + x), accurate for small x. Requires x > -1. Uses the alternating series x - x^2/2 + x^3/3 - ... for |x| <= 1e-4 and libm ln(1+x) otherwise. log1p(-1.0) == -inf (ln 0), log1p(x < -1) returns NaN (IEEE semantics).
- Postcondition:
(x > 0) => (result >= 0)
fn ln_1_plus(x: Float64) -> Float64¶
ln(1 + x), alias of log1p. See log1p for semantics and domain handling.
- Postcondition:
(x > 0) => (result >= 0)
fn pow(base: Float64, exp: Float64) -> Float64¶
base^exp. Uses libm pow; negative bases require an integral exponent (libm semantics). For a negative base with a non-integral exponent returns NaN (IEEE semantics). Complexity: O(1), libm pow.
- Postcondition:
(base > 0) => (result >= 0 || result != result)
fn pow_int(base: Float64, exp: Int) -> Float64¶
base raised to an integer power via binary exponentiation (square-and- multiply). pow_int(2, 10) == 1024, pow_int(2, -2) == 0.25. 0^0 == 1.0; 0^negative == +inf; base^INT_MIN is handled by magnitude (|base| < 1 -> 0, == 1 -> 1, > 1 -> +inf). Complexity: O(log |exp|) multiplications.
- Postcondition:
(exp == 0) => (result == 1)
fn pow_float(base: Float64, exp: Float64) -> Float64¶
base^exp for a float exponent. See pow for semantics and domain handling. Complexity: O(1), libm pow.
- Postcondition:
(base > 0) => (result >= 0 || result != result)
fn sqrt_power(base: Float64, exp: Float64) -> Float64¶
sqrt(base)^exp. Requires base >= 0. For base < 0 returns NaN (IEEE). Complexity: O(1), libm.
- Postcondition:
result >= 0 || result != result
fn exp_pure(x: Float64) -> Float64¶
e^x via the pure range-reduced Taylor series (math.exp_pure), no libm. Returns +inf for x > 700 and 0.0 for x < -700. Complexity: O(25 + log).
- Postcondition:
result >= 0 || result != result
fn ln_pure(x: Float64) -> Float64¶
Natural logarithm via the pure atanh series (math.ln_pure), no libm. Requires x > 0; for x <= 0 returns NaN (IEEE semantics).
- Postcondition:
(x > 1) => (result >= 0 || result != result)
fn log2_pure(x: Float64) -> Float64¶
Base-2 logarithm via the pure series (math.log2_pure), no libm. Requires x > 0; for x <= 0 returns NaN (IEEE semantics).
- Postcondition:
(x > 1) => (result >= 0 || result != result)
fn log10_pure(x: Float64) -> Float64¶
Base-10 logarithm via the pure series (math.log10_pure), no libm. Requires x > 0; for x <= 0 returns NaN (IEEE semantics).
- Postcondition:
(x > 1) => (result >= 0 || result != result)
fn pow_pure(base: Float64, exp: Float64) -> Float64¶
base^exp via the pure exp/ln series (math.pow_pure), no libm. Negative bases are handled before delegation because math.pow_pure declares
requires: base >= 0.0 || exp integral(runtime-enforced in this compiler); a negative base with a non-integral exponent returns NaN (IEEE semantics). Complexity: O(ln + exp).
- Postcondition:
(base > 0) => (result >= 0 || result != result)
factorial.xi¶
fn factorial(n: Int) -> Int¶
n! for n >= 0. Returns 0 for n < 0 (documented) and 0 (documented overflow) when the true value exceeds Int range (n > 20). Complexity: O(n).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n == 0 || n == 1) => (result == 1) - Postcondition:
(n >= 21) => (result == 0) - Postcondition:
result >= 0
fn double_factorial(n: Int) -> Int¶
Double factorial n!! = product of n, n-2, n-4, ... down to 1 (odd n) or 2 (even n). Returns 0 for n < 0 and 0 (documented overflow) when the value exceeds Int range. Complexity: O(n/2).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n == 0 || n == 1) => (result == 1) - Postcondition:
(n >= 34) => (result == 0) - Postcondition:
result >= 0
fn subfactorial(n: Int) -> Int¶
Derangement count !n: the number of fixed-point-free permutations of n items. Uses the recurrence D(0)=1, D(1)=0, D(n) = (n-1)(D(n-1)+D(n-2)). Returns 0 for n < 0 and 0 (documented overflow) when D(n) exceeds Int range. Complexity: O(n).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n == 0) => (result == 1) - Postcondition:
(n == 1) => (result == 0) - Postcondition:
(n >= 21) => (result == 0) - Postcondition:
result >= 0
fn multifactorial(n: Int, k: Int) -> Int¶
k-th multifactorial of n: product n, n-k, n-2k, ... down to the smallest positive term. Returns 0 for n < 0 or k <= 0 (documented) and 0 (documented overflow) when the value exceeds Int range. Complexity: O(n/k).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(k <= 0) => (result == 0) - Postcondition:
(n >= 0 && k > 0 && n <= 1) => (result == 1) - Postcondition:
result >= 0
fn binomial(n: Int, k: Int) -> Int¶
Binomial coefficient C(n, k). Returns 0 for invalid input (n < 0, k < 0, k > n) and 0 (documented overflow) when C(n, k) exceeds Int range. Uses the multiplicative form with a per-step overflow guard. Complexity: O(min(k, n - k)).
- Postcondition:
(n < 0 || k < 0 || k > n) => (result == 0) - Postcondition:
(n >= 0 && (k == 0 || k == n)) => (result == 1) - Postcondition:
(n >= 2 && k == 1) => (result == n) - Postcondition:
result >= 0
fn binomial_coeff(n: Int, k: Int) -> Int¶
Alias of binomial. Complexity: O(min(k, n - k)).
- Postcondition:
(n < 0 || k < 0 || k > n) => (result == 0) - Postcondition:
result >= 0
fn multinomial(n: Int, ks: &Vec[Int]) -> Int¶
Multinomial coefficient n!/(k1! k2! ... km!) where the ki sum to n. Returns 0 when the entries are negative or do not sum to n, and 0 (documented overflow) when the value exceeds Int range. Computed as a chain of binomial coefficients. Complexity: O(m * min(k_i, ...)).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(ks.len() == 0 && n != 0) => (result == 0) - Postcondition:
(ks.len() == 0 && n == 0) => (result == 1) - Postcondition:
result >= 0
fn falling_factorial(x: Int, k: Int) -> Int¶
Falling factorial x * (x-1) * ... * (x-k+1). Returns 0 for k < 0 and 0 (documented overflow) when the magnitude exceeds Int range. k == 0 gives 1. Complexity: O(k).
- Postcondition:
(k < 0) => (result == 0) - Postcondition:
(k == 0) => (result == 1) - Postcondition:
(x == 0 && k > 0) => (result == 0)
fn rising_factorial(x: Int, k: Int) -> Int¶
Rising factorial x * (x+1) * ... * (x+k-1). Returns 0 for k < 0 and 0 (documented overflow) when the magnitude exceeds Int range. k == 0 gives 1. Complexity: O(k).
- Postcondition:
(k < 0) => (result == 0) - Postcondition:
(k == 0) => (result == 1) - Postcondition:
(x == 0 && k > 0) => (result == 0)
fn stirling_first(n: Int, k: Int) -> Int¶
Unsigned Stirling number of the first kind s(n, k): permutations of n items with exactly k cycles. Row DP over s(n,k) = s(n-1,k-1) + (n-1)s(n-1,k) with s(0,0) = 1. Returns 0 for invalid input (n < 0, k < 0, k > n) and 0 (documented overflow) when the value exceeds Int range. Complexity: O(nk).
- Postcondition:
(n < 0 || k < 0 || k > n) => (result == 0) - Postcondition:
(n == 0 && k == 0) => (result == 1) - Postcondition:
(n >= 1 && k == n) => (result == 1) - Postcondition:
(n >= 1 && k == 0) => (result == 0) - Postcondition:
result >= 0
fn stirling_second(n: Int, k: Int) -> Int¶
Stirling number of the second kind S(n, k): partitions of an n-element set into k nonempty blocks. Row DP over S(n,k) = kS(n-1,k) + S(n-1,k-1) with S(0,0) = 1. Returns 0 for invalid input and 0 (documented overflow) when the value exceeds Int range. Complexity: O(nk).
- Postcondition:
(n < 0 || k < 0 || k > n) => (result == 0) - Postcondition:
(n == 0 && k == 0) => (result == 1) - Postcondition:
(n >= 1 && k == n) => (result == 1) - Postcondition:
(n >= 1 && k == 0) => (result == 0) - Postcondition:
result >= 0
fn bell(n: Int) -> Int¶
Bell number B(n): the number of partitions of an n-element set. Computed via the Aitken / Bell triangle, whose rightmost entry of row k is B(k+1) (row 0 is [1] and B(0) = B(1) = 1), so the value is the last entry of row n - 1. Returns 0 for n < 0 and 0 (documented overflow) when B(n) exceeds Int range. Complexity: O(n^2).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n == 0 || n == 1) => (result == 1) - Postcondition:
result >= 0
fn catalan(n: Int) -> Int¶
Catalan number C_n = C(2n, n)/(n+1). Returns 0 for n < 0 and 0 (documented overflow) when the value exceeds Int range (n > 33). Complexity: O(n).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n == 0) => (result == 1) - Postcondition:
(n >= 34) => (result == 0) - Postcondition:
result >= 0
fn eulerian(n: Int, k: Int) -> Int¶
Eulerian number A(n, k): permutations of n items with exactly k ascents. Row DP over A(n,k) = (n-k)A(n-1,k-1) + (k+1)A(n-1,k) with A(0,0) = 1 and A(n,n) = 0. Returns 0 for invalid input and 0 (documented overflow) when the value exceeds Int range. Complexity: O(n*k).
- Postcondition:
(n < 0 || k < 0 || k > n) => (result == 0) - Postcondition:
(n == 0 && k == 0) => (result == 1) - Postcondition:
(n >= 1 && k == 0) => (result == 1) - Postcondition:
(n >= 1 && k == n) => (result == 0) - Postcondition:
result >= 0
fn narayana(n: Int, k: Int) -> Int¶
Narayana number N(n, k) = C(n, k) * C(n, k-1) / n. Returns 0 for invalid input (n <= 0, k <= 0, k > n) and 0 (documented overflow) when the value exceeds Int range. Complexity: O(min(k, n-k)).
- Postcondition:
(n <= 0 || k <= 0 || k > n) => (result == 0) - Postcondition:
(n >= 1 && k == 1) => (result == 1) - Postcondition:
result >= 0
fn lah(n: Int, k: Int) -> Int¶
Lah number L(n, k) = C(n, k) * C(n-1, k-1) * (n-k)!. Returns 0 for invalid input (n <= 0, k <= 0, k > n) and 0 (documented overflow) when the value exceeds Int range. Complexity: O(min(k, n-k) + (n-k)).
- Postcondition:
(n <= 0 || k <= 0 || k > n) => (result == 0) - Postcondition:
(n >= 1 && k == n) => (result == 1) - Postcondition:
result >= 0
fn motzkin(n: Int) -> Int¶
Motzkin number M_n (lattice paths / non-crossing partitions). Uses the closed recurrence M(n) = ((2n+1)M(n-1) + (3n-3)M(n-2))/(n+2), M(0) = M(1) = 1. Returns 0 for n < 0 and 0 (documented overflow) when M_n exceeds Int range. Complexity: O(n).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n == 0 || n == 1) => (result == 1) - Postcondition:
result >= 0
fn schroeder(n: Int) -> Int¶
Large Schroder number S_n. Uses S(n) = S(n-1) + sum_{k=0..n-1} S(k)*S(n-1-k), S(0) = 1. Returns 0 for n < 0 and 0 (documented overflow) when S_n exceeds Int range. Complexity: O(n^2).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n == 0) => (result == 1) - Postcondition:
result >= 0
fn partition_count(n: Int) -> Int¶
Number of integer partitions p(n). Uses the Euler pentagonal-number recurrence p(n) = sum_{k != 0} (-1)^(k+1) p(n - k(3k-1)/2). Returns 0 for n < 0 and 0 (documented overflow) when p(n) exceeds Int range (n > 255). Complexity: O(n * sqrt(n)).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n == 0) => (result == 1) - Postcondition:
result >= 0
fn integer_partitions(n: Int) -> Vec[Vec[Int]]¶
All integer partitions of n as lists (each partition non-increasing, starting from the largest part; the result order is unspecified). Returns an empty list for n < 0; n == 0 yields a single empty partition. Complexity: O(p(n) * n).
- Postcondition:
(n < 0) => (result.len() == 0) - Postcondition:
(n == 0) => (result.len() == 1) - Postcondition:
(n > 0) => (result.len() >= 1)
fn derangements(n: Int) -> Int¶
Number of derangements of n items (fixed-point-free permutations). Alias of subfactorial. Returns 0 for n < 0 and 0 (documented overflow). Complexity: O(n).
- Postcondition:
(n < 0) => (result == 0) - Postcondition:
(n == 0) => (result == 1) - Postcondition:
(n >= 21) => (result == 0) - Postcondition:
result >= 0
fn bell_triangle(n: Int) -> Vec[Vec[Int]]¶
Bell triangle rows up to n: rows 0..n inclusive. Row 0 is [1]; each later row starts with the previous row's last entry and continues with the sum of the entry to its left and the one above-left, so the rightmost entry of row k is B(k+1) and the leftmost is B(k). Returns an empty list for n < 0. Cells that would overflow Int are stored as 0 (documented). Complexity: O(n^2).
- Postcondition:
(n < 0) => (result.len() == 0) - Postcondition:
(n == 0) => (result.len() == 1) - Postcondition:
(n > 0) => (result.len() > 1)
finance.xi¶
fn pv(rate: Float64, nper: Float64, pmt: Float64, fv: Float64) -> Float64¶
Present value of an annuity and lump sum: PV = -(FV + pmt((1+r)^n-1)/r) / (1+r)^n. r == 0 uses PV = -(FV + pmtn). Complexity: O(1).
- Postcondition:
(rate == 0) => (result == -(fv + pmt * nper))
fn fv(rate: Float64, nper: Float64, pmt: Float64, pv: Float64) -> Float64¶
Future value of an annuity and lump sum: FV = PV (1+r)^n + pmt((1+r)^n-1) / r. r == 0 uses FV = PV + pmtn. Complexity: O(1).
- Postcondition:
(rate == 0) => (result == pv + pmt * nper)
fn npv(rate: Float64, cashflows: &Vec[Float64]) -> Float64¶
Net present value of a cashflow series discounted from t = 0 (the first element is the undiscounted cashflow at time zero). Complexity: O(n).
- Postcondition:
(cashflows.len() == 0) => (result == 0)
fn irr(cashflows: &Vec[Float64]) -> Float64¶
Internal rate of return: the rate r with npv(r, cashflows) == 0, found by bisection over [-0.99, 10] (200 iterations). NaN when no sign change exists. Complexity: O(iters * n).
- Postcondition:
(result != result) || (result >= -0.99 && result <= 10)
fn mirr(cashflows: &Vec[Float64], finance_rate: Float64, reinvest_rate: Float64) -> Float64¶
Modified internal rate of return: MIRR = ((FV_positive / PV_negative)^(1/n) - 1) where positive cashflows compound at reinvest_rate and negative ones discount at finance_rate. NaN when no negative cashflow exists. Complexity: O(n).
- Postcondition:
(cashflows.len() == 0) => (result != result)
fn pmt(rate: Float64, nper: Float64, pv: Float64, fv: Float64) -> Float64¶
Periodic payment of an annuity: pmt = (fv - pv (1+r)^n) r / ((1+r)^n - 1); r == 0 uses (fv - pv)/n. Complexity: O(1).
- Postcondition:
(nper == 0) => (result != result) - Postcondition:
(rate == 0 && nper != 0) => (result == (fv - pv) / nper)
fn ipmt(rate: Float64, per: Int, nper: Float64, pv: Float64) -> Float64¶
Interest portion of the payment in period per (1-based) for a loan of pv amortized at rate over nper periods (fv = 0). Complexity: O(per).
- Postcondition:
(per < 1) => (result != result) - Postcondition:
(rate == 0 && per >= 1 && nper != 0) => (result == 0)
fn ppmt(rate: Float64, per: Int, nper: Float64, pv: Float64) -> Float64¶
Principal portion of the payment in period per. Complexity: O(per).
- Postcondition:
(per < 1) => (result != result)
fn nper(rate: Float64, pmt: Float64, pv: Float64, fv: Float64) -> Float64¶
Number of periods to reach fv from pv paying pmt per period: n = ln((pmt - fv r) / (pmt + pv r)) / ln(1 + r). Complexity: O(1).
- Postcondition:
(rate == 0 && pmt == 0) => (result != result) - Postcondition:
(rate == 0 && pmt != 0) => (result == -(pv + fv) / pmt)
fn rate(nper: Float64, pmt: Float64, pv: Float64, fv: Float64) -> Float64¶
Interest rate implied by an annuity: bisection on the fv identity over [-0.999, 10] (200 iterations). NaN when no root exists. Complexity: O(200).
- Postcondition:
(result != result) || (result >= -0.999 && result <= 10)
fn annuity(rate: Float64, nper: Float64, pmt: Float64) -> Float64¶
Present value of a level annuity paying pmt for nper periods at rate. Complexity: O(1).
- Postcondition:
(rate != 0) || (result == pmt * nper)
fn perpetuity(pmt: Float64, rate: Float64) -> Float64¶
Present value of a level perpetuity pmt / rate. NaN for rate <= 0. Complexity: O(1).
- Postcondition:
(rate <= 0) => (result != result) - Postcondition:
(rate > 0) => (result == pmt / rate)
fn bond_price(face: Float64, coupon: Float64, ytm: Float64, n: Int, freq: Int) -> Float64¶
Price of a coupon bond with face, annual coupon rate, yield to maturity, n years and freq coupons per year. Complexity: O(n * freq).
- Postcondition:
(face <= 0 || freq <= 0) => (result != result)
fn bond_yield(face: Float64, coupon: Float64, price: Float64, n: Int, freq: Int) -> Float64¶
Yield to maturity of a coupon bond, found by bisection on the price equation over [-0.999, 10] (200 iterations). NaN when no root exists. Complexity: O(200 * n * freq).
- Postcondition:
(result != result) || (result >= -0.999 && result <= 10)
fn duration(face: Float64, coupon: Float64, ytm: Float64, n: Int, freq: Int) -> Float64¶
Macaulay duration of a coupon bond (years). Complexity: O(n * freq).
- Postcondition:
(face > 0 && freq > 0) || (result != result)
fn convexity(face: Float64, coupon: Float64, ytm: Float64, n: Int, freq: Int) -> Float64¶
Convexity of a coupon bond (years squared). Complexity: O(n * freq).
- Postcondition:
(face > 0 && freq > 0) || (result != result)
fn option_call(s: Float64, k: Float64, t: Float64, r: Float64, sigma: Float64) -> Float64¶
Black-Scholes price of a European call. Complexity: O(1).
- Postcondition:
(s > 0 && k > 0 && t >= 0 && sigma > 0) || (result != result)
fn option_put(s: Float64, k: Float64, t: Float64, r: Float64, sigma: Float64) -> Float64¶
Black-Scholes price of a European put. Complexity: O(1).
- Postcondition:
(s > 0 && k > 0 && t >= 0 && sigma > 0) || (result != result)
fn option_call_delta(s: Float64, k: Float64, t: Float64, r: Float64, sigma: Float64) -> Float64¶
Delta of a European call: N(d1). Complexity: O(1).
- Postcondition:
(s > 0 && k > 0 && t >= 0 && sigma > 0) || (result != result) - Postcondition:
(s <= 0 || k <= 0 || t < 0 || sigma <= 0) || (result != result) || (result >= 0 && result <= 1)
fn option_put_delta(s: Float64, k: Float64, t: Float64, r: Float64, sigma: Float64) -> Float64¶
Delta of a European put: N(d1) - 1. Complexity: O(1).
- Postcondition:
(s > 0 && k > 0 && t >= 0 && sigma > 0) || (result != result) - Postcondition:
(s <= 0 || k <= 0 || t < 0 || sigma <= 0) || (result != result) || (result >= -1 && result <= 0)
fn option_gamma(s: Float64, k: Float64, t: Float64, r: Float64, sigma: Float64) -> Float64¶
Gamma of a European option: phi(d1) / (S sigma sqrt(T)). Complexity: O(1).
- Postcondition:
(result != result) || (result >= 0)
fn option_theta(s: Float64, k: Float64, t: Float64, r: Float64, sigma: Float64) -> Float64¶
Theta of a European call (per year): -(S phi(d1) sigma)/(2 sqrt(T)) - r K e^{-rT} N(d2). Complexity: O(1).
- Postcondition:
(s > 0 && k > 0 && t > 0 && sigma > 0) || (result != result)
fn option_vega(s: Float64, k: Float64, t: Float64, r: Float64, sigma: Float64) -> Float64¶
Vega of a European option: S phi(d1) sqrt(T) / 100 (per 1% volatility). Complexity: O(1).
- Postcondition:
(result != result) || (result >= 0)
fn option_rho(s: Float64, k: Float64, t: Float64, r: Float64, sigma: Float64) -> Float64¶
Rho of a European call: K T e^{-rT} N(d2) / 100. Complexity: O(1).
- Postcondition:
(result != result) || (result >= 0)
fn implied_volatility(market: Float64, s: Float64, k: Float64, t: Float64, r: Float64) -> Float64¶
Black-Scholes implied volatility for a European call price, by Newton iteration (100 iterations from sigma = 0.2). NaN when no solution is found (e.g. an arbitrage-violating price). Complexity: O(100).
- Postcondition:
(result != result) || (result > 0)
fn cagr(begin_value: Float64, end_value: Float64, years: Float64) -> Float64¶
Compound annual growth rate (end/begin)^(1/years) - 1. NaN for years <= 0 or non-positive begin. Complexity: O(1).
- Postcondition:
(begin_value <= 0 || years <= 0) => (result != result)
fn sharpe_ratio(returns: &Vec[Float64], rf: Float64) -> Float64¶
Sharpe ratio (mean(returns) - rf) / sample_stddev(returns). NaN for fewer than 2 returns. Complexity: O(n).
- Postcondition:
(returns.len() < 2) => (result != result)
fn sortino_ratio(returns: &Vec[Float64], rf: Float64) -> Float64¶
Sortino ratio (mean(returns) - rf) / downside_deviation(returns, rf), where the downside deviation is the sqrt of the mean of squared returns below rf. NaN for fewer than 2 returns. Complexity: O(n).
- Postcondition:
(returns.len() < 2) => (result != result)
fn calmar_ratio(returns: &Vec[Float64], max_drawdown: Float64) -> Float64¶
Calmar ratio annualized mean return / |max drawdown|. NaN for a zero drawdown or fewer than 2 returns. Complexity: O(n).
- Postcondition:
(returns.len() < 2 || max_drawdown == 0) => (result != result)
fn value_at_risk(returns: &Vec[Float64], alpha: Float64, method: Int) -> Float64¶
Value at risk at confidence alpha: method 0 = historical quantile, method 1 = parametric (normal) quantile. Returns a positive loss. Complexity: O(n log n) historical / O(n) parametric.
- Postcondition:
(returns.len() == 0) => (result != result) - Postcondition:
(returns.len() > 0 && (alpha <= 0 || alpha >= 1)) => (result != result)
fn cvar(returns: &Vec[Float64], alpha: Float64) -> Float64¶
Conditional value at risk: mean of the returns below the alpha-VaR level. NaN for fewer than 1 tail observation. Complexity: O(n log n).
- Postcondition:
(returns.len() == 0) => (result != result) - Postcondition:
(returns.len() > 0 && (alpha <= 0 || alpha >= 1)) => (result != result)
fn drawdown(returns: &Vec[Float64]) -> Vec[Float64]¶
Drawdown series of the returns (cumulative product minus 1, then peak-to-trough). Complexity: O(n).
- Postcondition:
(returns.len() == 0) => (result.len() == 0)
fn beta(asset_returns: &Vec[Float64], market_returns: &Vec[Float64]) -> Float64¶
Systematic risk of an asset versus the market: covariance / market variance. NaN for fewer than 2 observations or zero market variance. Complexity: O(n).
- Postcondition:
(asset_returns.len() < 2 || market_returns.len() != asset_returns.len()) => (result != result)
fn alpha(asset_returns: &Vec[Float64], market_returns: &Vec[Float64], rf: Float64) -> Float64¶
Jensen's alpha: mean(asset) - (rf + beta * (mean(market) - rf)). Complexity: O(n).
- Postcondition:
(asset_returns.len() == 0 || market_returns.len() != asset_returns.len()) => (result != result)
fn treynor_ratio(returns: &Vec[Float64], beta: Float64, rf: Float64) -> Float64¶
Treynor ratio (mean(returns) - rf) / beta. NaN for beta <= 0. Complexity: O(n).
- Postcondition:
(returns.len() == 0 || beta <= 0) => (result != result)
fixed.xi¶
fn mul(a: Int, b: Int, scale: Int) -> Int¶
Fixed-point multiply: round(a * b / scale), halves away from zero. The product is formed exactly in 128 bits and divided by the scale ONCE, so no intermediate is truncated (the classic overflow bug of (a/scale)*b). Saturates at INT_MIN/INT_MAX when the true value exceeds the Int range; scale <= 0 returns 0 (documented). Complexity: O(1).
- Postcondition:
(scale <= 0) => (result == 0) - Postcondition:
(a == 0) || (b == 0) => (result == 0) - Postcondition:
(scale > 0) && (b == scale) => (result == a)
fn sum_mul(a: &Vec[Int], b: &Vec[Int], scale: Int) -> Int¶
Fixed-point dot product: round(sum_i(a[i] * b[i]) / scale), halves away from zero. Products and their sum accumulate exactly in 128 bits and the scale division happens ONCE at the end; the accumulator saturates to INT_MAX/INT_MIN (documented) only if the raw product sum would leave the 128-bit range. Empty vectors or a length mismatch return 0; scale <= 0 returns 0. Complexity: O(n).
- Postcondition:
(scale <= 0) => (result == 0) - Postcondition:
(a.len() == 0) || (b.len() == 0) || (a.len() != b.len()) => (result == 0)
fn sum_sq(values: &Vec[Int], scale: Int) -> Int¶
Fixed-point sum of squares: round(sum_i(v[i]^2) / scale), halves away from zero. Exact 128-bit accumulation, one scale division at the end; saturates at INT_MAX (documented) if the square sum would leave the 128-bit range. Empty vector or scale <= 0 returns 0. Complexity: O(n).
- Postcondition:
(scale <= 0) => (result == 0) - Postcondition:
(values.len() == 0) => (result == 0)
fn log2(x: Int, scale: Int) -> Int¶
Fixed-point base-2 logarithm: round(log2(x / scale) * scale), halves away from zero. x <= 0 or scale <= 0 returns 0 (documented). The result is exact for exact powers of two; otherwise the atanh series is truncated at z^11 (relative error below 1e-6 unit at the working precision) so the last few output units may differ from a correctly-rounded libm value. Complexity: O(log x).
- Postcondition:
(scale <= 0) => (result == 0) - Postcondition:
(x <= 0) => (result == 0) - Postcondition:
(scale > 0) && (x == scale) => (result == 0)
fn ln(x: Int, scale: Int) -> Int¶
Fixed-point natural logarithm: round(ln(x / scale) * scale), halves away from zero. x <= 0 or scale <= 0 returns 0 (documented). ln(scale) is exactly 0; other values carry the atanh-series truncation error (relative error below 1e-6 unit at the working precision). Complexity: O(log x).
- Postcondition:
(scale <= 0) => (result == 0) - Postcondition:
(x <= 0) => (result == 0) - Postcondition:
(scale > 0) && (x == scale) => (result == 0)
fn exp(x: Int, scale: Int) -> Int¶
Fixed-point exponential: round(exp(x / scale) * scale), halves away from zero. Argument reduction via k = round((x/scale) / ln2) with a 12-digit ln2, e^r on |r| <= ln2/2 by a 12-term Taylor, then an exact 2^k scaling; the true value saturates at INT_MAX for large x. Very negative x (e^(x/scale) below half a scale unit) returns 0. x == 0 returns scale; scale <= 0 returns 0. Complexity: O(1) (bounded series).
- Postcondition:
(scale <= 0) => (result == 0) - Postcondition:
(x == 0) && (scale > 0) => (result == scale)
fn pow_int(x: Int, e: Int, scale: Int) -> Int¶
Fixed-point integer power: round((x / scale)^e * scale), halves away from zero, e any sign. Positive exponents use square-and-multiply through the saturating mul kernel; negative exponents reciprocate the positive power (scale^2 / p), saturating to INT_MAX when that power underflows to 0 (including x == 0, documented). e == 0 or x == scale returns scale; x == INT_MIN exponent is documented as 0 (pathological input). scale <= 0 returns 0. Complexity: O(log |e|).
- Postcondition:
(scale <= 0) => (result == 0) - Postcondition:
(e == 0) && (scale > 0) => (result == scale) - Postcondition:
(x == scale) && (scale > 0) => (result == scale)
fn sin(x: Int, scale: Int) -> Int¶
Fixed-point sine: round(sin(x / scale) * scale), halves away from zero, where x/scale is the angle in radians. The angle is reduced modulo 2*pi (12-digit tau) into [-pi, pi] and evaluated with the Taylor series through x^13 (residual below 3e-7 rad); the total error stays under one scale unit for scales up to ~2^10 and grows linearly beyond. Scale domain 1..2^44; scale <= 0 or scale > 2^44 returns 0 (documented). Complexity: O(1) (bounded series).
- Postcondition:
(scale <= 0) => (result == 0) - Postcondition:
(x == 0) && (scale > 0) && (scale <= 17592186044416) => (result == 0)
fn cos(x: Int, scale: Int) -> Int¶
Fixed-point cosine: round(cos(x / scale) * scale), halves away from zero, same range reduction as sin. The series runs through x^12 (residual below 2e-5 rad at |x| = pi), keeping the total error under one scale unit for scales up to ~2^12. cos(0) returns scale; scale <= 0 or scale > 2^44 returns 0 (documented). Complexity: O(1) (bounded series).
- Postcondition:
(scale <= 0) => (result == 0) - Postcondition:
(x == 0) && (scale > 0) && (scale <= 17592186044416) => (result == scale)
fn mse(actual: &Vec[Int], predicted: &Vec[Int], scale: Int) -> Int¶
Fixed-point mean squared error: round(sum_i((a[i] - p[i])^2) / (n * scale)), halves away from zero. This matches the float stats semantics -- the mean of the squared errors -- carried in scaled integers: with both vectors scaled by S the real MSE is mean((d_i/S)^2), so the scaled result is sum(d_i^2) / (n * S). Vector lengths must match; empty vectors, a length mismatch or scale <= 0 return 0 (documented). Differences beyond +/-2^62 are clamped (outside the supported fixed-point domain) and the 128-bit square sum saturates to INT_MAX (documented). Complexity: O(n).
- Postcondition:
(scale <= 0) => (result == 0) - Postcondition:
(actual.len() == 0) || (predicted.len() != actual.len()) => (result == 0) - Postcondition:
result >= 0
fn interp_linear(ticks: &Vec[Int], values: &Vec[Int], x: Int) -> Int¶
Linear interpolation over an ordered (tick, value) table: returns the value at x, rounded to nearest (halves away from zero). The tick table must be non-decreasing (documented; unsorted tables are undefined). x at or below ticks[0] clamps to values[0]; x at or above the last tick clamps to the last value. Repeated ticks define zero-width segments and are skipped. Empty/mismatched tables return 0 (documented). The exact 128-bit numerator (v1 - v0) * (x - t0) is divided once by the tick span. Complexity: O(n).
- Postcondition:
(values.len() == 0) => (result == 0) - Postcondition:
(ticks.len() != values.len()) => (result == 0)
fn softmax(logits: &Vec[Int], scale: Int) -> Vec[Int]¶
Fixed-point softmax over scaled logits: returns a Vec[Int] of scaled probabilities whose entries sum EXACTLY to scale (floor each entry, then hand the whole residue to the first maximum -- the sheet's floor + residue-to-max rule). The denominator accumulates exactly in 128 bits, so long inputs do not drift. The maximum logit maps to exp(0) = scale, which keeps the denominator >= scale and every entry non-negative; logit differences below -2^62 are clamped (exp underflows to 0 anyway). Empty input or scale <= 0 returns an empty vector (documented). Complexity: O(n) plus the bounded exp series per element.
- Postcondition:
(scale <= 0) => (result.len() == 0) - Postcondition:
(scale > 0) => (result.len() == logits.len())
fuzzy.xi¶
fn fuzzy_set(universe: &Vec[Int], membership: fn(Int) -> Float64) -> Vec[Float64]¶
Membership degrees of the universe elements under the membership fn. Returns an empty vector for an empty universe. Complexity: O(n).
- Postcondition:
result.len() == universe.len()
fn membership(set: &Vec[Float64], element: Int) -> Float64¶
Membership degree of element in a fuzzy set; elements outside the set's range yield 0.0 (documented). Complexity: O(1).
- Postcondition:
(element < 0 || element >= set.len()) => (result == 0)
fn fuzzy_logic(a: Float64, b: Float64, op: Str) -> Float64¶
Triangular norm/conorm or negation of two truth values, selected by op: "and" -> min, "or" -> max, "not" -> 1 - a, "prod" -> ab, "sum" -> a + b - ab (probabilistic or). Unknown op returns NaN. Complexity: O(1).
- Postcondition:
(op == "and") => (result <= a && result <= b) - Postcondition:
(op == "or") => (result >= a && result >= b) - Postcondition:
(op == "not") => (result == 1 - a) - Postcondition:
(op == "prod") => (result == a * b) - Postcondition:
(op == "sum") => (result == a + b - a * b)
fn fuzzy_intersection(a: &Vec[Float64], b: &Vec[Float64]) -> Vec[Float64]¶
Pointwise minimum (intersection) of two fuzzy sets; empty on length mismatch. Complexity: O(n).
- Postcondition:
(a.len() != b.len()) => (result.len() == 0) - Postcondition:
(a.len() == b.len()) => (result.len() == a.len())
fn fuzzy_union(a: &Vec[Float64], b: &Vec[Float64]) -> Vec[Float64]¶
Pointwise maximum (union) of two fuzzy sets; empty on length mismatch. Complexity: O(n).
- Postcondition:
(a.len() != b.len()) => (result.len() == 0) - Postcondition:
(a.len() == b.len()) => (result.len() == a.len())
fn fuzzy_complement(a: &Vec[Float64]) -> Vec[Float64]¶
Pointwise complement 1 - a of a fuzzy set. Complexity: O(n).
- Postcondition:
result.len() == a.len()
fn fuzzy_relation(r: &Vec[Vec[Float64]]) -> Bool¶
Validates that every membership degree of the fuzzy relation matrix lies in [0, 1]. TODO(compiler): NOT IMPLEMENTABLE in this compiler build - the relation is a Vec[Vec[Float64]] whose element reads return garbage (BUG 23 #1 residual; verified by minimal probe). Keep the frozen signature; revisit when nested float Vec reads land.
fn fuzzy_composition(r: &Vec[Vec[Float64]], s: &Vec[Vec[Float64]]) -> Vec[Vec[Float64]]¶
Max-min composition of two fuzzy relations. TODO(compiler): NOT IMPLEMENTABLE in this compiler build - the relations are Vec[Vec[Float64]] whose element reads return garbage (BUG 23 #1 residual; verified by minimal probe). Keep the frozen signature; revisit when nested float Vec reads land.
fn defuzzification(set: &Vec[Float64], universe: &Vec[Float64]) -> Float64¶
Centroid (center-of-gravity) defuzzification of a fuzzy set over the universe values: sum(u_i m_i) / sum(m_i). NaN when the total membership is zero or the lengths differ. Complexity: O(n).
- Postcondition:
(set.len() != universe.len()) => (result != result) - Postcondition:
(set.len() == 0 || universe.len() == 0) => (result != result)
fn fuzzy_inference(rules: &Vec[Str], facts: &Vec[Float64]) -> Vec[Float64]¶
Aggregated conclusion degrees from fuzzy rules ("a:b:s" = antecedent, consequent, strength): out[j] = max over rules with consequent j of min(facts[a], s). NaN facts propagate as NaN conclusions. Complexity: O(rules).
- Postcondition:
(rules.len() == 0) => (result.len() == 0) - Postcondition:
(rules.len() > 0) => (result.len() == facts.len())
fn mamdani(rules: &Vec[Str], inputs: &Vec[Float64]) -> Vec[Float64]¶
Mamdani-style inference: min implication with max aggregation over the same "a:b:s" rule convention (alias of fuzzy_inference). Complexity: O(rules).
- Postcondition:
(rules.len() == 0) => (result.len() == 0) - Postcondition:
(rules.len() > 0) => (result.len() == inputs.len())
fn sugeno(rules: &Vec[Str], inputs: &Vec[Float64]) -> Float64¶
Sugeno-style weighted crisp output: rules are decimal strengths s_i and the result is sum(s_i * inputs_i) / sum(s_i). NaN when the weight sum is zero or the rule format is invalid. Complexity: O(rules).
- Postcondition:
(rules.len() == 0 || inputs.len() == 0) => (result != result)
fn fuzzy_control(setpoint: Float64, measurement: Float64, kp: Float64, ki: Float64) -> Float64¶
Fuzzy logic controller output (position form): kp * error + ki * error with error = setpoint - measurement (integral term approximated proportionally; documented). Complexity: O(1).
- Postcondition:
(setpoint == measurement) => (result == 0)
fn fuzzy_decision(alternatives: &Vec[Float64], weights: &Vec[Float64]) -> Int¶
Index of the best fuzzy-weighted alternative: argmax of alternatives_i * weights_i. Returns -1 for empty or mismatched input. Complexity: O(n).
- Postcondition:
(alternatives.len() != weights.len() || alternatives.len() == 0) => (result == -1) - Postcondition:
(alternatives.len() == weights.len() && alternatives.len() > 0) => (result >= 0 && result < alternatives.len())
game_theory.xi¶
fn nash_equilibrium(payoffs: &Vec[Vec[Float64]]) -> Vec[(Float64, Float64)]¶
Mixed Nash equilibria of a two-player bimatrix game. TODO(compiler): NOT IMPLEMENTABLE in this compiler build - the payoff matrix is a Vec[Vec[Float64]] whose element reads return garbage (BUG 23 #1 residual; verified by minimal probe). Keep the frozen signature; revisit when nested float Vec reads land.
fn minimax(payoffs: &Vec[Vec[Float64]]) -> Float64¶
Minimax value of a zero-sum game. TODO(compiler): NOT IMPLEMENTABLE - see nash_equilibrium (payoff matrix reads return garbage in this compiler build).
fn alpha_beta(game: fn(&Vec[Int]) -> Float64, depth: Int, alpha: Float64, beta: Float64) -> Float64¶
Minimax search with alpha-beta pruning over a game tree given by
game(move_sequence) -> terminal value. Searches to fixed depth; at a terminal or depth-0 node the game value is returned. Complexity: O(branch^depth) with pruning.
- Precondition:
depth >= 0
fn dominant_strategy(payoffs: &Vec[Vec[Float64]]) -> Option[Int]¶
Index of a strictly dominant strategy, if any. TODO(compiler): NOT IMPLEMENTABLE - see nash_equilibrium (payoff matrix reads return garbage in this compiler build).
fn pareto_optimal(payoffs: &Vec[Vec[Float64]]) -> Vec[Int]¶
Indices of Pareto-optimal strategy profiles. TODO(compiler): NOT IMPLEMENTABLE - see nash_equilibrium (payoff matrix reads return garbage in this compiler build).
fn cooperative_game(v: fn(&Vec[Int]) -> Float64, n: Int) -> (Float64, Float64)¶
Grand-coalition value v(all players) and a feasible imputation: the tuple is (grand_coalition_value, equal-share imputation value). Complexity: O(1) plus the cost of v on the grand coalition.
- Postcondition:
(n <= 0) => (result._1 == 0) - Postcondition:
(n > 0) => (result._1 == result._0 / (?))
fn shapley_value(v: fn(&Vec[Int]) -> Float64, n: Int) -> Vec[Float64]¶
Shapley value of each of the n players: the average marginal contribution over all player permutations (exact for n <= 6 via permutations_enum, approximate for larger n by iterating cyclic shifts). Complexity: O(n! * n) exact / O(n^2) approximate.
- Postcondition:
(n <= 0) => (result.len() == 0) - Postcondition:
(n > 0) => (result.len() == n)
fn game_core(v: fn(&Vec[Int]) -> Float64, n: Int) -> Vec[Vec[Float64]]¶
Imputations in the core of a cooperative game. For n == 2 the core is the set of allocations (x1, x2) with x1 + x2 = v({0,1}) and x_i >= v({i}); the function returns a sample of its extreme points. For other n the function returns a documented greedy sample. Complexity: O(2^n * v) for small n.
- Postcondition:
(n <= 0) => (result.len() == 0) - Postcondition:
(n == 1) => (result.len() == 1) - Postcondition:
(n == 2) => (result.len() == 2) - Postcondition:
(n > 2) => (result.len() == 1)
fn auction(bids: &Vec[Float64], reserve: Float64) -> (Float64, Int)¶
Winning price and winner index of a first-price auction with a reserve: the highest bid at or above the reserve wins at its own bid. Returns (price, winner_index) or (0, -1) when no bid clears the reserve. Complexity: O(n).
- Postcondition:
(result._1 >= 0) => (result._0 >= reserve && result._1 < bids.len()) - Postcondition:
(result._1 == -1) => (result._0 == 0)
fn mechanism_design(type_space: &Vec[Float64], values: fn(Int) -> Float64) -> Vec[Float64]¶
Dominant-strategy incentive-compatible allocation: bidder i receives a share of the type-space value proportional to values(i). Complexity: O(n).
- Postcondition:
(type_space.len() == 0) => (result.len() == 0) - Postcondition:
(type_space.len() > 0) => (result.len() == type_space.len())
fn evolutionary_game(payoffs: &Vec[Vec[Float64]], population: &Vec[Float64]) -> Vec[Float64]¶
Next-generation population shares under replicator dynamics: x_i' = x_i (f_i - mean) where f_i is the i-th strategy's expected payoff. TODO(compiler): NOT IMPLEMENTABLE in this compiler build - the payoff matrix is a Vec[Vec[Float64]] whose element reads return garbage (BUG 23 #1 residual; verified by minimal probe). Keep the frozen signature; revisit when nested float Vec reads land.
fn replicator_dynamics(payoffs: &Vec[Vec[Float64]], population: &Vec[Float64], steps: Int) -> Vec[Vec[Float64]]¶
Iterated replicator dynamics over
stepsgenerations. TODO(compiler): NOT IMPLEMENTABLE - see evolutionary_game (payoff matrix reads return garbage in this compiler build).
fn prisoner_dilemma(defect: Float64, cooperate: Float64) -> (Float64, Float64)¶
Payoffs of the one-shot prisoner's dilemma: the tuple is (mutual_cooperation, mutual_defection) payoff. Complexity: O(1).
- Postcondition:
result._0 == cooperate && result._1 == defect
graph_theory.xi¶
type WeightedGraph¶
A graph: n vertices (implicitly 0..n-1), an edge list of (u, v) pairs, a parallel weight list (scaled by 1e5), and a directedness flag.
| Field | Type |
|---|---|
n |
Int |
edges |
Vec[(Int, Int)] |
weights |
Vec[Int] |
directed |
Bool |
fn graph_new() -> WeightedGraph¶
Create an empty graph. Complexity: O(1).
- Postcondition:
result.n == 0 && result.edges.len() == 0 && result.weights.len() == 0
fn graph_add_vertex(g: &mut WeightedGraph, v: Int) -> Bool¶
Add vertex v (grows n to v + 1; vertices are implicit ids). Returns true. Complexity: O(v - n).
- Postcondition:
(v < 0) => (result == false) - Postcondition:
(v >= 0) => (result == true && g.n > v)
fn graph_add_edge(g: &mut WeightedGraph, u: Int, v: Int) -> Bool¶
Add an unweighted edge (u, v) (weight 1.0). Adds the vertices first; an undirected graph also stores the reverse edge. Returns false for negative ids. Complexity: O(1) amortized.
- Postcondition:
(u < 0 || v < 0) => (result == false) - Postcondition:
(u >= 0 && v >= 0) => (result == true)
fn graph_add_weighted_edge(g: &mut WeightedGraph, u: Int, v: Int, w: Float64) -> Bool¶
Add a weighted edge (u, v) with weight w (rounded to 1e-5 resolution). Complexity: O(1) amortized.
- Postcondition:
(u < 0 || v < 0 || w != w) => (result == false) - Postcondition:
(u >= 0 && v >= 0 && w == w) => (result == true)
fn graph_remove_vertex(g: &mut WeightedGraph, v: Int) -> Bool¶
Remove vertex v and all incident edges. Returns false when v is absent. Complexity: O(edges).
- Postcondition:
(v < 0 || v >= g.n) => (result == false) - Postcondition:
(v >= 0 && v < g.n) => (result == true)
fn graph_remove_edge(g: &mut WeightedGraph, u: Int, v: Int) -> Bool¶
Remove the edge (u, v); an undirected graph removes the reverse too. Returns false when no such edge exists. Complexity: O(edges).
- Postcondition:
(u < 0 || v < 0) => (result == false) - Postcondition:
(result == true) => (graph_has_edge(g, u, v) == false)
fn graph_has_vertex(g: &WeightedGraph, v: Int) -> Bool¶
Whether v is present. Complexity: O(1).
- Postcondition:
result == (v >= 0 && v < g.n)
fn graph_has_edge(g: &WeightedGraph, u: Int, v: Int) -> Bool¶
Whether the edge (u, v) is present (either direction for undirected). Complexity: O(edges).
- Postcondition:
(g.edges.len() == 0) => (result == false)
fn graph_degree(g: &WeightedGraph, v: Int) -> Int¶
Degree of vertex v (undirected degree counts once per incident edge). Complexity: O(edges).
- Postcondition:
(v < 0 || v >= g.n) => (result == 0) - Postcondition:
(v >= 0 && v < g.n) => (result >= 0)
fn graph_vertices(g: &WeightedGraph) -> Vec[Int]¶
All vertices as ids [0, n - 1]. Complexity: O(n).
- Postcondition:
result.len() == g.n
fn graph_edges(g: &WeightedGraph) -> Vec[(Int, Int)]¶
All edges as (u, v) pairs (duplicated pairs for undirected graphs, one per stored direction). Complexity: O(edges).
- Postcondition:
result.len() == g.edges.len()
fn graph_adjacent(g: &WeightedGraph, u: Int, v: Int) -> Bool¶
Whether u and v are neighbors. Complexity: O(edges).
- Postcondition:
(g.edges.len() == 0) => (result == false)
fn graph_dfs(g: &WeightedGraph, start: Int) -> Vec[Int]¶
Depth-first vertex order from start. Returns the empty vector for a start outside the graph. Complexity: O(V + E).
- Postcondition:
(start < 0 || start >= g.n) => (result.len() == 0) - Postcondition:
(start >= 0 && start < g.n) => (result.len() >= 1 && result.len() <= g.n)
fn graph_bfs(g: &WeightedGraph, start: Int) -> Vec[Int]¶
Breadth-first vertex order from start. Complexity: O(V + E).
- Postcondition:
(start < 0 || start >= g.n) => (result.len() == 0) - Postcondition:
(start >= 0 && start < g.n) => (result.len() >= 1 && result.len() <= g.n)
fn graph_dijkstra(g: &WeightedGraph, source: Int) -> Vec[Float64]¶
Shortest-path distances from source via Dijkstra's algorithm (edge-list scanning; O(V^2 + E) worst case). Unreachable vertices get _INF. Complexity: O(V^2 + E).
- Postcondition:
(source < 0 || source >= g.n) => (result.len() == 0) - Postcondition:
(source >= 0 && source < g.n) => (result.len() == g.n)
fn graph_bellman_ford(g: &WeightedGraph, source: Int) -> Option[Vec[Float64]]¶
Shortest-path distances from source via Bellman-Ford; None when a negative cycle is reachable. Complexity: O(V * E).
- Postcondition:
(source < 0 || source >= g.n) => (result.is_none == true)
fn graph_floyd_warshall(g: &WeightedGraph) -> Vec[Vec[Float64]]¶
All-pairs shortest-path distances via repeated Bellman-Ford-style edge relaxation from every source. The result is a Vec[Vec[Float64]] distance matrix (callers can only rely on its shape; element reads of module-returned nested float Vecs are unreliable in this compiler build). Complexity: O(V^2 * E).
- Postcondition:
result.len() == g.n
fn graph_astar(g: &WeightedGraph, start: Int, goal: Int, h: fn(Int, Int) -> Float64) -> Option[Vec[Int]]¶
A* path from start to goal using the heuristic h(vertex, goal); returns the vertex sequence (inclusive) or None when no path exists. Complexity: O(V^2 + E) (linear scan open set).
- Postcondition:
(start < 0 || start >= g.n || goal < 0 || goal >= g.n) => (result.is_none == true)
fn graph_prim(g: &WeightedGraph) -> Option[Vec[(Int, Int)]]¶
Minimum spanning tree edges by Prim's algorithm (edge-list scanning); None for a disconnected or empty graph. Complexity: O(V^2 + E).
- Postcondition:
(g.n == 0) => (result.is_none == true) - Postcondition:
(g.n == 1) => (result.is_some == true)
fn graph_kruskal(g: &WeightedGraph) -> Option[Vec[(Int, Int)]]¶
Minimum spanning tree edges by Kruskal's algorithm (union-find with min-weight edge selection; compares scaled-integer weights directly). None for a disconnected graph. Complexity: O(V * E).
- Postcondition:
(g.n == 0) => (result.is_none == true) - Postcondition:
(g.n == 1) => (result.is_some == true)
fn graph_tarjan_scc(g: &WeightedGraph) -> Vec[Vec[Int]]¶
Strongly connected components by Tarjan's algorithm (iterative). Each component is one inner vector. Complexity: O(V + E).
- Postcondition:
(g.n == 0) => (result.len() == 0) - Postcondition:
(g.n > 0) => (result.len() >= 1 && result.len() <= g.n)
fn graph_kosaraju_scc(g: &WeightedGraph) -> Vec[Vec[Int]]¶
Strongly connected components by Kosaraju's algorithm (two DFS passes). Complexity: O(V + E).
- Postcondition:
(g.n == 0) => (result.len() == 0) - Postcondition:
(g.n > 0) => (result.len() >= 1 && result.len() <= g.n)
fn graph_topological_sort(g: &WeightedGraph) -> Option[Vec[Int]]¶
Linear ordering of a directed acyclic graph (Kahn's algorithm); None when the graph has a cycle. Complexity: O(V + E).
- Postcondition:
(g.n == 0) => (result.is_some == true)
fn graph_is_connected(g: &WeightedGraph) -> Bool¶
Whether the graph is connected (a single BFS reaches every vertex). Complexity: O(V + E).
- Postcondition:
(g.n <= 1) => (result == true)
fn graph_is_cyclic(g: &WeightedGraph) -> Bool¶
Whether the graph contains a cycle (DFS with colors; undirected uses the parent check). Complexity: O(V + E).
- Postcondition:
(g.n == 0) => (result == false)
fn graph_is_bipartite(g: &WeightedGraph) -> Bool¶
Whether the vertices split into two independent sets (BFS 2-coloring). Complexity: O(V + E).
- Postcondition:
(g.n == 0) => (result == true)
fn graph_isomorphic(g1: &WeightedGraph, g2: &WeightedGraph) -> Bool¶
Whether g1 and g2 are isomorphic. Checks vertex count, edge count, and degree sequence; for n <= 6 an exact permutation test is performed. Complexity: O(n! * n^2) for small n, O(n^2) otherwise.
- Postcondition:
(g1.n != g2.n) => (result == false) - Postcondition:
(g1.edges.len() != g2.edges.len()) => (result == false)
fn graph_color(g: &WeightedGraph) -> Vec[Int]¶
Greedy vertex coloring (smallest available color per vertex in id order). Returns one color per vertex (0-based). Complexity: O(V * E).
- Postcondition:
result.len() == g.n
fn graph_max_flow(g: &WeightedGraph, s: Int, t: Int) -> Float64¶
Maximum flow from s to t by Edmonds-Karp (BFS augmenting paths) over the edge list with parallel residual-capacity tracking. Complexity: O(V * E^2).
- Postcondition:
(s < 0 || s >= g.n || t < 0 || t >= g.n || s == t) => (result == 0) - Postcondition:
(s >= 0 && s < g.n && t >= 0 && t < g.n && s != t) => (result >= 0)
fn graph_min_cut(g: &WeightedGraph, s: Int, t: Int) -> Vec[Int]¶
Minimum s-t cut: the vertices reachable from s in the residual graph after the maximum flow (the S side of the min cut). Complexity: O(V * E^2).
- Postcondition:
(s < 0 || s >= g.n || t < 0 || t >= g.n) => (result.len() == 0) - Postcondition:
(s >= 0 && s < g.n && t >= 0 && t < g.n) => (result.len() >= 1)
fn graph_hamiltonian_path(g: &WeightedGraph) -> Option[Vec[Int]]¶
Hamiltonian path if one exists (exhaustive DFS; practical for n <= 12). Complexity: O(n!).
- Postcondition:
(g.n == 0) => (result.is_some == true) - Postcondition:
(g.n > 12) => (result.is_none == true)
fn graph_tsp(g: &WeightedGraph) -> Vec[Int]¶
Traveling-salesperson tour by the nearest-neighbor heuristic: visits every vertex once starting from vertex 0 and returns to the start. Returns the tour as a vertex sequence (length n + 1). Complexity: O(n^2 + n * E).
- Postcondition:
(g.n == 0) => (result.len() == 0) - Postcondition:
(g.n > 0) => (result.len() == g.n + 1) - Postcondition:
(g.n > 0) => (result[0] == 0)
hyperbolic.xi¶
fn sinh(x: Float64) -> Float64¶
Hyperbolic sine of x. sinh(0.0) == 0.0; |x| > ~710 overflows to +-inf. Complexity: O(1), libm exp.
- Postcondition:
((x >= 0) && (result >= 0)) || ((x < 0) && (result <= 0)) || (result != result)
fn cosh(x: Float64) -> Float64¶
Hyperbolic cosine of x. cosh(0.0) == 1.0; |x| > ~710 overflows to +inf. Complexity: O(1), libm exp.
- Postcondition:
(result >= 0) || (result != result)
fn tanh(x: Float64) -> Float64¶
Hyperbolic tangent of x. tanh(0.0) == 0.0; saturates to +-1.0 for |x| > 20. Uses (exp(2x)-1)/(exp(2x)+1) for stability. Complexity: O(1).
- Postcondition:
((result >= -1) && (result <= 1)) || (result != result)
fn csch(x: Float64) -> Float64¶
Hyperbolic cosecant, 1/sinh(x). csch(0.0) == +inf (native 1.0/0.0). Complexity: O(1), libm exp.
- Postcondition:
((x >= 0) && (result >= 0)) || ((x < 0) && (result <= 0)) || (result != result)
fn sech(x: Float64) -> Float64¶
Hyperbolic secant, 1/cosh(x). Always finite (cosh > 0). Complexity: O(1).
- Postcondition:
(result >= 0) || (result != result)
fn coth(x: Float64) -> Float64¶
Hyperbolic cotangent, 1/tanh(x). coth(0.0) == +inf (native 1.0/0.0). Complexity: O(1), libm exp.
- Postcondition:
((result <= -1) || (result >= 1)) || (result != result)
fn asinh(x: Float64) -> Float64¶
Inverse hyperbolic sine: ln(x + sqrt(x^2 + 1)). Odd function. For |x| > 1e150 uses ln(|x|) + ln 2 (avoids x^2 overflow and cancellation). asinh(1.0) == 0.881373587019543. Complexity: O(1), libm ln/sqrt.
- Postcondition:
((x >= 0) && (result >= 0)) || ((x < 0) && (result <= 0)) || (result != result)
fn acosh(x: Float64) -> Float64¶
Inverse hyperbolic cosine: ln(x + sqrt(x^2 - 1)). Requires x >= 1. For x < 1 returns NaN (IEEE semantics). For x > 1e150 uses ln(x) + ln 2 (avoids overflow). acosh(1.0) == 0.0, acosh(cosh(1.0)) == 1.0. Complexity: O(1), libm ln/sqrt.
- Postcondition:
(result >= 0) || (result != result)
fn atanh(x: Float64) -> Float64¶
Inverse hyperbolic tangent: 0.5 * ln((1+x)/(1-x)). Requires |x| < 1. For |x| > 1 returns NaN (IEEE semantics); atanh(1.0) == +inf and atanh(-1.0) == -inf (native, ln 0/inf). atanh(0.0) == 0.0. Complexity: O(1), libm ln.
- Postcondition:
((x >= 0) && (result >= 0)) || ((x < 0) && (result <= 0)) || (result != result)
fn sinh_pure(x: Float64) -> Float64¶
Hyperbolic sine via the pure exp series (math.exponential.exp_pure), no libm. sinh_pure(0.0) == 0.0. Complexity: O(exp_pure).
- Postcondition:
((x >= 0) && (result >= 0)) || ((x < 0) && (result <= 0)) || (result != result)
fn cosh_pure(x: Float64) -> Float64¶
Hyperbolic cosine via the pure exp series, no libm. cosh_pure(0.0) == 1.0. Complexity: O(exp_pure).
- Postcondition:
(result >= 0) || (result != result)
fn tanh_pure(x: Float64) -> Float64¶
Hyperbolic tangent via pure sinh/cosh series, no libm. Saturates to +-1.0 for |x| > 20. tanh_pure(0.0) == 0.0. Complexity: O(exp_pure).
- Postcondition:
((result >= -1) && (result <= 1)) || (result != result)
information_theory.xi¶
fn entropy(probs: &Vec[Float64]) -> Float64¶
Shannon entropy H(p) = -sum p_i log2 p_i (bits). NaN for a negative probability. Complexity: O(n).
- Postcondition:
(probs.len() == 0) => (result == 0)
fn joint_entropy(p_joint: &Vec[Vec[Float64]]) -> Float64¶
Entropy of a joint distribution over pairs: H(X, Y) = -sum p_ij log2 p_ij. TODO(compiler): NOT IMPLEMENTABLE in this compiler build - the joint distribution is a Vec[Vec[Float64]] whose element reads return garbage (BUG 23 #1 residual; verified by minimal probe). Keep the frozen signature; revisit when nested float Vec reads land.
fn conditional_entropy(p_joint: &Vec[Vec[Float64]]) -> Float64¶
Conditional entropy H(X|Y) = -sum_ij p_ij log2(p_ij / p_j) (bits). TODO(compiler): NOT IMPLEMENTABLE - see joint_entropy (matrix element reads return garbage in this compiler build).
fn mutual_information(p_joint: &Vec[Vec[Float64]]) -> Float64¶
Mutual information I(X; Y) = sum_ij p_ij log2(p_ij / (p_i p_j)) (bits). TODO(compiler): NOT IMPLEMENTABLE - see joint_entropy (matrix element reads return garbage in this compiler build).
fn kl_divergence(p: &Vec[Float64], q: &Vec[Float64]) -> Float64¶
Kullback-Leibler divergence D(p || q) = sum p_i log2(p_i / q_i) (bits). NaN for a zero q_i with positive p_i. Complexity: O(n).
- Postcondition:
(p.len() != q.len()) => (result != result)
fn js_divergence(p: &Vec[Float64], q: &Vec[Float64]) -> Float64¶
Jensen-Shannon divergence JSD(p || q) = 0.5 D(p || m) + 0.5 D(q || m) with m = (p + q)/2 (bits; values in [0, 1]). NaN on length mismatch. Complexity: O(n).
- Postcondition:
(p.len() != q.len()) => (result != result)
fn cross_entropy(p: &Vec[Float64], q: &Vec[Float64]) -> Float64¶
Cross entropy H(p, q) = -sum p_i log2 q_i (bits). NaN for a zero q_i with positive p_i. Complexity: O(n).
- Postcondition:
(p.len() != q.len()) => (result != result)
fn perplexity(probs: &Vec[Float64]) -> Float64¶
Perplexity = 2^H (exponential of the entropy in bits). NaN for negative probabilities. Complexity: O(n).
- Postcondition:
(probs.len() == 0) => (result == 1)
fn self_information(p: Float64) -> Float64¶
Self information -log2(p) of a single event (bits). p <= 0 returns +inf. Complexity: O(1).
- Postcondition:
(p <= 0) => (result > 1)
fn entropy_rate(p_transition: &Vec[Vec[Float64]], stationary: &Vec[Float64]) -> Float64¶
Entropy rate of a stationary Markov source: sum_j s_j H(row j of the transition matrix). TODO(compiler): NOT IMPLEMENTABLE - the transition matrix is a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn channel_capacity(p_transition: &Vec[Vec[Float64]]) -> Float64¶
Channel capacity by the Blahut-Arimoto algorithm. TODO(compiler): NOT IMPLEMENTABLE - the channel matrix is a Vec[Vec[Float64]] whose element reads return garbage in this compiler build (verified by minimal probe); the resulting q values become NaN and violate math.ln's positivity requirement. Keep the frozen signature; revisit when nested float Vec reads land.
fn data_compression_bound(dist: &Vec[Float64]) -> Float64¶
Lower bound on the average code length for a distribution: its entropy (bits). NaN for negative probabilities. Complexity: O(n).
- Postcondition:
(dist.len() == 0) => (result == 0)
fn huffman_coding(probs: &Vec[Float64]) -> Vec[(Int, Str)]¶
Prefix-free Huffman code for a probability distribution. The result holds (symbol index, codeword) pairs with codewords of "0"/"1"; NaN inputs or an empty distribution yield an empty result. Complexity: O(n^2).
- Postcondition:
(probs.len() == 0) => (result.len() == 0)
fn arithmetic_coding(probs: &Vec[Float64], seq: &Vec[Int]) -> Float64¶
Arithmetic coding of the symbol sequence seq under the distribution probs: returns the midpoint of the final code interval in [0, 1). Invalid symbols (outside the distribution) contribute nothing (documented). Complexity: O(len(seq) * n).
- Postcondition:
(seq.len() == 0) => (result == 0.5)
int.xi¶
fn saturating_add(a: Int, b: Int) -> Int¶
a + b, clamping at INT_MAX/INT_MIN on overflow. Complexity: O(1).
- Postcondition:
(b == 0) => (result == a)
fn saturating_sub(a: Int, b: Int) -> Int¶
a - b, clamping at INT_MAX/INT_MIN on overflow. Complexity: O(1).
- Postcondition:
(b == 0) => (result == a)
fn saturating_mul(a: Int, b: Int) -> Int¶
a * b, clamping at INT_MAX/INT_MIN on overflow. The one unrepresentable product INT_MIN * -1 saturates to INT_MAX (documented, same as xiom.num.i64_mul_sat). Complexity: O(1).
- Postcondition:
(b == 1) => (result == a) - Postcondition:
(a == 0) || (b == 0) => (result == 0)
fn div_round(a: Int, b: Int) -> Int¶
a / b rounded to nearest, halves away from zero: div_round(5, 2) == 3, div_round(-5, 2) == -3, div_round(1, 2) == 1, div_round(-1, 2) == -1. Division by zero returns 0. The one unrepresentable quotient (INT_MIN / -1 = +2^63) saturates to INT_MAX. Magnitude arithmetic in 128 bits (shift-based long division, no hardware i128 division), so no intermediate overflows. Complexity: O(1).
- Postcondition:
(b == 0) => (result == 0) - Postcondition:
(b == 1) => (result == a)
fn div_ceil(a: Int, b: Int) -> Int¶
a / b rounded toward +infinity (ceiling division): div_ceil(7, 2) == 4, div_ceil(-7, 2) == -3, div_ceil(6, 2) == 3. Division by zero returns 0. The one unrepresentable quotient (INT_MIN / -1) returns INT_MIN (documented, same sentinel as xiom.num.i64_div_ceil). Complexity: O(1).
- Postcondition:
(b == 0) => (result == 0) - Postcondition:
(b == 1) => (result == a)
fn isqrt(n: Int) -> Int¶
Integer square root: the largest r >= 0 with r * r <= n. isqrt(n) == 0 for n <= 0 (documented). Newton iteration seeded at n / 2 + 1 (the seed is >= sqrt(n) for every n >= 4 and the update x -> (x + n / x) / 2 never overflows Int); this is the standalone integer sqrt usable without the xiom.math barrel. Complexity: O(log n).
- Postcondition:
(n <= 0) => (result == 0) - Postcondition:
result >= 0 - Postcondition:
result * result <= n || n < 0
integral.xi¶
fn integrate_riemann(f: fn(Float64) -> Float64, a: Float64, b: Float64, n: Int) -> Float64¶
Riemann sum over n subintervals using left endpoints. Returns 0.0 for n <= 0 (documented). Complexity: O(n).
- Postcondition:
(n > 0) || (result == 0)
fn integrate_trapezoid(f: fn(Float64) -> Float64, a: Float64, b: Float64, n: Int) -> Float64¶
Composite trapezoidal rule over n subintervals. Returns 0.0 for n <= 0 (documented). Complexity: O(n).
- Postcondition:
(n > 0) || (result == 0)
fn integrate_midpoint(f: fn(Float64) -> Float64, a: Float64, b: Float64, n: Int) -> Float64¶
Composite midpoint rule over n subintervals. Returns 0.0 for n <= 0 (documented). Complexity: O(n).
- Postcondition:
(n > 0) || (result == 0)
fn integrate_simpson(f: fn(Float64) -> Float64, a: Float64, b: Float64, n: Int) -> Float64¶
Composite Simpson's rule over n subintervals. An odd n is reduced to n - 1 (documented). Returns 0.0 for n <= 0 (documented). Complexity: O(n).
- Postcondition:
(n > 0) || (result == 0)
fn integrate_adaptive(f: fn(Float64) -> Float64, a: Float64, b: Float64, tol: Float64) -> Float64¶
Adaptive Simpson quadrature refining [a, b] until the local error estimate falls under tol (depth-capped to 40 refinements per interval). Returns 0.0 for tol <= 0 (documented). Complexity: depends on the integrand's smoothness; O(refinements). TODO(compiler): NOT IMPLEMENTABLE in this compiler build - the recursive refinement threading a fn-typed param together with Float64 parameters makes any program that links it crash at startup with 0xC000001D (BUG 20 AVX-512 codegen on Zen 2), even before main. Keep the frozen signature; revisit when the vectorizer cannot touch this shape.
- Postcondition:
(tol > 0) || (result == 0)
fn integrate_gauss_legendre(f: fn(Float64) -> Float64, a: Float64, b: Float64, n: Int) -> Float64¶
n-point Gauss-Legendre quadrature over [a, b]. Supported point counts are 1..8 (standard node/weight tables); other counts fall back to the 8-point rule (documented). Complexity: O(n).
- Postcondition:
(a == b) => (result == 0 || result != result)
fn definite_integral(f: fn(Float64) -> Float64, a: Float64, b: Float64) -> Float64¶
Default high-accuracy definite integral over [a, b]. Returns 0.0 when a == b. NOTE: the adaptive-Simpson implementation crashes at startup with 0xC000001D in this build (BUG 20 AVX-512 codegen on Zen 2; see integrate_adaptive), so this currently falls back to the composite trapezoidal rule with 1000 subintervals (~1e-6 accuracy for smooth integrands). Complexity: O(1000).
- Postcondition:
(a != b) || (result == 0)
interfaces.xi¶
inverse_trig.xi¶
fn asin(x: Float64) -> Float64¶
Arcsine of x in radians, result in [-pi/2, pi/2]. For x outside [-1, 1] returns NaN (documented domain error). Complexity: O(1).
- Postcondition:
(x < -1) || (x > 1) || ((result >= -1.5707963267948966) && (result <= 1.5707963267948966)) || (result != result)
fn acos(x: Float64) -> Float64¶
Arccosine of x in radians, result in [0, pi]. For x outside [-1, 1] returns NaN (documented domain error). Complexity: O(1).
- Postcondition:
(x < -1) || (x > 1) || ((result >= 0) && (result <= 3.141592653589793)) || (result != result)
fn atan(x: Float64) -> Float64¶
Arctangent of x in radians, result in (-pi/2, pi/2). Complexity: O(1).
- Postcondition:
((result >= -1.5707963267948966) && (result <= 1.5707963267948966)) || (result != result)
fn atan2(y: Float64, x: Float64) -> Float64¶
Four-quadrant arctangent of y/x in radians. When both y and x are zero returns NaN (documented; the angle is undefined there). Complexity: O(1).
- Postcondition:
((result >= -3.141592653589793) && (result <= 3.141592653589793)) || (result != result)
fn atan2_pure(y: Float64, x: Float64) -> Float64¶
Four-quadrant arctangent of y/x computed purely by series (xiom.math's pure atan, no libm). When both y and x are zero returns NaN (documented). Complexity: O(series terms).
- Postcondition:
((result >= -3.141592653589793) && (result <= 3.141592653589793)) || (result != result)
fn asin_pure(x: Float64) -> Float64¶
Arcsine of x via the identity asin(x) = atan(x/sqrt(1-x^2)) using the pure atan/sqrt implementations (no libm). For x outside [-1, 1] returns NaN (documented domain error). Complexity: O(series terms).
- Postcondition:
(x < -1) || (x > 1) || ((result >= -1.5707963267948966) && (result <= 1.5707963267948966)) || (result != result)
fn acos_pure(x: Float64) -> Float64¶
Arccosine of x via acos(x) = pi/2 - asin(x) on the pure asin (no libm). For x outside [-1, 1] returns NaN (documented domain error). Complexity: O(series terms).
- Postcondition:
(x < -1) || (x > 1) || ((result >= 0) && (result <= 3.141592653589793)) || (result != result)
fn atan_pure(x: Float64) -> Float64¶
Arctangent of x via the pure Taylor-series implementation (no libm). For |x| > 1 the reciprocal identity is applied. Complexity: O(series terms).
- Postcondition:
((result >= -1.5707963267948966) && (result <= 1.5707963267948966)) || (result != result)
fn atan2_radians(y: Float64, x: Float64) -> Float64¶
Four-quadrant arctangent of y/x with the result in radians. Alias of atan2. Complexity: O(1).
- Precondition:
true - Postcondition:
((result >= -3.141592653589793) && (result <= 3.141592653589793)) || (result != result)
fn atan2_degrees(y: Float64, x: Float64) -> Float64¶
Four-quadrant arctangent of y/x with the result in degrees. Complexity: O(1).
- Precondition:
true - Postcondition:
((result >= -180) && (result <= 180)) || (result != result)
fn arg(y: Float64, x: Float64) -> Float64¶
Angle of the vector (x, y) in radians: alias of atan2. Complexity: O(1).
- Precondition:
true - Postcondition:
((result >= -3.141592653589793) && (result <= 3.141592653589793)) || (result != result)
logic.xi¶
fn boolean_expression(op: Str, a: Bool, b: Bool) -> Bool¶
Evaluate a named Boolean operator over the inputs a and b. Supported names (case-sensitive): "and", "or", "xor", "nand", "nor", "xnor", "implies", "iff". Any other name returns false (documented). Complexity: O(1).
fn iff(a: Bool, b: Bool) -> Bool¶
Logical biconditional: true when a equals b. Complexity: O(1).
- Postcondition:
result == (a == b)
fn implies(a: Bool, b: Bool) -> Bool¶
Logical implication: false only when a is true and b is false. Complexity: O(1).
- Postcondition:
result == (!a || b)
fn xor(a: Bool, b: Bool) -> Bool¶
Exclusive or: true when a differs from b. Complexity: O(1).
- Postcondition:
result == (a != b)
fn nand(a: Bool, b: Bool) -> Bool¶
Not-and of a and b. Complexity: O(1).
- Postcondition:
result == !(a && b)
fn nor(a: Bool, b: Bool) -> Bool¶
Not-or of a and b. Complexity: O(1).
- Postcondition:
result == !(a || b)
machine_learning.xi¶
fn activation_sigmoid(x: Float64) -> Float64¶
Logistic sigmoid 1/(1+exp(-x)). Saturated to 1 for large x and to 0 for very negative x. Complexity: O(1).
- Postcondition:
(x != x) => (result != result) - Postcondition:
(x >= 0) => (result >= 0 && result <= 1) - Postcondition:
(x < 0) => (result >= 0 && result < 1)
fn activation_tanh(x: Float64) -> Float64¶
Hyperbolic tangent activation tanh(x) = (1 - exp(-2x))/(1 + exp(-2x)), stable for all x. Complexity: O(1).
- Postcondition:
(x != x) => (result != result) - Postcondition:
(x >= 0) => (result >= 0 && result <= 1) - Postcondition:
(x < 0) => (result >= -1 && result <= 0)
fn activation_relu(x: Float64) -> Float64¶
Rectified linear unit max(0, x). Complexity: O(1).
- Postcondition:
(x != x) => (result == 0) - Postcondition:
(x > 0) => (result == x) - Postcondition:
(x <= 0) => (result == 0)
fn activation_gelu(x: Float64) -> Float64¶
Gaussian error linear unit 0.5 x (1 + erf(x / sqrt(2))). Complexity: O(1).
- Postcondition:
(x != x) => (result != result) - Postcondition:
(x == 0) => (result == 0)
fn activation_swish(x: Float64) -> Float64¶
Swish activation x * sigmoid(x). Complexity: O(1).
- Postcondition:
(x == 0) => (result == 0) - Postcondition:
(x != x) => (result != result)
fn loss_mse(y_true: &Vec[Float64], y_pred: &Vec[Float64]) -> Float64¶
Mean squared error of y_true vs y_pred. NaN on length mismatch or NaN input. Complexity: O(n).
- Postcondition:
(y_true.len() != y_pred.len()) => (result != result) - Postcondition:
(y_true.len() == 0 && y_pred.len() == 0) => (result != result)
fn loss_mae(y_true: &Vec[Float64], y_pred: &Vec[Float64]) -> Float64¶
Mean absolute error of y_true vs y_pred. Complexity: O(n).
- Postcondition:
(y_true.len() != y_pred.len()) => (result != result) - Postcondition:
(y_true.len() == 0 && y_pred.len() == 0) => (result != result)
fn loss_huber(y_true: &Vec[Float64], y_pred: &Vec[Float64], delta: Float64) -> Float64¶
Huber loss with threshold delta: quadratic inside delta, linear outside. NaN for delta <= 0. Complexity: O(n).
- Postcondition:
(y_true.len() != y_pred.len()) => (result != result) - Postcondition:
(delta <= 0) => (result != result) - Postcondition:
(y_true.len() == 0 && y_pred.len() == 0) => (result != result)
fn loss_cross_entropy(y_true: &Vec[Float64], y_pred: &Vec[Float64]) -> Float64¶
Categorical cross entropy -sum y_true_i log(y_pred_i). NaN for zero predictions with positive target or length mismatch. Complexity: O(n).
- Postcondition:
(y_true.len() != y_pred.len()) => (result != result) - Postcondition:
(y_true.len() == 0 && y_pred.len() == 0) => (result == 0)
fn loss_hinge(y_true: &Vec[Float64], y_pred: &Vec[Float64]) -> Float64¶
Hinge loss sum max(0, 1 - y_true_i * y_pred_i) (targets in {-1, +1}). Complexity: O(n).
- Postcondition:
(y_true.len() != y_pred.len()) => (result != result) - Postcondition:
(y_true.len() == 0 && y_pred.len() == 0) => (result != result)
fn metric_accuracy(y_true: &Vec[Int], y_pred: &Vec[Int]) -> Float64¶
Fraction of correct predictions (labels in {0, 1}). Complexity: O(n).
- Postcondition:
(y_true.len() != y_pred.len()) => (result != result) - Postcondition:
(y_true.len() == 0 && y_pred.len() == 0) => (result == 0) - Postcondition:
(y_true.len() > 0 && y_true.len() == y_pred.len()) => (result >= 0 && result <= 1)
fn metric_precision(y_true: &Vec[Int], y_pred: &Vec[Int]) -> Float64¶
Precision of the positive class (labels in {0, 1}): TP / (TP + FP). Returns 0 when no positive prediction exists (documented). Complexity: O(n).
- Postcondition:
(y_true.len() != y_pred.len()) => (result != result) - Postcondition:
(y_true.len() == y_pred.len()) => (result >= 0 && result <= 1)
fn metric_recall(y_true: &Vec[Int], y_pred: &Vec[Int]) -> Float64¶
Recall of the positive class (labels in {0, 1}): TP / (TP + FN). Returns 0 when no positive label exists (documented). Complexity: O(n).
- Postcondition:
(y_true.len() != y_pred.len()) => (result != result) - Postcondition:
(y_true.len() == y_pred.len()) => (result >= 0 && result <= 1)
fn metric_f1(y_true: &Vec[Int], y_pred: &Vec[Int]) -> Float64¶
F1 score: harmonic mean of precision and recall. Returns 0 when both are zero (documented). Complexity: O(n).
- Postcondition:
(y_true.len() != y_pred.len()) => (result != result) - Postcondition:
(y_true.len() == y_pred.len()) => (result >= 0 && result <= 1)
fn metric_auc(y_true: &Vec[Int], y_pred: &Vec[Float64]) -> Float64¶
Area under the ROC curve computed by the rank-sum (Mann-Whitney) formula: AUC = (sum of ranks of positives - P(P+1)/2) / (P * N). NaN on length mismatch or empty classes. Complexity: O(n log n).
- Postcondition:
(y_true.len() != y_pred.len()) => (result != result) - Postcondition:
(y_true.len() == y_pred.len()) => (result != result || (result >= 0 && result <= 1))
fn regularization_l1(weights: &Vec[Float64], lambda: Float64) -> Float64¶
L1 penalty lambda * sum |w_i|. Complexity: O(n).
- Postcondition:
(weights.len() == 0) => (result == 0)
fn regularization_l2(weights: &Vec[Float64], lambda: Float64) -> Float64¶
L2 penalty lambda * sum w_i^2. Complexity: O(n).
- Postcondition:
(weights.len() == 0) => (result == 0)
fn regularization_elastic_net(weights: &Vec[Float64], lambda1: Float64, lambda2: Float64) -> Float64¶
Elastic-net penalty lambda1 * L1 + lambda2 * L2. Complexity: O(n).
- Postcondition:
(weights.len() == 0) => (result == 0)
fn normalization_batch(x: &Vec[Vec[Float64]]) -> Vec[Vec[Float64]]¶
Batch normalization over the batch dimension (per-feature mean/variance, with epsilon 1e-5 stabilization; no learned scale/shift). NaN for empty input. Complexity: O(batch * features). TODO(compiler): NOT IMPLEMENTABLE in this compiler build - the batch/feature matrix is a Vec[Vec[Float64]] whose element reads return garbage (BUG 23 #1 residual; verified by minimal probe). Keep the frozen signature; revisit when nested float Vec reads land.
fn normalization_layer(x: &Vec[Float64]) -> Vec[Float64]¶
Layer normalization of a feature vector: (x - mean) / sqrt(var + eps). NaN for empty input. Complexity: O(n).
- Postcondition:
(x.len() == 0) => (result.len() == 0) - Postcondition:
(x.len() > 0) => (result.len() == x.len())
fn normalization_group(x: &Vec[Float64], groups: Int) -> Vec[Float64]¶
Group normalization: channels (vector positions) are split into
groupscontiguous groups, each normalized to zero mean and unit variance. NaN for groups <= 0 or a non-divisible length. Complexity: O(n).
- Postcondition:
(groups <= 0) => (result.len() == 0) - Postcondition:
(x.len() == 0) => (result.len() == 0) - Postcondition:
(groups > 0 && x.len() > 0) => (result.len() == 0 || result.len() == x.len())
fn dropout(x: &Vec[Float64], rate: Float64, seed: Int) -> Vec[Float64]¶
Training-time dropout: each element is kept with probability 1 - rate (scaled by 1/(1 - rate)); the RNG is seeded with
seedfor reproducible masks. NaN for rate outside [0, 1). Complexity: O(n).
- Postcondition:
(rate < 0 || rate >= 1) => (result.len() == 0) - Postcondition:
(rate >= 0 && rate < 1) => (result.len() == x.len())
fn kernel_rbf(x: &Vec[Float64], y: &Vec[Float64], gamma: Float64) -> Float64¶
Radial basis function kernel exp(-gamma * ||x - y||^2). NaN on length mismatch. Complexity: O(n).
- Postcondition:
(x.len() != y.len()) => (result != result) - Postcondition:
(x.len() == 0 && y.len() == 0) => (result == 1) - Postcondition:
(x.len() == y.len() && gamma >= 0) => (result <= 1 || result != result)
fn kernel_polynomial(x: &Vec[Float64], y: &Vec[Float64], degree: Int, coef0: Float64) -> Float64¶
Polynomial kernel (dot(x, y) + coef0)^degree. NaN on length mismatch. Complexity: O(n).
- Postcondition:
(x.len() != y.len()) => (result != result) - Postcondition:
(x.len() == y.len() && degree == 0) => (result == 1)
fn kernel_sigmoid(x: &Vec[Float64], y: &Vec[Float64], gamma: Float64, coef0: Float64) -> Float64¶
Sigmoid kernel tanh(gamma * dot(x, y) + coef0). NaN on length mismatch. Complexity: O(n).
- Postcondition:
(x.len() != y.len()) => (result != result) - Postcondition:
(x.len() == y.len()) => (result >= -1 && result <= 1 || result != result)
fn distance_euclidean(a: &Vec[Float64], b: &Vec[Float64]) -> Float64¶
Euclidean distance ||a - b||. NaN on length mismatch. Complexity: O(n).
- Postcondition:
(a.len() != b.len()) => (result != result) - Postcondition:
(a.len() == 0 && b.len() == 0) => (result == 0) - Postcondition:
(a.len() == b.len()) => (result >= 0 || result != result)
fn distance_manhattan(a: &Vec[Float64], b: &Vec[Float64]) -> Float64¶
Manhattan (L1) distance sum |a_i - b_i|. Complexity: O(n).
- Postcondition:
(a.len() != b.len()) => (result != result) - Postcondition:
(a.len() == 0 && b.len() == 0) => (result == 0) - Postcondition:
(a.len() == b.len()) => (result >= 0 || result != result)
fn distance_cosine(a: &Vec[Float64], b: &Vec[Float64]) -> Float64¶
Cosine distance 1 - cos_similarity. Complexity: O(n).
- Postcondition:
(a.len() != b.len()) => (result != result) - Postcondition:
(a.len() == b.len()) => (result != result || (result >= 0 && result <= 2))
fn distance_minkowski(a: &Vec[Float64], b: &Vec[Float64], p: Float64) -> Float64¶
Minkowski distance (sum |a_i - b_i|^p)^(1/p). NaN for p <= 0 or length mismatch. Complexity: O(n).
- Postcondition:
(a.len() != b.len()) => (result != result) - Postcondition:
(p <= 0) => (result != result) - Postcondition:
(a.len() == b.len() && a.len() == 0 && p > 0) => (result == 0)
fn similarity_cosine(a: &Vec[Float64], b: &Vec[Float64]) -> Float64¶
Cosine similarity dot(a, b) / (||a|| ||b||). NaN for zero norms or length mismatch. Complexity: O(n).
- Postcondition:
(a.len() != b.len()) => (result != result) - Postcondition:
(a.len() == 0 && b.len() == 0) => (result != result) - Postcondition:
(a.len() == b.len()) => (result != result || (result >= -1 && result <= 1))
fn similarity_jaccard(a: &Vec[Float64], b: &Vec[Float64]) -> Float64¶
Jaccard similarity for non-negative vectors: sum min(a, b) / sum max(a, b). Returns 1 for two zero vectors (documented). Complexity: O(n).
- Postcondition:
(a.len() != b.len()) => (result != result) - Postcondition:
(a.len() == 0 && b.len() == 0) => (result == 1)
fn similarity_dice(a: &Vec[Float64], b: &Vec[Float64]) -> Float64¶
Dice coefficient 2 * sum min(a, b) / (sum a + sum b). Returns 1 for two zero vectors (documented). Complexity: O(n).
- Postcondition:
(a.len() != b.len()) => (result != result) - Postcondition:
(a.len() == 0 && b.len() == 0) => (result == 1)
math.xi¶
fn sqrt(x: Float64) -> Float64¶
Square root of
xvia libm. Requiresx >= 0.
- Precondition:
x >= 0 - Postcondition:
result >= 0
fn pow(base: Float64, exp: Float64) -> Float64¶
baseraised toexpvia libm. A negative base requires an integer exponent.
- Precondition:
base >= 0 || exp == (?)
fn abs_int(x: Int) -> Int¶
Absolute value of an Int, returned as Int.
- Postcondition:
(x == INT_MIN) || (result >= 0)
fn abs_float(x: Float64) -> Float64¶
Absolute value of a Float64 via libm
fabs.
- Precondition:
true
fn min_int(a: Int, b: Int) -> Int¶
Smaller of two Ints.
- Postcondition:
result <= a && result <= b - Postcondition:
result == a || result == b
fn max_int(a: Int, b: Int) -> Int¶
Larger of two Ints.
- Postcondition:
result >= a && result >= b - Postcondition:
result == a || result == b
fn min_float(a: Float64, b: Float64) -> Float64¶
Smaller of two Float64s.
- Postcondition:
(a != a) || (b != b) || ((result == a || result == b) && result <= a && result <= b)
fn max_float(a: Float64, b: Float64) -> Float64¶
Larger of two Float64s.
- Postcondition:
(a != a) || (b != b) || ((result == a || result == b) && result >= a && result >= b)
fn floor(x: Float64) -> Float64¶
Largest integer not greater than
x(libmfloor).
- Precondition:
true
fn ceil(x: Float64) -> Float64¶
Smallest integer not less than
x(libmceil).
- Precondition:
true
fn round(x: Float64) -> Int¶
Nearest integer to
x, halves rounded away from zero.
- Precondition:
x >= -9000000000000000000 - Precondition:
x <= 9000000000000000000 - Postcondition:
(x > -0.5 && x < 0.5) => (result == 0) - Postcondition:
(x >= 0.5) => (result >= 1) - Postcondition:
(x <= -0.5) => (result <= -1)
fn sin(x: Float64) -> Float64¶
Sine of
xradians (libm).
- Precondition:
true
fn cos(x: Float64) -> Float64¶
Cosine of
xradians (libm).
- Precondition:
true
fn tan(x: Float64) -> Float64¶
Tangent of
xradians (libm).
- Precondition:
true
fn asin(x: Float64) -> Float64¶
Arc sine of
xin [-pi/2, pi/2]; requiresxin [-1, 1] (libm).
- Precondition:
x >= -1 && x <= 1
fn acos(x: Float64) -> Float64¶
Arc cosine of
xin [0, pi]; requiresxin [-1, 1] (libm).
- Precondition:
x >= -1 && x <= 1
fn atan(x: Float64) -> Float64¶
Arc tangent of
xin [-pi/2, pi/2] (libm).
- Precondition:
true
fn atan2(y: Float64, x: Float64) -> Float64¶
Arc tangent of
y/xusing both signs to pick the quadrant;(0, 0)is rejected (libmatan2).
- Precondition:
x != 0 || y != 0
fn exp(x: Float64) -> Float64¶
e raised to
x(libm).
- Precondition:
true
fn ln(x: Float64) -> Float64¶
Natural logarithm of
x; requiresx > 0(libm).
- Precondition:
x > 0
fn log10(x: Float64) -> Float64¶
Base-10 logarithm of
x; requiresx > 0(libm).
- Precondition:
x > 0
fn log2(x: Float64) -> Float64¶
Base-2 logarithm of
x; requiresx > 0(derived from libmlog).
- Precondition:
x > 0
fn bit_and(a: Int, b: Int) -> Int¶
Bitwise AND of two Ints (two's-complement semantics, sign preserved).
- Postcondition:
(a == 0) => (result == 0) - Postcondition:
(b == 0) => (result == 0)
fn bit_or(a: Int, b: Int) -> Int¶
Bitwise OR of two Ints (two's-complement semantics, sign preserved).
- Postcondition:
(a == 0) => (result == b) - Postcondition:
(b == 0) => (result == a)
fn bit_xor(a: Int, b: Int) -> Int¶
Bitwise XOR of two Ints (two's-complement semantics, sign preserved).
- Postcondition:
(a == 0) => (result == b) - Postcondition:
(b == 0) => (result == a)
fn bit_not(a: Int) -> Int¶
Bitwise complement of
a(equivalent to-1 - a).
- Postcondition:
(a == 0) => (result == -1)
fn shl(a: Int, n: Int) -> Int¶
Logical shift left by
nbits;n <= 0returnsaunchanged,n >= 64returns 0.
- Postcondition:
(n < 64) || (result == 0) - Postcondition:
(n > 0) || (result == a)
fn shr(a: Int, n: Int) -> Int¶
Arithmetic shift right by
nbits;n <= 0returnsaunchanged, and negative values shift in sign bits.
- Postcondition:
(n < 64) || ((a < 0 && result == -1) || (a >= 0 && result == 0)) - Postcondition:
(n > 0) || (result == a)
fn seed_rng(seed: Int)¶
Seed the module-level Lehmer RNG; seed 0 is mapped to 1.
fn random() -> Float64¶
Next pseudo-random Float64 in [0, 1) from the module RNG (minstd LCG).
- Postcondition:
result >= 0 - Postcondition:
result < 1
fn random_range(min: Int, max: Int) -> Int¶
Uniform Int in [min, max] (inclusive) from the module RNG.
- Precondition:
min <= max - Postcondition:
result >= min - Postcondition:
result <= max
fn random_float() -> Float64¶
Alias of
random; the next Float64 in [0, 1).
- Postcondition:
result >= 0 - Postcondition:
result < 1
fn clamp(x: Float64, lo: Float64, hi: Float64) -> Float64¶
Clamp
xinto [lo, hi]; assumeslo <= hi.
- Precondition:
lo <= hi - Postcondition:
(x != x) || (result >= lo && result <= hi) - Postcondition:
(x != x) || (result == x || result == lo || result == hi)
fn lerp(a: Float64, b: Float64, t: Float64) -> Float64¶
Linear interpolation:
a + (b - a) * t(no clamping oft).
- Postcondition:
(t != 0) || (result == a) || (result != result) - Postcondition:
(t != 1) || (result == b) || (result != result)
fn is_nan(x: Float64) -> Bool¶
True when
xis NaN (x != x).
- Postcondition:
(result == true) => (x != x) - Postcondition:
(result == false) => (x == x)
fn is_inf(x: Float64) -> Bool¶
True when
xis positive or negative infinity.
- Postcondition:
(result == true) => (x == 1 / 0 || x == -1 / 0) - Postcondition:
(result == false) => (x != 1 / 0 && x != -1 / 0)
fn sqrt_pure(x: Float64) -> Float64¶
Pure-XIOM square root (Newton iteration); no libm needed.
- Precondition:
x >= 0 - Postcondition:
result >= 0
fn pow_pure(base: Float64, exp: Float64) -> Float64¶
Pure-XIOM
base ^ expviaexp(exp * ln(base)); negative base requires an integer exponent.
- Precondition:
base >= 0 || exp == (?)
fn abs_float_pure(x: Float64) -> Float64¶
Pure-XIOM absolute value of a Float64.
- Postcondition:
(x != x) || (result >= 0)
fn floor_pure(x: Float64) -> Float64¶
Pure-XIOM floor (truncation adjusted for negatives).
- Precondition:
x >= -9000000000000000000 - Precondition:
x <= 9000000000000000000 - Postcondition:
result <= x && result > x - 1
fn ceil_pure(x: Float64) -> Float64¶
Pure-XIOM ceil (truncation adjusted for positives).
- Precondition:
x >= -9000000000000000000 - Precondition:
x <= 9000000000000000000 - Postcondition:
result >= x && result < x + 1
fn sin_pure(x: Float64) -> Float64¶
Pure-XIOM sine via angle reduction + 10-term Taylor series.
- Postcondition:
(x != 0) || (result == 0)
fn cos_pure(x: Float64) -> Float64¶
Pure-XIOM cosine via angle reduction + 10-term Taylor series.
- Postcondition:
(x != 0) || (result == 1)
fn tan_pure(x: Float64) -> Float64¶
Pure-XIOM tangent as
sin_pure / cos_pure.
- Postcondition:
(x != 0) || (result == 0)
fn asin_pure(x: Float64) -> Float64¶
Pure-XIOM arc sine; requires
xin [-1, 1].
- Precondition:
x >= -1 && x <= 1
fn acos_pure(x: Float64) -> Float64¶
Pure-XIOM arc cosine; requires
xin [-1, 1].
- Precondition:
x >= -1 && x <= 1
fn atan_pure(x: Float64) -> Float64¶
Pure-XIOM arc tangent via series with reciprocal reduction.
- Postcondition:
(x != x) || (result >= -PI / 2 && result <= PI / 2)
fn atan2_pure(y: Float64, x: Float64) -> Float64¶
Pure-XIOM two-argument arc tangent with quadrant selection; rejects
(0, 0).
- Precondition:
x != 0 || y != 0
fn exp_pure(x: Float64) -> Float64¶
Pure-XIOM
e ^ xvia range reduction + 25-term series (overflow guard).
- Postcondition:
(x != x) || (result >= 0)
fn ln_pure(x: Float64) -> Float64¶
Pure-XIOM natural logarithm with atanh series; requires
x > 0.
- Precondition:
x > 0
fn log10_pure(x: Float64) -> Float64¶
Pure-XIOM base-10 logarithm; requires
x > 0.
- Precondition:
x > 0
fn log2_pure(x: Float64) -> Float64¶
Pure-XIOM base-2 logarithm; requires
x > 0.
- Precondition:
x > 0
mathematical_biology.xi¶
fn population_growth(r: Float64, n0: Float64, t: Float64) -> Float64¶
Exponential population size N0 * exp(r t). Complexity: O(1).
- Precondition:
n0 >= 0 - Postcondition:
(result != result) || (result >= 0)
fn logistic_growth(r: Float64, k: Float64, n0: Float64, t: Float64) -> Float64¶
Logistic growth N(t) = K N0 e^(rt) / (K + N0(e^(rt) - 1)). Returns K for n0 == 0 and 0 for t == 0 with n0 == 0 (documented). Complexity: O(1).
- Precondition:
k > 0 - Postcondition:
(n0 != 0) || (result == 0)
fn lotka_volterra(alpha: Float64, beta: Float64, gamma: Float64, delta: Float64, prey: Float64, pred: Float64, dt: Float64) -> (Float64, Float64)¶
One Euler step of the Lotka-Volterra predator-prey system: prey' = alphaprey - betapreypred, pred' = deltapreypred - gammapred. Returns (prey, pred). Complexity: O(1).
- Postcondition:
(dt != 0) || (result._0 != result._0) || (result._0 == prey) - Postcondition:
(dt != 0) || (result._1 != result._1) || (result._1 == pred)
fn epidemiological_sir(beta: Float64, gamma: Float64, s: Float64, i: Float64, r: Float64, dt: Float64) -> (Float64, Float64, Float64)¶
One SIR compartment step: S' = -beta S I, I' = beta S I - gamma I, R' = gamma I. Returns (S, I, R). Complexity: O(1).
- Postcondition:
(dt != 0) || (result._0 != result._0) || (result._0 == s) - Postcondition:
(dt != 0) || (result._1 != result._1) || (result._1 == i) - Postcondition:
(dt != 0) || (result._2 != result._2) || (result._2 == r)
fn epidemiological_seir(beta: Float64, sigma: Float64, gamma: Float64, s: Float64, e: Float64, i: Float64, r: Float64, dt: Float64) -> (Float64, Float64, Float64, Float64)¶
One SEIR compartment step: S' = -beta S I, E' = beta S I - sigma E, I' = sigma E - gamma I, R' = gamma I. Returns (S, E, I, R). Complexity: O(1).
- Postcondition:
(dt != 0) || (result._0 != result._0) || (result._0 == s) - Postcondition:
(dt != 0) || (result._1 != result._1) || (result._1 == e) - Postcondition:
(dt != 0) || (result._2 != result._2) || (result._2 == i) - Postcondition:
(dt != 0) || (result._3 != result._3) || (result._3 == r)
fn chemotherapy(growth: Float64, kill: Float64, tumor: Float64, dose: Float64, dt: Float64) -> Float64¶
Tumor size after a treatment step: tumor * exp((growth - kill*dose) dt). Complexity: O(1).
- Precondition:
tumor >= 0 - Postcondition:
(result != result) || (result >= 0)
fn genetics(p: Float64, q: Float64, selection: Float64) -> Vec[Float64]¶
Hardy-Weinberg genotype frequencies under selection on the homozygote (aa): p^2 w_AA : 2 p q w_Aa : q^2 w_aa, normalized. Returns a 3-vector (AA, Aa, aa). NaN for p + q far from 1 or negative frequencies. Complexity: O(1).
- Precondition:
p >= 0 - Precondition:
q >= 0 - Precondition:
selection >= 0 && selection <= 1 - Postcondition:
(result.len() == 0) || (result.len() == 3) - Postcondition:
(result.len() != 3) || (result[0] >= 0 && result[0] <= 1 && result[1] >= 0 && result[1] <= 1 && result[2] >= 0 && result[2] <= 1)
fn ecology(species: &Vec[Float64], interaction: &Vec[Vec[Float64]], dt: Float64) -> Vec[Float64]¶
One Lotka-Volterra multi-species step: x_i' = x_i (r_i - sum_j a_ij x_j) with the interaction matrix a and no intrinsic growth vector (r = 1). Returns the next-generation abundances. TODO(compiler): NOT IMPLEMENTABLE in this compiler build - the interaction matrix is a Vec[Vec[Float64]] whose element reads return garbage (BUG 23 #1 residual; verified by minimal probe). Keep the frozen signature; revisit when nested float Vec reads land.
fn immunology(antigen: Float64, antibody: Float64, infection_rate: Float64, clearance: Float64, dt: Float64) -> (Float64, Float64)¶
One immune-response step: antigen' = infection_rateantigen - antibodyantigen, antibody' = antigenantibody - clearanceantibody. Returns (antigen, antibody). Complexity: O(1).
- Postcondition:
(dt != 0) || (result._0 != result._0) || (result._0 == antigen) - Postcondition:
(dt != 0) || (result._1 != result._1) || (result._1 == antibody)
fn neuroscience(v: Float64, input: Float64, tau: Float64, threshold: Float64, dt: Float64) -> (Float64, Bool)¶
Leaky integrate-and-fire neuron update: v <- v + (input - v)/tau * dt; fires (v resets to 0) when v crosses the threshold. Returns (new_voltage, fired). Complexity: O(1). NOTE: the Bool tuple element cannot be computed or read back reliably in this compiler build (Bool-in-tuple codegen bug, see docs/COMPILER_BUGS.md BUG 23 #7; verified by minimal probes). The returned voltage resets to 0.0 when the neuron fires, so callers derive the flag from the voltage; the tuple's Bool element is a documented literal false placeholder.
- Postcondition:
result._1 == false
fn evolution(fitness: &Vec[Float64], population: &Vec[Float64], mutation: Float64) -> Vec[Float64]¶
Next-generation allele frequencies under selection and mutation: x_i' = (x_i w_i + mutation * (1/n - x_i)) / mean fitness, with w_i = fitness[i]. Empty for length mismatch. Complexity: O(n).
- Postcondition:
(result.len() == 0) || (result.len() == population.len())
mathematical_economics.xi¶
fn utility(bundle: &Vec[Float64], weights: &Vec[Float64]) -> Float64¶
Cobb-Douglas utility of a consumption bundle: prod x_i^w_i. NaN for a negative bundle entry or a length mismatch. Complexity: O(n).
- Postcondition:
(result != result) || (result >= 0)
fn production_cobb_douglas(a: Float64, alpha: Float64, beta: Float64, labor: Float64, capital: Float64) -> Float64¶
Cobb-Douglas production function A L^alpha K^beta. NaN for negative inputs. Complexity: O(1).
- Postcondition:
(result != result) || (result >= 0)
fn demand(price: Float64, income: Float64, elasticity: Float64) -> Float64¶
Quantity demanded at price p with constant elasticity: income * p^-e. Complexity: O(1).
- Precondition:
price > 0 - Precondition:
income >= 0 - Postcondition:
(result != result) || (result >= 0)
fn supply(price: Float64, cost: Float64, elasticity: Float64) -> Float64¶
Quantity supplied at price p with constant elasticity: cost * p^e. Complexity: O(1).
- Precondition:
price > 0 - Precondition:
cost >= 0 - Postcondition:
(result != result) || (result >= 0)
fn market_equilibrium(demand_fn: fn(Float64) -> Float64, supply_fn: fn(Float64) -> Float64) -> (Float64, Float64)¶
Equilibrium price and quantity where demand_fn(p) == supply_fn(p), found by bisection over [0, 1000] (300 iterations). NaN when no crossing exists. Complexity: O(300 * cost(demand_fn + supply_fn)).
- Postcondition:
(result._0 != result._0) || (result._0 >= 0 && result._0 <= 1000)
fn elasticity(q0: Float64, q1: Float64, p0: Float64, p1: Float64) -> Float64¶
Arc elasticity: ((q1 - q0)/((q0+q1)/2)) / ((p1 - p0)/((p0+p1)/2)). NaN for zero midpoints. Complexity: O(1).
- Precondition:
q0 + q1 != 0 - Precondition:
p0 + p1 != 0
fn marginal(f: fn(Float64) -> Float64, x: Float64, h: Float64) -> Float64¶
Finite-difference marginal value of f at x: (f(x+h) - f(x-h)) / (2h). NaN for h <= 0. Complexity: O(1) with 2 evaluations.
- Precondition:
h > 0
fn consumer_theory(prices: &Vec[Float64], income: Float64, utilities: fn(&Vec[Float64]) -> Float64) -> Vec[Float64]¶
Optimal consumption bundle: the income is allocated across goods in proportion to the marginal-utility weights supplied by
utilities; the returned bundle sums toincome. Empty for a length mismatch. Complexity: O(n * cost(utilities)).
- Postcondition:
(result.len() == 0) || (result.len() == prices.len())
fn producer_theory(prices: &Vec[Float64], costs: fn(&Vec[Float64]) -> Float64) -> Vec[Float64]¶
Profit-maximizing input combination by coordinate search: starting from a unit input vector, scale each input to maximize prices-x - costs(x). Returns the input vector. Empty for a price mismatch. Complexity: O(steps * n * cost(costs)).
- Postcondition:
(result.len() == 0) || (result.len() == prices.len())
fn general_equilibrium(endowments: &Vec[Vec[Float64]], utilities: &Vec[fn(&Vec[Float64]) -> Float64]) -> Vec[Float64]¶
Walrasian equilibrium price vector. TODO(compiler): NOT IMPLEMENTABLE in this compiler build - the endowment matrix is a Vec[Vec[Float64]] and the utility vector is a Vec[fn], whose element reads return garbage (BUG 23 #1 residual; verified by minimal probe). Keep the frozen signature; revisit when the fixes land.
fn auction_theory(bidders: &Vec[Float64], private_values: &Vec[Float64]) -> (Float64, Int)¶
Equilibrium revenue and winner of a second-price (Vickrey) auction: the highest bid wins and pays the second-highest bid; bidders are private values. Returns (price, winner_index); a single bidder pays the reserve. Complexity: O(n).
- Postcondition:
(result._1 == -1) || (result._1 >= 0 && result._1 < bidders.len())
fn mechanism_design(types: &Vec[Float64], valuations: fn(Int, Float64) -> Float64) -> Vec[Float64]¶
Incentive-compatible allocation rule: the total type space is allocated so that each type i receives a share proportional to valuations(i, types[i]). Empty for a mismatch. Complexity: O(n).
- Postcondition:
(result.len() == 0) || (result.len() == types.len())
mathematical_logic.xi¶
fn propositional(expr: Str) -> Bool¶
Validity of a propositional formula over the variables a..z: the formula evaluates true under every assignment. Complexity: O(2^vars * len).
fn predicate(expr: Str, domain: &Vec[Int]) -> Bool¶
Truth of a first-order formula over a finite domain: atoms P(d) hold when d is a member of the domain. Complexity: O(len).
fn first_order(formula: Str, structure: fn(&Vec[Int]) -> Bool) -> Bool¶
Satisfiability of a formula in a given structure: atoms P(d) are evaluated by structure([d]). Complexity: O(len * cost(structure)).
fn modal(formula: Str, world: Int, relations: &Vec[(Int, Int)]) -> Bool¶
Truth of a modal formula at a world: atoms are P
(predicate P holds of world k); [f] is true when f holds at every world reachable from the current one, when it holds at some reachable world. The relations vector is a list of (from, to) pairs. Complexity: O(len * reachable).
fn temporal(formula: Str, state: Int, next: fn(Int) -> Int) -> Bool¶
Temporal-logic truth evaluation along the successor run: atoms are P
(true at state k) and the next-time operator X shifts evaluation to next(current). Complexity: O(len * cost(next)).
fn fuzzy_logic(formula: Str, values: &Vec[Float64]) -> Float64¶
Fuzzy truth value in [0, 1] of a formula over the variable truth values in
values(a..z indexed; unknown variables default to 0). min/max/1-x semantics for &/|/!, and |a - b| for = (documented). Complexity: O(len).
fn provability(axioms: &Vec[Str], theorem: Str) -> Bool¶
Theorem follows from the axioms via the inference rules: true when the theorem string matches an axiom or a single modus ponens step (an axiom is an implication "a>b" and "a" is derivable). Complexity: O(axioms^2 * len).
- Postcondition:
(axioms.len() == 0) => (result == false)
fn model_theory(sentences: &Vec[Str], structure: fn(&Vec[Int]) -> Bool) -> Bool¶
Structure is a model of every sentence (atoms P(d) evaluated by the structure). Complexity: O(sentences * len).
- Postcondition:
(sentences.len() == 0) => (result == true)
fn proof_theory(axioms: &Vec[Str], rules: fn(&Vec[Str]) -> Vec[Str]) -> Vec[Str]¶
All formulas derivable from the axioms under the rule function
rules(one forward-chaining round, at most 50 derivations; the seed axioms are included first). Complexity: O(50 * cost(rules)).
- Postcondition:
result.len() >= axioms.len()
fn set_theory_axioms(axiom: Str) -> Bool¶
Validates an instance of the set-theoretic axiom schemas: the argument is matched by name against the known axioms (extensionality, empty, pairing, union, powerset, infinity, separation, replacement, regularity, choice). Complexity: O(len).
fn type_theory(term: Str, context: fn(Str) -> Str) -> Option[Str]¶
Type of a term in a typing context. TODO(compiler): NOT IMPLEMENTABLE - a sound type checker over an arbitrary string term language requires a context/term grammar that the finite string machinery here cannot faithfully represent. Keep the frozen signature; revisit with a concrete term syntax.
fn category_theory(obj: Str, morphisms: &Vec[(Str, Str, Str)]) -> Bool¶
Category axioms on objects and morphisms: the morphisms are (source, name, target) triples; the axioms verified are the existence of an identity per object and the closure/associativity of composition where defined. Complexity: O(morphisms^2).
- Postcondition:
(morphisms.len() == 0) => (result == true)
fn intuitionistic(formula: Str) -> Bool¶
Provability in intuitionistic propositional logic. TODO(compiler): NOT IMPLEMENTABLE - requires a genuine proof search (e.g. the sequent calculus) over the formula grammar; the finite validity check used by propositional/ is classical. Keep the frozen signature; revisit with a theorem-prover kernel.
fn linear_logic(formula: Str) -> Bool¶
Provability in resource-sensitive linear logic. TODO(compiler): NOT IMPLEMENTABLE - see intuitionistic (needs a proof search kernel; a truth-table semantics is unsound for linear logic).
fn relevance(formula: Str) -> Bool¶
Provability in relevance logic. TODO(compiler): NOT IMPLEMENTABLE - see intuitionistic (needs a proof search kernel with the relevance restriction).
mathematical_physics.xi¶
fn hamiltonian(q: &Vec[Float64], p: &Vec[Float64], h: fn(&Vec[Float64], &Vec[Float64]) -> Float64) -> Float64¶
Hamiltonian evaluated at state (q, p). Complexity: O(1) evaluation.
fn lagrangian(q: &Vec[Float64], qdot: &Vec[Float64], l: fn(&Vec[Float64], &Vec[Float64]) -> Float64) -> Float64¶
Lagrangian evaluated at (q, qdot). Complexity: O(1) evaluation.
fn quantum_operators(observable: &Vec[Vec[Float64]], state: &Vec[Float64]) -> Vec[Float64]¶
Apply an observable operator to a state vector. TODO(compiler): NOT IMPLEMENTABLE in this compiler build - the observable is a Vec[Vec[Float64]] whose element reads return garbage (BUG 23 #1 residual; verified by minimal probe). Keep the frozen signature; revisit when nested float Vec reads land.
fn pauli_matrices(index: Int) -> Vec[Vec[Float64]]¶
The index-th Pauli matrix (0 = identity, 1..3 = X, Y, Z) as a Vec[Vec[Float64]] 2x2. NaN-indexed inputs return an empty matrix. Complexity: O(1).
- Postcondition:
(index >= 0 && index <= 3) => (result.len() == 2) - Postcondition:
(index < 0 || index > 3) => (result.len() == 0)
fn gamma_matrices(dim: Int) -> Vec[Vec[Float64]]¶
Gamma matrices of the given spacetime dimension: for dim 2 the Pauli matrices; for dim 4 the Weyl representation. Other dimensions return the empty matrix. Complexity: O(dim^2).
- Postcondition:
(dim == 2 || dim == 4) => (result.len() == 4) - Postcondition:
(dim != 2 && dim != 4) => (result.len() == 0)
fn tensor_calculus(tensor: &Vec[Float64], metric: &Vec[Vec[Float64]]) -> Vec[Float64]¶
Raise or lower tensor indices with the metric. TODO(compiler): NOT IMPLEMENTABLE - the metric is a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn differential_geometry(chart: fn(&Vec[Float64]) -> Vec[Float64], point: &Vec[Float64]) -> Vec[Float64]¶
Coordinate derivatives of a chart at point: the flattened Jacobian of the chart (one output row per coordinate). Complexity: O(dim^2 * cost(chart)).
- Postcondition:
(point.len() == 0) || (result.len() % point.len() == 0)
fn riemannian(g: &Vec[Vec[Float64]], point: &Vec[Float64]) -> Float64¶
Ricci scalar or curvature invariant at point. TODO(compiler): NOT IMPLEMENTABLE - the metric is a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn symplectic(w: &Vec[Vec[Float64]], x: &Vec[Float64], y: &Vec[Float64]) -> Float64¶
Symplectic form applied to two vectors. TODO(compiler): NOT IMPLEMENTABLE - the form w is a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn lie_algebra(basis: &Vec[Vec[Vec[Float64]]], a: Int, b: Int) -> Vec[Vec[Float64]]¶
Structure-constant combination of two basis elements. TODO(compiler): NOT IMPLEMENTABLE - the basis is a triply nested float Vec whose element reads return garbage in this compiler build.
fn lie_group(algebra: &Vec[Vec[Vec[Float64]]], params: &Vec[Float64]) -> Vec[Vec[Float64]]¶
Group element from the exponential of the algebra. TODO(compiler): NOT IMPLEMENTABLE - the algebra is a nested float Vec whose element reads return garbage in this compiler build.
fn representation(group: &Vec[Vec[Float64]], algebra: &Vec[Vec[Float64]]) -> Vec[Vec[Float64]]¶
Linear representation of a group element. TODO(compiler): NOT IMPLEMENTABLE - the inputs are nested float Vecs whose element reads return garbage in this compiler build.
fn greens_function(operator: fn(&Vec[Float64]) -> Vec[Float64], source: &Vec[Float64]) -> Vec[Float64]¶
Green's function applied to a source: solve L u = source by Jacobi-style relaxation over the residual L(u) - source (matrix-free). Returns the approximate solution (at most 200 sweeps). Empty for an empty source. Complexity: O(sweeps * cost(operator)).
- Postcondition:
result.len() == source.len()
fn propagator(hamiltonian: &Vec[Vec[Float64]], t: Float64) -> Vec[Vec[Float64]]¶
Time-evolution operator exp(-i H t) via the truncated series sum (-i H t)^k / k! (8 terms), built locally. The returned matrix is computed from the Hamiltonian's elements; callers should rely on its shape. TODO(compiler): the Hamiltonian is a Vec[Vec[Float64]] whose element reads return garbage in this compiler build, so the series degenerates to the identity matrix of the input's shape. Keep the frozen signature; revisit when nested float Vec reads land.
- Postcondition:
(hamiltonian.len() == 0) => (result.len() == 0) - Postcondition:
(hamiltonian.len() > 0) => (result.len() == hamiltonian.len())
fn path_integral(action: fn(&Vec[Float64]) -> Float64, paths: &Vec[Vec[Float64]]) -> Vec[Float64]¶
Amplitudes of a discretized path integral. TODO(compiler): NOT IMPLEMENTABLE - the paths are a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
matrices.xi¶
type Mat2¶
2x2 column-major matrix.
| Field | Type |
|---|---|
m00 |
Float64 |
m01 |
Float64 |
m10 |
Float64 |
m11 |
Float64 |
type Mat3¶
3x3 column-major matrix.
| Field | Type |
|---|---|
m00 |
Float64 |
m01 |
Float64 |
m02 |
Float64 |
m10 |
Float64 |
m11 |
Float64 |
m12 |
Float64 |
m20 |
Float64 |
m21 |
Float64 |
m22 |
Float64 |
type Mat4¶
4x4 column-major matrix.
| Field | Type |
|---|---|
m00 |
Float64 |
m01 |
Float64 |
m02 |
Float64 |
m03 |
Float64 |
m10 |
Float64 |
m11 |
Float64 |
m12 |
Float64 |
m13 |
Float64 |
m20 |
Float64 |
m21 |
Float64 |
m22 |
Float64 |
m23 |
Float64 |
m30 |
Float64 |
m31 |
Float64 |
m32 |
Float64 |
m33 |
Float64 |
fn mat2_new(a11: Float64, a12: Float64, a21: Float64, a22: Float64) -> Mat2¶
Construct a 2x2 matrix from elements in row-major reading order (a11 a12 / a21 a22) stored column-major. O(1).
- Postcondition:
((((result.m00 == a11) || (result.m00 != result.m00)) && ((result.m01 == a12) || (result.m01 != result.m01))) && ((result.m10 == a21) || (result.m10 != result.m10))) && ((result.m11 == a22) || (result.m11 != result.m11))
fn mat2_mul(a: Mat2, b: Mat2) -> Mat2¶
Matrix product a * b (2x2). O(8) ops.
- Postcondition:
((((result.m00 == a.m00 * b.m00 + a.m01 * b.m10) || (result.m00 != result.m00)) && ((result.m01 == a.m00 * b.m01 + a.m01 * b.m11) || (result.m01 != result.m01))) && ((result.m10 == a.m10 * b.m00 + a.m11 * b.m10) || (result.m10 != result.m10))) && ((result.m11 == a.m10 * b.m01 + a.m11 * b.m11) || (result.m11 != result.m11))
fn mat2_det(m: Mat2) -> Float64¶
Determinant of a 2x2 matrix: m00m11 - m01m10. O(1).
- Postcondition:
(result == m.m00 * m.m11 - m.m01 * m.m10) || (result != result)
fn mat2_inv(m: Mat2) -> Option[Mat2]¶
Inverse of a 2x2 matrix via the adjugate formula. Returns None when the determinant is near zero (|det| < 1e-12, documented singularity cutoff). O(1).
- Postcondition:
(result is None) => ((m.m00 * m.m11 - m.m01 * m.m10) * (m.m00 * m.m11 - m.m01 * m.m10) < 0.000000000000000000000001)
fn mat2_transpose(m: Mat2) -> Mat2¶
Transpose of a 2x2 matrix. O(1).
- Postcondition:
((((result.m00 == m.m00) || (result.m00 != result.m00)) && ((result.m01 == m.m10) || (result.m01 != result.m01))) && ((result.m10 == m.m01) || (result.m10 != result.m10))) && ((result.m11 == m.m11) || (result.m11 != result.m11))
fn mat3_new(a11: Float64, a12: Float64, a13: Float64, a21: Float64, a22: Float64, a23: Float64, a31: Float64, a32: Float64, a33: Float64) -> Mat3¶
Construct a 3x3 matrix from elements in row-major reading order (three rows) stored column-major. O(1).
- Postcondition:
((((((result.m00 == a11) || (result.m00 != result.m00)) && ((result.m01 == a12) || (result.m01 != result.m01))) && ((result.m02 == a13) || (result.m02 != result.m02))) && (((result.m10 == a21) || (result.m10 != result.m10)) && ((result.m11 == a22) || (result.m11 != result.m11)))) && (((result.m12 == a23) || (result.m12 != result.m12)) && ((result.m20 == a31) || (result.m20 != result.m20)))) && (((result.m21 == a32) || (result.m21 != result.m21)) && ((result.m22 == a33) || (result.m22 != result.m22)))
fn mat3_mul(a: Mat3, b: Mat3) -> Mat3¶
Matrix product a * b (3x3). O(27) ops.
- Postcondition:
((result.m00 == a.m00 * b.m00 + a.m01 * b.m10 + a.m02 * b.m20) || (result.m00 != result.m00)) && ((result.m01 == a.m00 * b.m01 + a.m01 * b.m11 + a.m02 * b.m21) || (result.m01 != result.m01)) && ((result.m02 == a.m00 * b.m02 + a.m01 * b.m12 + a.m02 * b.m22) || (result.m02 != result.m02)) - Postcondition:
((result.m10 == a.m10 * b.m00 + a.m11 * b.m10 + a.m12 * b.m20) || (result.m10 != result.m10)) && ((result.m11 == a.m10 * b.m01 + a.m11 * b.m11 + a.m12 * b.m21) || (result.m11 != result.m11)) && ((result.m12 == a.m10 * b.m02 + a.m11 * b.m12 + a.m12 * b.m22) || (result.m12 != result.m12)) - Postcondition:
((result.m20 == a.m20 * b.m00 + a.m21 * b.m10 + a.m22 * b.m20) || (result.m20 != result.m20)) && ((result.m21 == a.m20 * b.m01 + a.m21 * b.m11 + a.m22 * b.m21) || (result.m21 != result.m21)) && ((result.m22 == a.m20 * b.m02 + a.m21 * b.m12 + a.m22 * b.m22) || (result.m22 != result.m22))
fn mat3_det(m: Mat3) -> Float64¶
Determinant of a 3x3 matrix by cofactor expansion. O(9) ops.
- Postcondition:
(result == m.m00 * (m.m11 * m.m22 - m.m12 * m.m21) - m.m01 * (m.m10 * m.m22 - m.m12 * m.m20) + m.m02 * (m.m10 * m.m21 - m.m11 * m.m20)) || (result != result)
fn mat3_inv(m: Mat3) -> Option[Mat3]¶
Inverse of a 3x3 matrix via the adjugate formula. Returns None when the determinant is near zero (|det| < 1e-12, documented singularity cutoff). O(27) ops.
- Postcondition:
(result is None) => (((m.m00 * (m.m11 * m.m22 - m.m12 * m.m21) - m.m01 * (m.m10 * m.m22 - m.m12 * m.m20) + m.m02 * (m.m10 * m.m21 - m.m11 * m.m20)) * (m.m00 * (m.m11 * m.m22 - m.m12 * m.m21) - m.m01 * (m.m10 * m.m22 - m.m12 * m.m20) + m.m02 * (m.m10 * m.m21 - m.m11 * m.m20))) < 0.000000000000000000000001)
fn mat3_transpose(m: Mat3) -> Mat3¶
Transpose of a 3x3 matrix. O(1).
- Postcondition:
((((((result.m00 == m.m00) || (result.m00 != result.m00)) && ((result.m01 == m.m10) || (result.m01 != result.m01))) && ((result.m02 == m.m20) || (result.m02 != result.m02))) && (((result.m10 == m.m01) || (result.m10 != result.m10)) && ((result.m11 == m.m11) || (result.m11 != result.m11)))) && (((result.m12 == m.m21) || (result.m12 != result.m12)) && ((result.m20 == m.m02) || (result.m20 != result.m20)))) && (((result.m21 == m.m12) || (result.m21 != result.m21)) && ((result.m22 == m.m22) || (result.m22 != result.m22)))
fn mat4_new(a11: Float64, a12: Float64, a13: Float64, a14: Float64, a21: Float64, a22: Float64, a23: Float64, a24: Float64, a31: Float64, a32: Float64, a33: Float64, a34: Float64, a41: Float64, a42: Float64, a43: Float64, a44: Float64) -> Mat4¶
Construct a 4x4 matrix from elements in row-major reading order (four rows) stored column-major. O(1).
- Postcondition:
((result.m00 == a11) || (result.m00 != result.m00)) && ((result.m01 == a12) || (result.m01 != result.m01)) && ((result.m02 == a13) || (result.m02 != result.m02)) && ((result.m03 == a14) || (result.m03 != result.m03)) - Postcondition:
((result.m10 == a21) || (result.m10 != result.m10)) && ((result.m11 == a22) || (result.m11 != result.m11)) && ((result.m12 == a23) || (result.m12 != result.m12)) && ((result.m13 == a24) || (result.m13 != result.m13)) - Postcondition:
((result.m20 == a31) || (result.m20 != result.m20)) && ((result.m21 == a32) || (result.m21 != result.m21)) && ((result.m22 == a33) || (result.m22 != result.m22)) && ((result.m23 == a34) || (result.m23 != result.m23)) - Postcondition:
((result.m30 == a41) || (result.m30 != result.m30)) && ((result.m31 == a42) || (result.m31 != result.m31)) && ((result.m32 == a43) || (result.m32 != result.m32)) && ((result.m33 == a44) || (result.m33 != result.m33))
fn mat4_mul(a: Mat4, b: Mat4) -> Mat4¶
Matrix product a * b (4x4). O(64) ops.
fn mat4_det(m: Mat4) -> Float64¶
Determinant of a 4x4 matrix by cofactor expansion along the first row (3x3 sub-determinants of the lower rows). O(48) ops.
fn mat4_inv(m: Mat4) -> Option[Mat4]¶
Inverse of a 4x4 matrix via the adjugate (cofactor-transpose / det). Returns None when |det| < 1e-12 (documented singularity cutoff). O(150).
- Postcondition:
(result is None) => (math.abs_float(mat4_det(m)) < 0.000000000001)
fn mat4_transpose(m: Mat4) -> Mat4¶
Transpose of a 4x4 matrix. O(1).
- Postcondition:
((result.m00 == m.m00) || (result.m00 != result.m00)) && ((result.m01 == m.m10) || (result.m01 != result.m01)) && ((result.m02 == m.m20) || (result.m02 != result.m02)) && ((result.m03 == m.m30) || (result.m03 != result.m03)) - Postcondition:
((result.m10 == m.m01) || (result.m10 != result.m10)) && ((result.m11 == m.m11) || (result.m11 != result.m11)) && ((result.m12 == m.m21) || (result.m12 != result.m12)) && ((result.m13 == m.m31) || (result.m13 != result.m13)) - Postcondition:
((result.m20 == m.m02) || (result.m20 != result.m20)) && ((result.m21 == m.m12) || (result.m21 != result.m21)) && ((result.m22 == m.m22) || (result.m22 != result.m22)) && ((result.m23 == m.m32) || (result.m23 != result.m23)) - Postcondition:
((result.m30 == m.m03) || (result.m30 != result.m30)) && ((result.m31 == m.m13) || (result.m31 != result.m31)) && ((result.m32 == m.m23) || (result.m32 != result.m32)) && ((result.m33 == m.m33) || (result.m33 != result.m33))
fn mat_identity(n: Int) -> Vec[Vec[Float64]]¶
n x n identity matrix. Returns an empty matrix for n <= 0 (documented). O(n^2).
- Postcondition:
((n <= 0) => (result.len() == 0)) && ((n > 0) => (result.len() == n))
fn mat_mul(a: &Vec[Vec[Float64]], b: &Vec[Vec[Float64]]) -> Vec[Vec[Float64]]¶
Dynamic matrix product a * b. Returns an empty matrix when the inner dimensions disagree (a.cols != b.rows), or when either input is empty (documented; no silent garbage). O(rows * cols * inner).
- Postcondition:
(result.len() == 0) || (result.len() == a.len())
fn mat_det(m: &Vec[Vec[Float64]]) -> Float64¶
Determinant of a dynamic square matrix via Laplace cofactor expansion. Returns NaN (0.0/0.0) for non-square or empty input (documented). O(n!).
- Postcondition:
(m.len() == 0) => (result != result)
fn mat_inv(m: &Vec[Vec[Float64]]) -> Option[Vec[Vec[Float64]]]¶
Inverse of a dynamic square matrix via Gauss-Jordan elimination. Returns None for non-square, empty, or (numerically) singular input (documented; pivot tolerance 1e-12). O(n^3).
- Postcondition:
(m.len() == 0) => (result is None)
fn mat_translate(m: &Vec[Vec[Float64]], x: Float64, y: Float64, z: Float64) -> Vec[Vec[Float64]]¶
m * T where T is the 4x4 translation matrix by (x, y, z). When m is not 4x4 the input is returned unchanged (documented). O(1).
- Postcondition:
result.len() == m.len()
fn mat_rotate(m: &Vec[Vec[Float64]], angle: Float64, axis: &Vec[Float64]) -> Vec[Vec[Float64]]¶
m * R where R is the 4x4 rotation by angle radians about axis (axis is normalised internally). A zero axis returns m unchanged (documented); a non-4x4 m is returned unchanged. O(1).
- Postcondition:
result.len() == m.len()
fn mat_scale(m: &Vec[Vec[Float64]], x: Float64, y: Float64, z: Float64) -> Vec[Vec[Float64]]¶
m * S where S is the 4x4 scale matrix by (x, y, z). A non-4x4 m is returned unchanged (documented). O(1).
- Postcondition:
result.len() == m.len()
fn mat_look_at(eye: &Vec[Float64], target: &Vec[Float64], up: &Vec[Float64]) -> Vec[Vec[Float64]]¶
Right-handed look-at view matrix: camera at eye looking at target with up vector. eye/target/up are length-3 dynamic vectors; vectors of any other length return an empty matrix (documented). O(1).
- Postcondition:
(result.len() == 0) || (result.len() == 4)
fn mat_perspective(fovy: Float64, aspect: Float64, near: Float64, far: Float64) -> Vec[Vec[Float64]]¶
Perspective projection matrix (right-handed, standard OpenGL mapping to NDC [-1, 1]^3). Returns an empty matrix for fovy <= 0, aspect <= 0, or near == far (documented). O(1).
- Postcondition:
(result.len() == 0) || (result.len() == 4)
fn mat_ortho(left: Float64, right: Float64, bottom: Float64, top: Float64, near: Float64, far: Float64) -> Vec[Vec[Float64]]¶
Orthographic projection matrix mapping [l, r] x [b, t] x [n, f] to NDC [-1, 1]^3. Returns an empty matrix when any two facing planes coincide (documented). O(1).
- Postcondition:
(result.len() == 0) || (result.len() == 4)
modular.xi¶
fn mod_add(a: Int, b: Int, m: Int) -> Int¶
(a + b) mod m with the result in [0, m). Returns 0 for m <= 0 (no modulus, documented) and 0 for m == 1 (everything is 0 mod 1). Complexity: O(1).
- Postcondition:
result >= 0 && (m <= 1 || result < m)
fn mod_sub(a: Int, b: Int, m: Int) -> Int¶
(a - b) mod m with the result in [0, m). Returns 0 for m <= 0 (no modulus, documented) and 0 for m == 1. Complexity: O(1).
- Postcondition:
result >= 0 && (m <= 1 || result < m)
fn mod_mul(a: Int, b: Int, m: Int) -> Int¶
(a * b) mod m with the result in [0, m). Uses overflow-free double-and-add. Returns 0 for m <= 0 (no modulus, documented) and 0 for m == 1. Complexity: O(log min(a, b)).
- Postcondition:
result >= 0 && (m <= 1 || result < m)
fn mod_pow(base: Int, exp: Int, m: Int) -> Int¶
base^exp mod m with the result in [0, m). Delegates to xiom.math.arithmetic.pow_mod. Returns 0 for m <= 0, m == 1, and exp < 0 (documented; only non-negative exponents are supported). Complexity: O(log exp).
- Postcondition:
result >= 0 && (m <= 1 || result < m)
fn mod_inverse(a: Int, m: Int) -> Int¶
Multiplicative inverse of a mod m: x with (a*x) % m == 1. Returns 0 when no inverse exists (gcd(a, m) != 1), when m == 0 (no modulus) and for m == 1 (documented). Delegates to xiom.math.arithmetic.mod_inverse. Complexity: O(log min(|a|, |m|)).
- Postcondition:
result >= 0 && (m <= 1 || result < m)
fn mod_sqrt(a: Int, p: Int) -> Int¶
A square root of a mod prime p (x with x^2 == a mod p), choosing the root in [0, (p-1)/2]. Returns 0 when no root exists, when p <= 1 (no modulus) and when p is composite (documented: p must be prime). Delegates to tonelli_shanks. Complexity: O(log^3 p).
- Postcondition:
p <= 2 || (result >= 0 && result <= (p - 1) / 2)
fn mod_cbrt(a: Int, m: Int) -> Int¶
A cube root of a mod m: x with x^3 == a mod m. For prime m with gcd(3, m-1) == 1 the root is a^((2m-1)/3) mod m; for m == 1 (mod 3) a small scan is used. Returns 0 when no root exists, for m <= 0 (no modulus) and when m == 1. Complexity: O(log m) for the closed form, O(m) scan otherwise.
- Postcondition:
result >= 0 && (m <= 1 || result < m)
fn mod_div(a: Int, b: Int, m: Int) -> Int¶
(a / b) mod m: a * b^(-1) mod m. Returns 0 when b has no inverse mod m (gcd(b, m) != 1), when m <= 0 (no modulus) and for m == 1 (documented). Complexity: O(log min(|b|, |m|)).
- Postcondition:
result >= 0 && (m <= 1 || result < m)
fn mod_lcm(a: Int, b: Int, m: Int) -> Int¶
Least common multiple of a and b reduced mod m. Returns 0 when m <= 0 (no modulus), for m == 1 and when either input is 0. Uses the overflow-free modular multiply so the true lcm may exceed Int range. Complexity: O(log).
- Postcondition:
result >= 0 && (m <= 1 || result < m)
fn crt(remainders: &Vec[Int], moduli: &Vec[Int]) -> Int¶
Chinese remainder theorem solution x with x % m_i == r_i for every pair. Returns 0 when the slices differ in length, when either slice is empty, when any modulus is non-positive, when the moduli are not pairwise coprime, and when the product of the moduli overflows Int (documented). The result lies in [0, M) with M = prod(m_i). Complexity: O(n^2 * log max(m_i)).
- Postcondition:
result >= 0
fn crt_solve(congruences: &Vec[(Int, Int)]) -> Int¶
Solve a system of congruences given as (remainder, modulus) pairs using the iterative merging method. Returns 0 when the list is empty, when any modulus is non-positive, when the system is inconsistent, and on overflow (documented). Complexity: O(n * log max(m_i)).
- Postcondition:
result >= 0
fn linear_congruence(a: Int, b: Int, m: Int) -> Int¶
Solve a*x == b (mod m): returns the least non-negative solution. Returns 0 when m <= 0 (no modulus), when m == 1, when gcd(a, m) does not divide b (no solution) and on overflow (documented). Complexity: O(log min(|a|, |m|)).
- Postcondition:
result >= 0 && (m <= 1 || result < m)
fn quadratic_residue(a: Int, p: Int) -> Bool¶
True iff a is a quadratic residue mod prime p, i.e. x^2 == a (mod p) has a solution. a == 0 (mod p) counts as a residue (x = 0). Returns false for p <= 1 (no modulus). Uses Euler's criterion. Complexity: O(log p).
- Postcondition:
result == false || p >= 2
fn tonelli_shanks(n: Int, p: Int) -> Int¶
Square root of n mod odd prime p via the Tonelli-Shanks algorithm, choosing the root in [0, (p-1)/2]. Returns 0 when n is a non-residue mod p, for p <= 2 (p == 2 is handled directly) and when p is composite (documented: p must be prime). Complexity: O(log^3 p).
- Postcondition:
p <= 2 || (result >= 0 && result <= (p - 1) / 2)
fn cipolla(n: Int, p: Int) -> Int¶
Square root of n mod odd prime p via Cipolla's algorithm, choosing the root in [0, (p-1)/2]. Returns 0 when n is a non-residue mod p, for p <= 2 (p == 2 is handled directly) and when p is composite (documented: p must be prime). Complexity: O(log^2 p).
- Postcondition:
p <= 2 || (result >= 0 && result <= (p - 1) / 2)
fn cornacchia(d: Int, b: Int, m: Int) -> (Int, Int)¶
Cornacchia's algorithm: find integers x, y >= 0 with x^2 + d*y^2 = m. The parameter b is a square root of -d modulo m (the caller must supply one; for prime m this is sqrt(-d) mod m, e.g. via tonelli_shanks). Returns (0, 0) when d <= 0, when no representation exists, and on overflow (documented). Complexity: O(log^2 m).
- Postcondition:
result._0 >= 0 && result._1 >= 0
fn hilbert_symbol(a: Int, b: Int, p: Int) -> Int¶
Local Hilbert symbol (a, b)_p over Q_p, returning 1 or -1. Uses the standard factorization: for odd p, (a,b)_p = (-1)^(alpha*beta) * (u/p)^beta * (v/p)^alpha with a = p^alpha * u, b = p^beta * v; for p == 2 the explicit epsilon/omega formula is used. Returns 0 when a or b is 0 (the symbol is degenerate there, documented). Complexity: O(log_p |a| + log_p |b| + log p).
- Postcondition:
result >= -1 && result <= 1
fn pow_mod_fast(base: Int, exp: Int, m: Int) -> Int¶
Fast modular exponentiation base^exp mod m. Alias of xiom.math.arithmetic.pow_mod; returns 0 for m <= 0, m == 1 and exp < 0 (documented). Complexity: O(log exp).
- Postcondition:
result >= 0 && (m <= 1 || result < m)
number_systems.xi¶
fn binary_to_int(s: Str) -> Result[Int, Str]¶
Binary string to Int. Err("invalid") for empty, non-'0'/'1', or overflow input. Complexity: O(len).
- Postcondition:
(s.len() == 0) => (result.is_err == true)
fn int_to_binary(n: Int) -> Str¶
Decimal Int to a binary string. n == 0 yields "0"; negatives get a '-' prefix. Complexity: O(log n).
- Postcondition:
((n == 0) => (result == "0")) && ((n < 0) => (result != ""))
fn octal_to_int(s: Str) -> Result[Int, Str]¶
Octal string to Int. Err on invalid input. Complexity: O(len).
- Postcondition:
(s.len() == 0) => (result.is_err == true)
fn int_to_octal(n: Int) -> Str¶
Decimal Int to an octal string. Complexity: O(log n).
- Postcondition:
((n == 0) => (result == "0")) && ((n < 0) => (result != ""))
fn hex_to_int(s: Str) -> Result[Int, Str]¶
Hexadecimal string to Int. Err on invalid input. Complexity: O(len).
- Postcondition:
(s.len() == 0) => (result.is_err == true)
fn int_to_hex(n: Int) -> Str¶
Decimal Int to a hexadecimal string (upper-case digits). Complexity: O(log n).
- Postcondition:
((n == 0) => (result == "0")) && ((n < 0) => (result != ""))
fn base_n_to_int(s: Str, base: Int) -> Result[Int, Str]¶
Parse a string in an arbitrary base (2..36) to Int. Err on invalid input, an out-of-range base, or overflow. Complexity: O(len).
- Postcondition:
((base < 2) || (base > 36)) => (result.is_ok == false)
fn int_to_base_n(n: Int, base: Int) -> Str¶
Decimal Int to a string in an arbitrary base (2..36). Returns "" for an out-of-range base. Complexity: O(log n).
- Postcondition:
(((base < 2) || (base > 36)) => (result == "")) && (((base >= 2) && (base <= 36) && (n == 0)) => (result == "0"))
fn roman_to_int(s: Str) -> Result[Int, Str]¶
Roman numeral string to Int. Err for empty or invalid input; subtractive notation (IV, IX, XL, XC, CD, CM) is supported. Complexity: O(len).
- Postcondition:
(s.len() == 0) => (result.is_err == true) - Postcondition:
(result.is_ok == true) => (result.value >= 1) - Postcondition:
(result.is_err == true) => (result.error.len() > 0)
fn int_to_roman(n: Int) -> Str¶
Int to a Roman numeral string (1..3999); "" outside that range. Complexity: O(n).
- Postcondition:
(((n < 1) || (n > 3999)) => (result == "")) && (((n >= 1) && (n <= 3999)) => (result != ""))
fn chinese_numerals(n: Int) -> Str¶
Int to a Chinese numeral string (supports 0..99999999; larger values return the 亿-form with the remainder documented). Complexity: O(log n).
- Postcondition:
result != ""
fn japanese_numerals(n: Int) -> Str¶
Int to a Japanese numeral string (〇一...九 + 十百千万; 0..99999999). Complexity: O(log n).
- Postcondition:
result != ""
fn egyptian_fractions(numer: Int, denom: Int) -> Vec[(Int, Int)]¶
Greedy Egyptian fraction expansion of numer/denom as (1, unit) pairs. Empty for a non-positive numerator or denominator. Complexity: O(denom).
- Postcondition:
(((numer <= 0) || (denom <= 0)) => (result.len() == 0)) && (((numer > 0) && (denom > 0)) => (result.len() > 0))
fn babylonian_numerals(n: Int) -> Str¶
Babylonian-style base-60 notation: the sexagesimal places of n joined by ';' (a documented approximation of cuneiform numerals). n == 0 yields "0". Complexity: O(log_60 n).
- Postcondition:
((n == 0) => (result == "0")) && ((n != 0) => (result != ""))
fn greek_numerals(n: Int) -> Str¶
Int to a Greek alphabetic numeral string (1..999 using the standard archaic digits; "" outside the range). Complexity: O(log n).
- Postcondition:
(((n < 1) || (n > 999)) => (result == "")) && (((n >= 1) && (n <= 999)) => (result != ""))
fn continued_fraction(x: Float64, terms: Int) -> Vec[Int]¶
Continued-fraction coefficients of x (at most
termsof them). Complexity: O(terms).
- Postcondition:
(((terms <= 0) || (x != x)) => (result.len() == 0)) && (((terms > 0) && (x == x)) => (result.len() <= terms))
fn fraction_new(numer: Int, denom: Int) -> (Int, Int)¶
Reduced fraction (numer / gcd, denom / gcd) with the sign on the numerator. Returns (0, 1) for denom == 0. Complexity: O(log n).
- Postcondition:
((denom == 0) => ((result._0 == 0) && (result._1 == 1))) && ((denom != 0) => (result._1 > 0))
fn fraction_add(a: (Int, Int), b: (Int, Int)) -> (Int, Int)¶
Sum of two reduced fractions (reduced again). Complexity: O(log n).
- Postcondition:
result._1 > 0
fn surd_simplify(a: Int, b: Int) -> (Int, Int)¶
Simplify sqrt(a)/sqrt(b) to (coefficient, radicand): the largest square factor of ab is pulled out of the radical. Returns (1, 1) for b == 0. Complexity: O(sqrt(ab)).
- Postcondition:
(((b == 0) => ((result._0 == 1) && (result._1 == 1))) && (((a == 0) && (b != 0)) => ((result._0 == 0) && (result._1 == 1)))) && (((a != 0) && (b != 0) && ((a * b) > 0)) => ((result._0 >= 1) && (result._1 >= 1)))
fn octonion_add(a: &Vec[Float64], b: &Vec[Float64]) -> Vec[Float64]¶
Componentwise sum of two octonions (8 components). Empty for a length mismatch. Complexity: O(8).
- Postcondition:
(result.len() == 0) || (result.len() == 8)
fn sedenion_add(a: &Vec[Float64], b: &Vec[Float64]) -> Vec[Float64]¶
Componentwise sum of two sedenions (16 components). Empty for a length mismatch. Complexity: O(16).
- Postcondition:
(result.len() == 0) || (result.len() == 16)
number_theory.xi¶
fn is_prime(n: Int) -> Bool¶
Deterministic primality test for 64-bit n (Miller-Rabin over the fixed base set {2, 325, 9375, 28178, 450775, 9780504, 1795265022}, which is proven for every n < 2^64). Returns false for n < 2. Complexity: O(log^3 n).
- Postcondition:
(n < 2) => (result == false) - Postcondition:
(n == 2) => (result == true)
fn is_prime_deterministic(n: Int) -> Bool¶
Strict deterministic primality test: Miller-Rabin with the fixed base set proven correct for all 64-bit integers. Returns false for n < 2. Complexity: O(log^3 n).
- Postcondition:
(n < 2) => (result == false) - Postcondition:
(n == 2) => (result == true) - Postcondition:
(n > 2 && n % 2 == 0) => (result == false)
fn next_prime(n: Int) -> Int¶
Smallest prime strictly greater than n. Returns 0 for n < 0 (no positive prime is representable in range for the largest inputs) and 0 when no such prime fits in Int (n >= INT_MAX - 1). Complexity: O(gap * sqrt(p)).
- Postcondition:
(n < 2) => (result == 2) - Postcondition:
(n >= 2 && result != 0) => (result > n) - Postcondition:
(n >= 9223372036854775806) => (result == 0)
fn prev_prime(n: Int) -> Int¶
Largest prime strictly less than n. Returns 0 for n <= 2 (no such prime) and 0 (documented) when the search leaves the representable range. Complexity: O(gap * sqrt(p)).
- Postcondition:
(n <= 2) => (result == 0) - Postcondition:
(result != 0) => (result < n) - Postcondition:
result >= 0
fn factor(n: Int) -> Vec[Int]¶
Prime factorization of n with multiplicity. Returns the empty list for n <= 1; negative n is factored by absolute value. Complexity: O(sqrt(|n|)).
- Postcondition:
(n <= 1) => (result.len() == 0) - Postcondition:
(n > 1) => (result.len() >= 1)
fn pollard_rho(n: Int) -> Int¶
A non-trivial factor of n via Pollard's rho (Floyd cycle detection with f(x) = x^2 + c mod n). Returns n itself when n is prime or when no split is found within the retry budget (documented; a repeated call with a different internal constant is the standard recovery). Returns 1 for n <= 1. Complexity: O(sqrt(p)) expected for the smallest prime factor p.
- Postcondition:
result >= 1 - Postcondition:
(n > 1) => (result <= n)
fn p_1_factor(n: Int) -> Int¶
A non-trivial factor of n via Pollard's p-1 method (a = 2^B! mod n for an increasing stage bound B). Returns n itself when n is prime or when no factor is found within the stage bound (documented). Returns 1 for n <= 1. Complexity: O(B * log B * mulmod).
- Postcondition:
result >= 1 - Postcondition:
(n > 1) => (result <= n)
fn is_pseudoprime(n: Int, base: Int) -> Bool¶
True iff n passes the Fermat test for base a, i.e. a^(n-1) == 1 (mod n). Returns false for n <= 1, true for n == 2, and false when a is a multiple of n (the residue is 0, not 1). Primes always pass; composite pseudoprimes to base a also return true. Complexity: O(log n).
- Postcondition:
(n <= 1) => (result == false) - Postcondition:
(n == 2) => (result == true)
fn miller_rabin(n: Int, bases: &Vec[Int]) -> Bool¶
Miller-Rabin strong pseudoprime test against the supplied bases. Returns false for n <= 1, even n (n > 2) and for any base witnessing compositeness; a value that passes every base is reported true (likely prime, exactly prime for n < 2^64 when the base set is the deterministic one). Complexity: O(|bases| * log^3 n).
- Postcondition:
(n <= 1) => (result == false) - Postcondition:
(n == 2) => (result == true) - Postcondition:
(n > 2 && n % 2 == 0) => (result == false) - Postcondition:
(bases.len() == 0 && n > 2 && n % 2 != 0) => (result == true)
fn fermat_test(n: Int, a: Int) -> Bool¶
Fermat compositeness test with base a: true iff a^(n-1) == 1 (mod n). Alias of is_pseudoprime. Complexity: O(log n).
- Postcondition:
(n <= 1) => (result == false) - Postcondition:
(n == 2) => (result == true)
fn lucas_lehmer(p: Int) -> Bool¶
Lucas-Lehmer primality test for the Mersenne number M_p = 2^p - 1. Returns false for p < 2 and when M_p does not fit in Int (p > 62). Complexity: O(p * mulmod).
- Postcondition:
(p < 2) => (result == false) - Postcondition:
(p == 2) => (result == true) - Postcondition:
(p > 62) => (result == false)
fn mersenne_prime_p(p: Int) -> Bool¶
True iff 2^p - 1 is prime. Alias of lucas_lehmer. Returns false for p < 2 and when M_p exceeds Int range. Complexity: O(p * mulmod).
- Postcondition:
(p < 2) => (result == false) - Postcondition:
(p == 2) => (result == true) - Postcondition:
(p > 62) => (result == false)
fn euler_phi(n: Int) -> Int¶
Euler totient phi(n): count of integers k in [1, n] coprime to n. Returns 0 for n <= 0 (documented). Complexity: O(sqrt(n)).
- Postcondition:
(n <= 0) => (result == 0) - Postcondition:
(n > 0) => (result >= 1 && result <= n)
fn mobius(n: Int) -> Int¶
Mobius function mu(n): 0 if n has a squared prime factor, otherwise (-1)^k with k the number of distinct prime factors. Returns 0 for n <= 0 (documented). Complexity: O(sqrt(n)).
- Postcondition:
(n <= 0) => (result == 0) - Postcondition:
(n > 0) => (result >= -1 && result <= 1)
fn jordan_totient(n: Int, k: Int) -> Int¶
Jordan totient J_k(n): count of k-tuples (x_1..x_k) in [1, n]^k that are jointly coprime to n. Returns 0 for n <= 0, 1 for n == 1, 0 for k < 0 (documented) and 0 for k == 0 with n > 1 (J_0(n) = 0). Returns 0 (documented overflow) when the value exceeds Int range. Complexity: O(sqrt(n) * log k).
- Postcondition:
(n <= 0) => (result == 0) - Postcondition:
(n == 1) => (result == 1) - Postcondition:
(n > 1 && k <= 0) => (result == 0)
fn carmichael(n: Int) -> Int¶
Carmichael lambda function: the smallest m with a^m == 1 (mod n) for every a coprime to n. Computed as the lcm of lambda(p^a) over the prime powers dividing n: lambda(2) = 1, lambda(4) = 2, lambda(2^a) = 2^(a-2) for a >= 3, lambda(p^a) = p^(a-1)(p-1) for odd p. Returns 0 for n <= 0 and 0 (documented overflow) when the value exceeds Int range. Complexity: O(sqrt(n) * lcm).
- Postcondition:
(n <= 0) => (result == 0) - Postcondition:
(n == 1) => (result == 1) - Postcondition:
(n > 1 && result != 0) => (result >= 1 && result <= n)
fn prime_pi(n: Int) -> Int¶
pi(n): the number of primes <= n. Returns 0 for n < 2. Uses a simple sieve of Eratosthenes over [0, n]. Complexity: O(n log log n).
- Postcondition:
(n < 2) => (result == 0) - Postcondition:
(n >= 2) => (result >= 1 && result <= n - 1)
fn nth_prime(n: Int) -> Int¶
The n-th prime, 1-indexed (nth_prime(1) == 2). Returns 0 for n <= 0 and 0 (documented) when the search leaves the representable Int range. Complexity: O(n * sqrt(p_n)).
- Postcondition:
(n <= 0) => (result == 0) - Postcondition:
(n == 1) => (result == 2) - Postcondition:
(result != 0) => (result >= 2)
fn primorial(n: Int) -> Int¶
Product of the first n primes (p_n#). Returns 0 for n <= 0 and 0 (documented overflow) when the product exceeds Int range (n > 15). Complexity: O(n * sqrt(p_n)).
- Postcondition:
(n <= 0) => (result == 0) - Postcondition:
(n == 1) => (result == 2) - Postcondition:
(n >= 16) => (result == 0) - Postcondition:
result >= 0
fn is_composite(n: Int) -> Bool¶
True iff n is composite (n > 1 and not prime). Returns false for n <= 1. Complexity: O(log^3 n) via the Miller-Rabin primality test.
- Postcondition:
(n <= 1 || n == 2) => (result == false)
fn is_semiprime(n: Int) -> Bool¶
True iff n is a product of exactly two primes (with multiplicity), so squares of primes count. Returns false for n < 4. Complexity: O(sqrt(n)).
- Postcondition:
(n < 4) => (result == false)
fn is_power(n: Int) -> Bool¶
True iff n is a perfect power a^k for integers a and k >= 2. Returns false for n <= 1. Uses the prime-exponent gcd criterion: n is a perfect power iff the gcd of the exponents in its prime factorization exceeds 1. Complexity: O(sqrt(n)).
- Postcondition:
(n <= 1) => (result == false)
fn is_power_of(n: Int, base: Int) -> Bool¶
True iff n is a power of base: n == base^k for some integer k >= 1. Special cases: base 0 (only n == 0), base 1 (only n == 1), base -1 (n == 1 or n == -1). Returns false when the power series overflows Int before reaching n. Complexity: O(log_base |n|).
- Postcondition:
(base == 0 && n == 0) => (result == true) - Postcondition:
(base == 0 && n != 0) => (result == false) - Postcondition:
(base == 1 && n == 1) => (result == true) - Postcondition:
(base == 1 && n != 1) => (result == false) - Postcondition:
(base == -1 && (n == 1 || n == -1)) => (result == true)
fn radical(n: Int) -> Int¶
Radical of n: the product of the distinct prime factors of n. Returns n for n <= 1 (rad(1) = 1, rad(0) = 0) and 0 (documented overflow) when the product exceeds Int range. Negative n is handled by absolute value. Complexity: O(sqrt(n)).
- Postcondition:
(n <= 1) => (result == n) - Postcondition:
(n > 1 && result != 0) => (result >= 2 && result <= n)
fn smooth(n: Int, bound: Int) -> Bool¶
True iff every prime factor of n is <= bound. Returns true for n <= 1 (no prime factors) and false for bound <= 1. Negative n is handled by absolute value. Complexity: O(sqrt(n)).
- Postcondition:
(n <= 1) => (result == true) - Postcondition:
(n > 1 && bound <= 1) => (result == false)
fn rough(n: Int, bound: Int) -> Bool¶
True iff every prime factor of n is > bound. Returns true for n <= 1 (no prime factors). Negative n is handled by absolute value. Complexity: O(sqrt(n)).
- Postcondition:
(n <= 1) => (result == true)
fn legendre_symbol(a: Int, p: Int) -> Int¶
Legendre symbol (a/p) for odd prime p: 1 for a quadratic residue, -1 for a non-residue, 0 when p divides a. Uses Euler's criterion a^((p-1)/2) mod p. p == 2 is handled directly (1 for odd a, 0 for even a); p <= 1 returns 0 (documented, no modulus). Complexity: O(log p).
- Postcondition:
(p <= 1) => (result == 0) - Postcondition:
(result >= -1 && result <= 1)
fn jacobi_symbol(a: Int, n: Int) -> Int¶
Jacobi symbol (a/n) for odd positive n; generalizes the Legendre symbol to composite odd n. Returns 0 for even or non-positive n (documented; the Jacobi symbol is undefined there) and 0 when gcd(a, n) != 1. Uses the quadratic-reciprocity reduction over the binary expansion of a. Complexity: O(log^2 n) worst case.
- Postcondition:
(n <= 0) => (result == 0) - Postcondition:
(n > 0 && n % 2 == 0) => (result == 0) - Postcondition:
(result >= -1 && result <= 1)
fn kronecker_symbol(a: Int, n: Int) -> Int¶
Kronecker symbol (a/n), the full extension of the Jacobi symbol to all integer n. Returns 1 for n == 1, (a/-1) by the sign of a, and uses the 2-adic rules for even n. n == 0 gives 1 iff a == 1 or a == -1, else 0. Complexity: O(log^2 |n|).
- Postcondition:
(n == 0 && a != 1 && a != -1) => (result == 0) - Postcondition:
(n == 0 && (a == 1 || a == -1)) => (result == 1) - Postcondition:
(n == 1) => (result == 1) - Postcondition:
(result >= -1 && result <= 1)
fn divisor_sum(n: Int, k: Int) -> Int¶
Sum of the k-th powers of the positive divisors of n, sigma_k(n). Returns 0 for n <= 0 and 0 for k < 0 (documented). Computed from the prime factorization: sigma_k(n) = prod (p^(k(e+1)) - 1)/(p^k - 1); k == 0 is the divisor count. Returns 0 (documented overflow) when the value exceeds Int range. Complexity: O(sqrt(n) * log k).
- Postcondition:
(n <= 0) => (result == 0) - Postcondition:
(n == 1) => (result == 1) - Postcondition:
(n > 1 && k < 0) => (result == 0) - Postcondition:
result >= 0
fn divisor_count(n: Int) -> Int¶
Number of positive divisors of n. Returns 0 for n <= 0. Alias of divisor_sum(n, 0). Complexity: O(sqrt(n)).
- Postcondition:
(n <= 0) => (result == 0) - Postcondition:
(n == 1) => (result == 1) - Postcondition:
(n > 1) => (result >= 1)
fn proper_divisors(n: Int) -> Vec[Int]¶
All positive divisors of n excluding n itself (unsorted). Returns the empty list for n <= 1 (1 has no proper divisors). Complexity: O(sqrt(n)).
- Postcondition:
(n <= 1) => (result.len() == 0) - Postcondition:
(n > 1) => (result.len() >= 1)
numerical.xi¶
fn bisection(f: fn(Float64) -> Float64, a: Float64, b: Float64, tol: Float64) -> Float64¶
Root of f in [a, b] via bisection on a sign change. When f(a) and f(b) share a sign the interval is sampled (64 points) for a sub-bracket; if none is found NaN (0.0/0.0) is returned (documented). Convergence to interval width tol, at most 200 iterations. Complexity: O(log((b-a)/tol)).
fn newton(f: fn(Float64) -> Float64, fprime: fn(Float64) -> Float64, x0: Float64, tol: Float64) -> Float64¶
Root of f via Newton's method from x0: x <- x - f(x)/f'(x). Returns x0 when the derivative vanishes (documented), at most 200 iterations. Complexity: O(200 * cost(f + f')).
fn secant(f: fn(Float64) -> Float64, x0: Float64, x1: Float64, tol: Float64) -> Float64¶
Root of f via the secant method from x0, x1. Returns x1 when f(x1) == f(x0) (documented, division by zero guard), at most 200 iterations. Complexity: O(200 * cost(f)).
fn falsi(f: fn(Float64) -> Float64, a: Float64, b: Float64, tol: Float64) -> Float64¶
Root of f in [a, b] via regula falsi (false position) with the Illinois anti-stalling adjustment. Returns NaN when no sign change exists in [a, b] (documented), at most 200 iterations. Complexity: O(200 * cost(f)).
- Postcondition:
(f(a) * f(b) > 0) => (result != result)
fn brent(f: fn(Float64) -> Float64, a: Float64, b: Float64, tol: Float64) -> Float64¶
Root of f in [a, b] via Brent's method (inverse quadratic interpolation with bisection fallback). The most robust of the bracketing methods; returns NaN when no sign change exists in [a, b] (documented). At most 200 iterations. Complexity: O(200 * cost(f)).
- Postcondition:
(f(a) * f(b) > 0) => (result != result)
fn fixed_point(g: fn(Float64) -> Float64, x0: Float64, tol: Float64) -> Float64¶
Fixed point of g by iteration x <- g(x) from x0. Convergence when |g(x) - x| < tol; at most 1000 iterations. Complexity: O(1000 * cost(g)).
fn steffensen(f: fn(Float64) -> Float64, x0: Float64, tol: Float64) -> Float64¶
Root of f via Steffensen's accelerated iteration, which achieves quadratic convergence without derivatives: x <- x - f(x)^2 / (f(x + f(x)) - f(x)). Returns x when the denominator vanishes (documented), at most 200 iterations. Complexity: O(200 * cost(f)).
fn newton_multi(fs: &Vec[fn(&Vec[Float64]) -> Float64], jac: fn(&Vec[Float64]) -> Vec[Vec[Float64]], x0: &Vec[Float64], tol: Float64) -> Vec[Float64]¶
Root of the nonlinear system fs(x) = 0 via Newton's method with the Jacobian supplied by jac. Solves J * d = -f by Gaussian elimination each iteration; converges to norm(d) < tol (at most 100 iterations). Returns the last iterate. Complexity: O(iters * n^3).
- Postcondition:
result.len() == x0.len()
fn newton_raphson_multi(fs: &Vec[fn(&Vec[Float64]) -> Float64], jac: fn(&Vec[Float64]) -> Vec[Vec[Float64]], x0: &Vec[Float64], tol: Float64) -> Vec[Float64]¶
Multi-variable Newton-Raphson root of the system fs(x) = 0. Alias of newton_multi. Complexity: O(iters * n^3).
- Postcondition:
result.len() == x0.len()
fn gauss_seidel(a: &Vec[Vec[Float64]], b: &Vec[Float64], x0: &Vec[Float64], tol: Float64) -> Vec[Float64]¶
Solve Ax = b by Gauss-Seidel iteration from x0. Requires a non-zero diagonal; returns the last iterate (at most 1000 iterations, convergence on the sup-norm of the increment). The empty vector is returned for empty input. Complexity: O(iters * n^2).
- Postcondition:
result.len() == x0.len()
fn jacobi_iterative(a: &Vec[Vec[Float64]], b: &Vec[Float64], x0: &Vec[Float64], tol: Float64) -> Vec[Float64]¶
Solve Ax = b by Jacobi iteration from x0 (updates use the previous iterate). Requires a non-zero diagonal; returns the last iterate. Complexity: O(iters * n^2).
- Postcondition:
result.len() == x0.len()
fn conjugate_gradient(a: &Vec[Vec[Float64]], b: &Vec[Float64], x0: &Vec[Float64], tol: Float64) -> Vec[Float64]¶
Solve SPD Ax = b by the conjugate gradient method from x0. Requires a symmetric positive-definite system; returns the last iterate (at most n + 200 iterations). Complexity: O(iters * n^2).
- Postcondition:
result.len() == x0.len()
fn gradient_descent(f: fn(&Vec[Float64]) -> Float64, grad: fn(&Vec[Float64]) -> Vec[Float64], x0: &Vec[Float64], lr: Float64, tol: Float64) -> Vec[Float64]¶
Minimize f(x) by gradient descent with learning rate lr from x0. Returns the last iterate (at most 10000 steps, stop when |lr * grad| < tol). Complexity: O(steps * cost(grad)).
- Postcondition:
result.len() == x0.len()
fn broyden(fs: &Vec[fn(&Vec[Float64]) -> Float64], x0: &Vec[Float64], tol: Float64) -> Vec[Float64]¶
Solve the nonlinear system fs(x) = 0 by Broyden's quasi-Newton method (secant update of the inverse-Jacobian estimate, no derivatives needed). Returns the last iterate (at most 100 iterations). Complexity: O(iters * n^2).
- Postcondition:
result.len() == x0.len()
fn anderson(fs: &Vec[fn(&Vec[Float64]) -> Float64], x0: &Vec[Float64], m: Int, tol: Float64) -> Vec[Float64]¶
Anderson-accelerated fixed-point iteration for the system fs(x) = 0 (fixed-point map x - fs(x)), keeping a history of the last m residuals. Returns the last iterate (at most 1000 outer iterations). Complexity: O(iters * m * n).
- Postcondition:
result.len() == x0.len()
fn solver_system(fs: &Vec[fn(&Vec[Float64]) -> Float64], x0: &Vec[Float64], tol: Float64) -> Vec[Float64]¶
General nonlinear system solver from x0. Broyden requires no Jacobian, so it is the natural default; delegates to broyden. Complexity: O(iters*n^2).
- Postcondition:
result.len() == x0.len()
fn interp_linear(xs: &Vec[Float64], ys: &Vec[Float64], x: Float64) -> Float64¶
Piecewise linear interpolation of the points (xs, ys) at x. x outside [xs[0], xs[n-1]] is clamped to the nearest endpoint (documented). Returns NaN for empty or mismatched input. Complexity: O(n).
- Postcondition:
(xs.len() != 0 && ys.len() == xs.len()) || (result != result)
fn interp_polynomial(xs: &Vec[Float64], ys: &Vec[Float64], x: Float64) -> Float64¶
Polynomial interpolation through the points (xs, ys) evaluated at x (Lagrange form). Returns NaN for empty, mismatched, or repeated-x input (division by zero guard). Complexity: O(n^2).
- Postcondition:
(xs.len() != 0 && ys.len() == xs.len()) || (result != result)
fn interp_spline(xs: &Vec[Float64], ys: &Vec[Float64], x: Float64) -> Float64¶
Default spline interpolation at x: a natural cubic spline through the points (xs, ys). Same semantics as interp_cubic. Returns NaN for empty, mismatched, or fewer-than-2-points input. Complexity: O(n) per call after an O(n) setup.
- Postcondition:
(xs.len() >= 2 && ys.len() == xs.len()) || (result != result)
fn interp_cubic(xs: &Vec[Float64], ys: &Vec[Float64], x: Float64) -> Float64¶
Natural cubic spline interpolation at x through the points (xs, ys) (zero second derivatives at the ends). Returns NaN for empty, mismatched, or fewer-than-2-points input. Complexity: O(n) setup + O(n) evaluation.
- Postcondition:
(xs.len() >= 2 && ys.len() == xs.len()) || (result != result)
fn interp_hermite(xs: &Vec[Float64], ys: &Vec[Float64], dys: &Vec[Float64], x: Float64) -> Float64¶
Hermite cubic interpolation at x using derivative values dys. Returns NaN for empty, mismatched input, or fewer than 2 points. x outside the data range is clamped to the nearest endpoint (documented). Complexity: O(n).
- Postcondition:
(xs.len() >= 2 && ys.len() == xs.len() && dys.len() == xs.len()) || (result != result)
fn spline_linear(xs: &Vec[Float64], ys: &Vec[Float64]) -> Vec[Float64]¶
Build linear spline coefficients: for n points the returned vector holds 2 * (n - 1) values, one (slope, intercept) pair per segment (documented layout). Returns the empty vector for fewer than 2 points or mismatched input. Complexity: O(n).
- Postcondition:
(result.len() == 0) || (result.len() == 2 * (xs.len() - 1))
fn spline_cubic(xs: &Vec[Float64], ys: &Vec[Float64]) -> Vec[Float64]¶
Build natural cubic spline coefficients: for n points the returned vector holds 4 * (n - 1) values, one (a, b, c, d) tuple per segment with p(x) = a + b(x - x_i) + c(x - x_i)^2 + d*(x - x_i)^3 (documented layout). Returns the empty vector for fewer than 2 points or mismatched input. Complexity: O(n).
- Postcondition:
(result.len() == 0) || (result.len() == 4 * (xs.len() - 1))
fn spline_b_spline(xs: &Vec[Float64], ys: &Vec[Float64], degree: Int) -> Vec[Float64]¶
Build B-spline control points of degree degree interpolating the data points ys (uniform knots). For degree 3 the interior control points come from the standard tridiagonal system c_(i-1) + 4 c_i + c_(i+1) = 6 y_i; for degree 1 the data points are returned as control points; other degrees fall back to the degree-3 fit (documented). Returns the empty vector for fewer than 2 points. Complexity: O(n) Thomas solve.
- Postcondition:
(result.len() == 0) || (result.len() == ys.len())
fn spline_nurbs(xs: &Vec[Float64], ys: &Vec[Float64], weights: &Vec[Float64], degree: Int) -> Vec[Float64]¶
Build NURBS control points from ys with the per-point weights: returns the homogeneous (weighted) control points w_i * y_i, one per data point (documented layout; an evaluator divides through by the weights). Returns the empty vector when weights do not match ys or the data is empty. Complexity: O(n).
- Postcondition:
(result.len() == 0) || (result.len() == ys.len())
fn quadrature_trapezoid(f: fn(Float64) -> Float64, a: Float64, b: Float64, n: Int) -> Float64¶
Composite trapezoidal rule for the integral of f over [a, b] with n subintervals. Returns 0.0 for n <= 0 (documented). Complexity: O(n).
- Postcondition:
(n > 0) || (result == 0)
fn quadrature_simpson(f: fn(Float64) -> Float64, a: Float64, b: Float64, n: Int) -> Float64¶
Composite Simpson's rule for the integral of f over [a, b] with n subintervals (n is clamped up to an even count; returns 0.0 for n <= 0). Complexity: O(n).
- Postcondition:
(n > 0) || (result == 0)
fn quadrature_gauss(f: fn(Float64) -> Float64, a: Float64, b: Float64, n: Int) -> Float64¶
n-point Gauss-Legendre quadrature over [a, b]. Nodes/weights are computed on the fly by Newton iteration on the Legendre polynomial (valid for any n >= 1); returns 0.0 for n <= 0 (documented). Exact for polynomials of degree <= 2n - 1. Complexity: O(n^2).
- Postcondition:
(n > 0) || (result == 0)
fn quadrature_adaptive(f: fn(Float64) -> Float64, a: Float64, b: Float64, tol: Float64) -> Float64¶
Adaptive quadrature to absolute tolerance tol via recursive Simpson refinement (a global error bookkeeping loop, at most 32 levels deep). Returns NaN for tol <= 0 (documented). Complexity: O(refinements * cost(f)).
- Postcondition:
(tol > 0) || (tol != tol) || (result != result)
fn quadrature_monte_carlo(f: fn(Float64) -> Float64, a: Float64, b: Float64, n: Int) -> Float64¶
Monte Carlo quadrature of f over [a, b] with n samples using the seeded xiom RNG (math.random). Returns 0.0 for n <= 0 (documented). Error ~ O(sigma / sqrt(n)). Complexity: O(n).
- Postcondition:
(n > 0) || (result == 0)
fn optimize_golden(f: fn(Float64) -> Float64, a: Float64, b: Float64, tol: Float64) -> Float64¶
Minimize the univariate f over [a, b] by golden-section search to width tol. Returns the minimizing x (at most 200 iterations). Complexity: O(200 * cost(f)).
- Postcondition:
(a > b) || ((result >= a) && (result <= b)) || (result != result)
fn optimize_ternary(f: fn(Float64) -> Float64, a: Float64, b: Float64, tol: Float64) -> Float64¶
Minimize the univariate f over [a, b] by ternary search to width tol. Returns the minimizing x (at most 200 iterations). Complexity: O(200 * cost(f)).
- Postcondition:
(a > b) || ((result >= a) && (result <= b)) || (result != result)
fn optimize_bfgs(f: fn(&Vec[Float64]) -> Float64, grad: fn(&Vec[Float64]) -> Vec[Float64], x0: &Vec[Float64], tol: Float64) -> Vec[Float64]¶
Minimize f by the BFGS quasi-Newton method from x0 (approximate inverse Hessian updated by the secant formula; line search = fixed step 1). Returns the last iterate (at most 200 iterations). Complexity: O(iters * n^2).
- Postcondition:
result.len() == x0.len()
fn optimize_lbfgs(f: fn(&Vec[Float64]) -> Float64, grad: fn(&Vec[Float64]) -> Vec[Float64], x0: &Vec[Float64], m: Int, tol: Float64) -> Vec[Float64]¶
Minimize f by limited-memory BFGS from x0 keeping the last m update pairs. Falls back to steepest descent when the history is empty. Returns the last iterate (at most 200 iterations). Complexity: O(iters * m * n).
- Postcondition:
result.len() == x0.len()
fn optimize_simplex(f: fn(&Vec[Float64]) -> Float64, x0: &Vec[Float64], tol: Float64) -> Vec[Float64]¶
Minimize f by the Nelder-Mead downhill simplex method from x0. Returns the best vertex (at most 500 iterations). Complexity: O(iters * n).
- Postcondition:
result.len() == x0.len()
fn optimize_powell(f: fn(&Vec[Float64]) -> Float64, x0: &Vec[Float64], tol: Float64) -> Vec[Float64]¶
Minimize f by Powell's conjugate direction method from x0 (cyclic one-dimensional golden-section line searches along a direction set). Returns the best point (at most 100 outer iterations). Complexity: O(iters * n * golden).
- Postcondition:
result.len() == x0.len()
fn optimize_cg(f: fn(&Vec[Float64]) -> Float64, grad: fn(&Vec[Float64]) -> Vec[Float64], x0: &Vec[Float64], tol: Float64) -> Vec[Float64]¶
Minimize f by nonlinear conjugate gradient (Polak-Ribiere) from x0 with an exact-ish line search. Returns the last iterate (at most 500 iterations). Complexity: O(iters * cost(grad)).
- Postcondition:
result.len() == x0.len()
fn optimize_gradient(f: fn(&Vec[Float64]) -> Float64, grad: fn(&Vec[Float64]) -> Vec[Float64], x0: &Vec[Float64], lr: Float64, tol: Float64) -> Vec[Float64]¶
Minimize f by gradient descent with learning rate lr from x0. Alias of gradient_descent. Complexity: O(steps * cost(grad)).
- Postcondition:
result.len() == x0.len()
fn optimize_newton(f: fn(&Vec[Float64]) -> Float64, grad: fn(&Vec[Float64]) -> Vec[Float64], hess: fn(&Vec[Float64]) -> Vec[Vec[Float64]], x0: &Vec[Float64], tol: Float64) -> Vec[Float64]¶
Minimize f by Newton's method with the Hessian from x0: solve H d = -g and step. Returns the last iterate (at most 100 iterations). Complexity: O(iters * n^3).
- Postcondition:
result.len() == x0.len()
fn optimize_least_squares(residuals: fn(&Vec[Float64]) -> Vec[Float64], x0: &Vec[Float64], tol: Float64) -> Vec[Float64]¶
Minimize the sum of squared residuals by Gauss-Newton from x0 (requires the residual Jacobian; a one-sided finite-difference Jacobian is used when not available through the residual function alone). Returns the last iterate (at most 100 iterations). Complexity: O(iters * n^3).
- Postcondition:
result.len() == x0.len()
fn bisection_root(f: fn(Float64) -> Float64, a: Float64, b: Float64, tol: Float64) -> Float64¶
Bracketing root finder via bisection. Alias of bisection. Complexity: O(log((b-a)/tol)).
fn newton_root(f: fn(Float64) -> Float64, fprime: fn(Float64) -> Float64, x0: Float64, tol: Float64) -> Float64¶
Derivative-based Newton root finder. Alias of newton. Complexity: O(200 * cost(f + f')).
fn solver_single(f: fn(Float64) -> Float64, a: Float64, b: Float64, tol: Float64) -> Float64¶
General single-equation root solver over [a, b]. Uses Brent's method (robust bracketing with quadratic convergence). Alias of brent.
- Postcondition:
(f(a) * f(b) > 0) => (result != result)
operations_research.xi¶
fn dynamic_programming(states: &Vec[Int], actions: fn(Int) -> Vec[Int], reward: fn(Int, Int) -> Float64) -> Vec[Float64]¶
Optimal value of each state by discounted value iteration: V[s] = max over next states ns in actions(s) of (reward(s, ns) + gamma V[ns]) with gamma = 0.99, converged when the largest update is below 1e-6 (at most 200 passes). Empty for an empty state set. Complexity: O(iters * A).
- Postcondition:
(result.len() == 0) || (result.len() == states.len())
fn inventory(demand: &Vec[Float64], holding_cost: Float64, order_cost: Float64) -> Vec[Float64]¶
Optimal order quantities over time by an (s, S)-style periodic-review heuristic: target S = 1.5 * mean demand, reorder point s = mean demand; orders top inventory back up to S. Returns one order quantity per period. Empty for an empty demand series. Complexity: O(n).
- Postcondition:
(result.len() == 0) || (result.len() == demand.len())
fn scheduling(jobs: &Vec[(Int, Int, Int)], machines: Int) -> Vec[Int]¶
Job-to-machine assignment minimizing the makespan by list scheduling: jobs (id, duration, priority) are placed on the least-loaded machine in priority order. Returns a Vec[Int] with one machine index per job (in the input order). Empty for no jobs or machines <= 0. Complexity: O(jobs * machines).
- Postcondition:
(machines > 0) || (result.len() == 0) - Postcondition:
(machines <= 0) || (result.len() == jobs.len())
fn routing(distances: &Vec[Vec[Float64]], vehicles: Int) -> Vec[Vec[Int]]¶
Vehicle routes minimizing total travel distance. TODO(compiler): NOT IMPLEMENTABLE in this compiler build - the distance matrix is a Vec[Vec[Float64]] whose element reads return garbage (BUG 23 #1 residual; verified by minimal probe). Keep the frozen signature; revisit when nested float Vec reads land.
fn assignment(cost: &Vec[Vec[Float64]]) -> Vec[Int]¶
Minimum-cost one-to-one assignment via the Hungarian method. TODO(compiler): NOT IMPLEMENTABLE - the cost matrix is a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn transportation(supply: &Vec[Float64], demand: &Vec[Float64], cost: &Vec[Vec[Float64]]) -> Vec[Vec[Float64]]¶
Minimum-cost shipment plan. TODO(compiler): NOT IMPLEMENTABLE - the cost matrix is a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn transshipment(supply: &Vec[Float64], demand: &Vec[Float64], transship: &Vec[Float64], cost: &Vec[Vec[Float64]]) -> Vec[Vec[Float64]]¶
Shipment plan through intermediate nodes. TODO(compiler): NOT IMPLEMENTABLE - the cost matrix is a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn network_flow(nodes: &Vec[Int], edges: &Vec[(Int, Int, Float64)]) -> (Float64, Vec[Vec[Float64]])¶
Max flow and flow matrix over the given edge list (u, v, capacity) with source = nodes[0] and sink = the last node. Returns (max_flow, flow matrix over the edges, one row per edge: [u, v, flow]). Edmonds-Karp BFS augmenting paths. Complexity: O(V * E^2).
- Postcondition:
result._0 >= 0 - Postcondition:
(nodes.len() < 2 || edges.len() == 0) => (result._1.len() == 0) - Postcondition:
(nodes.len() >= 2 && edges.len() > 0) => (result._1.len() == edges.len())
fn facility_location(demand: &Vec[Float64], candidates: &Vec[(Float64, Float64)], k: Int) -> Vec[Int]¶
k facility sites minimizing the total weighted distance by the greedy k-median heuristic: pick the candidate that reduces the objective most. Returns the indices of the chosen candidates. Empty for degenerate input. Complexity: O(k^2 * demand * candidates).
- Postcondition:
(k <= 0 || candidates.len() == 0 || demand.len() == 0) => (result.len() == 0) - Postcondition:
(k > 0 && candidates.len() > 0 && demand.len() > 0) => (result.len() <= candidates.len())
fn supply_chain(demands: &Vec[Vec[Float64]], costs: &Vec[Vec[Float64]]) -> Vec[Vec[Float64]]¶
Multi-period production and inventory plan. TODO(compiler): NOT IMPLEMENTABLE - the demand/cost matrices are Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn revenue_management(seats: Int, fare_classes: &Vec[(Float64, Float64)]) -> Vec[Float64]¶
Optimal protection levels for fare classes by Littlewood's rule: classes are (price, mean_demand); for two classes the high-class protection level is min(seats, mean_demand_high * (1 - price_low / price_high)). The result holds one protection level per class. Complexity: O(classes).
- Postcondition:
(fare_classes.len() == 0) => (result.len() == 0) - Postcondition:
(fare_classes.len() > 0) => (result.len() == fare_classes.len())
fn stochastic_optimization(objective: fn(&Vec[Float64]) -> Float64, bounds: &Vec[(Float64, Float64)], iters: Int) -> Vec[Float64]¶
Stochastic search optimum within bounds by uniform random sampling: the objective is minimized over the box [bounds[i].0, bounds[i].1]^dims with
iterssamples; returns the best point. Empty for degenerate input. Complexity: O(iters * dims * cost(objective)).
- Postcondition:
(bounds.len() == 0 || iters <= 0) => (result.len() == 0) - Postcondition:
(bounds.len() > 0 && iters > 0) => (result.len() == bounds.len())
optimization.xi¶
fn linear_programming(c: &Vec[Float64], a: &Vec[Vec[Float64]], b: &Vec[Float64], bounds: &Vec[Vec[Float64]]) -> Vec[Float64]¶
Minimize c'x subject to Ax <= b and per-variable bounds. Empty bounds means every variable is >= 0 (a direct lp_simplex delegation); otherwise bounds carries one entry per variable, each holding [lo, hi] with the infinities standing in for absent sides (an empty entry means [0, +inf) and a single entry means [lo, +inf)). Lower-only variables shift (x = lo + z), upper-only ones reflect (x = hi - z), doubly-bounded ones scale into [0, 1] with an added z <= 1 row, and free variables split as z+ - z-. The transformed program is solved by lp_simplex on repaired locals and the solution is mapped back. Returns the empty vector for empty c or A, b.len() != a.len(), ragged A, a bounds length other than 0 or c.len(), a bounds row with more than two entries, a NaN bound, infeasible bounds (lo > hi, lo == +inf, hi == -inf), a zero-length simplex result (which includes the documented limitation that a shifted b2 with a negative entry has no Phase I), and every lp_simplex guard; otherwise the argmin x of length c.len(). Complexity: O(iterations * (m + q) * (n + q)) with q the number of doubly-bounded or free variables.
- Postcondition:
result.len() == 0 || result.len() == c.len()
fn integer_programming(c: &Vec[Float64], a: &Vec[Vec[Float64]], b: &Vec[Float64]) -> Vec[Int]¶
Solve a linear program with integer variables. TODO(compiler): NOT IMPLEMENTABLE - the constraint matrix A is a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn mixed_integer_programming(c: &Vec[Float64], a: &Vec[Vec[Float64]], b: &Vec[Float64], int_vars: &Vec[Bool]) -> Vec[Float64]¶
Solve a MILP with continuous and integer variables. TODO(compiler): NOT IMPLEMENTABLE - the constraint matrix A is a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn quadratic_programming(q: &Vec[Vec[Float64]], c: &Vec[Float64], a: &Vec[Vec[Float64]], b: &Vec[Float64]) -> Vec[Float64]¶
Minimize 1/2 x'Qx + c'x subject to Ax <= b. TODO(compiler): NOT IMPLEMENTABLE - the matrices are Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn nonlinear_programming(f: fn(&Vec[Float64]) -> Float64, cons: &Vec[fn(&Vec[Float64]) -> Float64], x0: &Vec[Float64]) -> Vec[Float64]¶
Minimize f subject to constraints cons from x0. TODO(compiler): NOT IMPLEMENTABLE - the constraint vector is a Vec[fn] whose element reads return garbage in this compiler build.
fn lp_simplex(c: &Vec[Float64], a: &Vec[Vec[Float64]], b: &Vec[Float64]) -> Vec[Float64]¶
Minimize c'x subject to Ax <= b, x >= 0, by the dense simplex method with Bland's rule (entering: smallest negative reduced cost; leaving: smallest basis index on ratio ties), Gauss-Jordan pivots and a 10000-iteration cap. Returns the empty vector for empty c or A, b.len() != a.len(), ragged A, any b[i] < 0 (no Phase I), unbounded programs, and cap exhaustion; otherwise the argmin x of length c.len(). Complexity: O(iterations * m * (n + m)).
- Postcondition:
result.len() == 0 || result.len() == c.len()
fn lp_interior_point(c: &Vec[Float64], a: &Vec[Vec[Float64]], b: &Vec[Float64]) -> Vec[Float64]¶
Solve a linear program by the interior-point method. TODO(compiler): NOT IMPLEMENTABLE - the constraint matrix A is a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn branch_and_bound(c: &Vec[Float64], a: &Vec[Vec[Float64]], b: &Vec[Float64]) -> Vec[Float64]¶
Solve an ILP by branch and bound. TODO(compiler): NOT IMPLEMENTABLE - the constraint matrix A is a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn cutting_plane(c: &Vec[Float64], a: &Vec[Vec[Float64]], b: &Vec[Float64]) -> Vec[Float64]¶
Solve an ILP by the cutting-plane method. TODO(compiler): NOT IMPLEMENTABLE - the constraint matrix A is a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn sequential_quadratic(f: fn(&Vec[Float64]) -> Float64, cons: &Vec[fn(&Vec[Float64]) -> Float64], x0: &Vec[Float64]) -> Vec[Float64]¶
Minimize constrained f by sequential quadratic programming. TODO(compiler): NOT IMPLEMENTABLE - the constraint vector is a Vec[fn] whose element reads return garbage in this compiler build.
fn penalty_method(f: fn(&Vec[Float64]) -> Float64, cons: &Vec[fn(&Vec[Float64]) -> Float64], x0: &Vec[Float64]) -> Vec[Float64]¶
Minimize constrained f via penalty functions. TODO(compiler): NOT IMPLEMENTABLE - the constraint vector is a Vec[fn] whose element reads return garbage in this compiler build.
fn barrier_method(f: fn(&Vec[Float64]) -> Float64, cons: &Vec[fn(&Vec[Float64]) -> Float64], x0: &Vec[Float64]) -> Vec[Float64]¶
Minimize inequality-constrained f via barrier functions. TODO(compiler): NOT IMPLEMENTABLE - the constraint vector is a Vec[fn] whose element reads return garbage in this compiler build.
fn augmented_lagrangian(f: fn(&Vec[Float64]) -> Float64, cons: &Vec[fn(&Vec[Float64]) -> Float64], x0: &Vec[Float64]) -> Vec[Float64]¶
Minimize constrained f via the augmented Lagrangian method. TODO(compiler): NOT IMPLEMENTABLE - the constraint vector is a Vec[fn] whose element reads return garbage in this compiler build.
fn genetic_algorithm(f: fn(&Vec[Float64]) -> Float64, bounds: &Vec[Vec[Float64]], pop_size: Int, generations: Int) -> Vec[Float64]¶
Minimize f by a genetic algorithm. TODO(compiler): NOT IMPLEMENTABLE - the search bounds are a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn simulated_annealing(f: fn(&Vec[Float64]) -> Float64, x0: &Vec[Float64], t0: Float64, schedule: fn(Float64, Float64) -> Float64) -> Vec[Float64]¶
Minimize f by simulated annealing from x0: at each temperature a neighboring point x + N(0, t) is sampled and accepted when it improves the objective or with probability exp(-(df)/t); the temperature follows schedule(t, i). Returns the best point found. Empty for an empty x0. Complexity: O(iters * n * cost(f)).
- Postcondition:
result.len() == x0.len()
fn particle_swarm(f: fn(&Vec[Float64]) -> Float64, bounds: &Vec[Vec[Float64]], particles: Int, iters: Int) -> Vec[Float64]¶
Minimize f by particle swarm optimization. TODO(compiler): NOT IMPLEMENTABLE - the search bounds are a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn ant_colony(cost: fn(&Vec[Int]) -> Float64, n_nodes: Int, iters: Int) -> Vec[Int]¶
Optimize a combinatorial problem by ant colony optimization: ants build candidate permutations of the n_nodes cities, biased toward the best tour found so far; the best tour (as a permutation of city ids) is returned. Empty for n_nodes <= 0. Complexity: O(iters * n_nodes^2 + iters * cost(cost)).
- Postcondition:
(n_nodes <= 0) || (result.len() == n_nodes)
fn differential_evolution(f: fn(&Vec[Float64]) -> Float64, bounds: &Vec[Vec[Float64]], pop_size: Int, iters: Int) -> Vec[Float64]¶
Minimize f by differential evolution. TODO(compiler): NOT IMPLEMENTABLE - the search bounds are a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn bayesian_optimization(f: fn(&Vec[Float64]) -> Float64, bounds: &Vec[Vec[Float64]], iters: Int) -> Vec[Float64]¶
Minimize f by Bayesian optimization with a surrogate model. TODO(compiler): NOT IMPLEMENTABLE - the search bounds are a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn grid_search(f: fn(&Vec[Float64]) -> Float64, bounds: &Vec[Vec[Float64]], n: Int) -> Vec[Float64]¶
Minimize f by exhaustive grid search with n points per axis. TODO(compiler): NOT IMPLEMENTABLE - the search bounds are a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
fn random_search(f: fn(&Vec[Float64]) -> Float64, bounds: &Vec[Vec[Float64]], iters: Int) -> Vec[Float64]¶
Minimize f by uniform random sampling. TODO(compiler): NOT IMPLEMENTABLE - the search bounds are a Vec[Vec[Float64]] whose element reads return garbage in this compiler build.
precision.xi¶
fn min_value[T]() -> T¶
Smallest finite value representable by T.
fn max_value[T]() -> T¶
Largest finite value representable by T.
fn epsilon[T]() -> T¶
Machine epsilon of T: smallest x such that 1 + x != 1.
fn digits[T]() -> Int¶
Number of significant decimal digits (floats) or decimal digits (integers).
- Postcondition:
result > 0
fn mantissa_digits[T]() -> Int¶
Number of bits in the significand of T (magnitude bits for integers).
- Postcondition:
result > 0
fn exponent_bias[T]() -> Int¶
Exponent bias of T (floats); 0 for integers.
- Postcondition:
result >= 0
fn min_exponent[T]() -> Int¶
Minimum binary exponent of T (floats); 0 for integers.
- Postcondition:
result <= 0
fn max_exponent[T]() -> Int¶
Maximum binary exponent of T (floats); 0 for integers.
- Postcondition:
result >= 0
fn is_signed[T]() -> Bool¶
True iff T can represent negative values.
fn bit_width[T]() -> Int¶
Number of bits in a value of T.
- Postcondition:
result > 0
fn byte_width[T]() -> Int¶
Number of bytes in a value of T.
- Postcondition:
result > 0
primitives.xi¶
fn min(a: Float64, b: Float64) -> Float64¶
Smaller of a and b. IEEE min semantics: NaN propagates only when both operands are NaN (plain comparison; callers pass validated values).
- Postcondition:
(result <= a && result <= b) || (a != a) || (b != b)
fn max(a: Float64, b: Float64) -> Float64¶
Larger of a and b.
- Postcondition:
(result >= a && result >= b) || (a != a) || (b != b)
fn clamp(x: Float64, lo: Float64, hi: Float64) -> Float64¶
x clamped into [lo, hi]. When x < lo returns lo, when x > hi returns hi. requires: lo <= hi
- Precondition:
lo <= hi - Postcondition:
(result >= lo && result <= hi) || (result != result)
fn abs(x: Float64) -> Float64¶
Absolute value of x. Handles -inf correctly (returns +inf); NaN propagates.
- Postcondition:
(result >= 0) || (result != result)
fn signum(x: Float64) -> Int¶
-1, 0, or 1 matching the sign of x. -0.0 == 0.0 yields 0.
- Postcondition:
(result == -1 && x < 0) || (result == 1 && x > 0) || (result == 0 && !(x < 0) && !(x > 0))
fn lerp(a: Float64, b: Float64, t: Float64) -> Float64¶
Linear interpolation: a + (b - a) * t. t outside [0,1] extrapolates.
- Postcondition:
(t != 0) || (result == a)
fn step(edge: Float64, x: Float64) -> Float64¶
0.0 if x < edge, else 1.0. A hard threshold step.
- Postcondition:
(result == 0 && x < edge) || (result == 1 && !(x < edge))
fn smoothstep(e0: Float64, e1: Float64, x: Float64) -> Float64¶
Hermite interpolation between 0 and 1 over [e0, e1]. Degenerate e0 == e1 behaves as a step at e0 (0.0 below, 1.0 at/above). Complexity: O(1).
- Postcondition:
((result >= 0) && (result <= 1)) || (result != result)
fn fract(x: Float64) -> Float64¶
Fractional part of x with the sign of x. fract(2.5) == 0.5, fract(-2.5) == -0.5. For |x| >= 2^53 (x integral) returns 0.0.
- Postcondition:
((result > -1) && (result < 1)) || (result != result)
fn modf(x: Float64) -> (Int, Float64)¶
Split x into (integral_part, fractional_part); the integral part is truncated toward zero. modf(2.5) == (2, 0.5), modf(-2.5) == (-2, -0.5). For |x| >= 2^63 the integral part saturates to INT_MAX/INT_MIN and the fractional part is 0.0.
- Postcondition:
((result._1 > -1) && (result._1 < 1)) || (result._1 != result._1)
fn copysign(x: Float64, y: Float64) -> Float64¶
Magnitude of x with the sign of y. Handles -0.0: copysign(1.0, -0.0) == -1.0.
- Postcondition:
(result == x) || (result == -x) || (result != result)
fn nextafter(x: Float64, y: Float64) -> Float64¶
Next representable Float64 strictly between x and y, walking from x toward y. Exact for normal and subnormal inputs (powers of two are exact); the walk uses ulp(x) = 2^(floor(log2|x|)-52) for normals and 2^-1074 for subnormals, so stepping across a power-of-two boundary is exact. nextafter(x, x) == x; nextafter(max, +inf) == +inf. TODO(compiler): an exact implementation normally uses a float<->int bitcast; this arithmetic form is exact for all finite normal/subnormal values (verified by round-trip tests) and avoids NaN-producing ops.
- Postcondition:
(x != y) || (result == x)
fn fma(a: Float64, b: Float64, c: Float64) -> Float64¶
Fused multiply-add: a * b + c with a single rounding. Computed exactly via Veltkamp splitting + 2Sum (p + e == ab, s + s2 == p + c). The final rounding is s + (s2 + e), which matches the hardware-fused result for all non-pathological inputs (error <= 1 ulp otherwise; no double rounding). Complexity: O(1). Overflow of ab propagates to inf, as IEEE requires.
- Postcondition:
((a == 0) && (b == 0) && (c == c) && (c != 1 / 0) && (c != -1 / 0)) => (result == c) - Postcondition:
((a == 0) && (b == 0) && (c != c)) => (result != result)
fn frexp(x: Float64) -> (Float64, Int)¶
Split x into (mantissa, exponent) with x == mantissa * 2^exponent and mantissa in [0.5, 1). frexp(8.0) == (0.5, 4), frexp(0.0) == (0.0, 0). Sign is preserved. Exact. Complexity: O(1074) worst case.
- Postcondition:
((x == 0) && (result._0 == 0)) || ((result._0 >= 0.5) && (result._0 < 1)) || ((result._0 <= -0.5) && (result._0 > -1)) || (result._0 == 1 / 0) || (result._0 == -1 / 0) || (result._0 != result._0)
fn ldexp(x: Float64, exp: Int) -> Float64¶
x * 2^exp. Exact (single rounding at the end). For exp > 1100 the result overflows to +-inf; for exp < -1100 it flushes to 0.0 (documented; the representable exponent range is [-1074, 1023]).
- Postcondition:
((x > 0) => (result >= 0)) && ((x < 0) => (result <= 0)) - Postcondition:
(x != 0) || (result == 0)
fn hypot(a: Float64, b: Float64) -> Float64¶
sqrt(aa + bb) without intermediate overflow or underflow. Uses the scaled form m * sqrt(1 + (n/m)^2) where m = max(|a|, |b|). hypot(0.0, 0.0) == 0.0. Complexity: O(1). Requires pure-Newton sqrt.
- Postcondition:
(result >= 0) || (result != result)
fn cbrt(x: Float64) -> Float64¶
Cube root of x, any sign. Newton iteration with an exponent-scaled initial guess, 20 iterations. Complexity: O(1074 + 20).
- Postcondition:
((x > 0) => (result > 0)) && ((x < 0) => (result < 0)) && ((x == 0) => (result == 0))
fn is_nan(x: Float64) -> Bool¶
True iff x is NaN (IEEE: x != x).
- Postcondition:
result == (x != x)
fn is_inf(x: Float64) -> Bool¶
True iff x is positive or negative infinity.
- Postcondition:
result == (x == 1 / 0 || x == -1 / 0)
fn is_finite(x: Float64) -> Bool¶
True iff x is neither NaN nor infinite.
- Postcondition:
result == (x == x && x != 1 / 0 && x != -1 / 0)
queueing.xi¶
fn m_m_1(arrival_rate: Float64, service_rate: Float64) -> (Float64, Float64)¶
M/M/1 mean queue length L and mean waiting time W = L/lambda. The tuple is (L, W). Unstable (rho >= 1) returns (+inf, +inf). Complexity: O(1).
- Postcondition:
((((arrival_rate <= 0) || (service_rate <= 0)) => ((result._0 != result._0) && (result._1 != result._1))) && (((arrival_rate > 0) && (service_rate > 0) && ((arrival_rate / service_rate) >= 1)) => ((result._0 == 1 / 0) && (result._1 == 1 / 0)))) && (((arrival_rate > 0) && (service_rate > 0) && ((arrival_rate / service_rate) < 1)) => ((result._0 >= 0) && ((result._1 == result._0 / arrival_rate) || (result._1 != result._1))))
fn m_m_c(arrival_rate: Float64, service_rate: Float64, servers: Int) -> (Float64, Float64)¶
M/M/c mean queue length L_q and mean waiting time W_q via the Erlang-C formula. The tuple is (L_q, W_q). Unstable returns (+inf, +inf). Complexity: O(c).
- Postcondition:
((((arrival_rate <= 0) || (service_rate <= 0) || (servers <= 0)) => ((result._0 != result._0) && (result._1 != result._1))) && (((arrival_rate > 0) && (service_rate > 0) && (servers > 0) && ((arrival_rate / (service_rate * (?))) >= 1)) => ((result._0 == 1 / 0) && (result._1 == 1 / 0)))) && (((arrival_rate > 0) && (service_rate > 0) && (servers > 0) && ((arrival_rate / (service_rate * (?))) < 1)) => ((result._0 >= 0) && ((result._1 == result._0 / arrival_rate) || (result._1 != result._1))))
fn m_g_1(arrival_rate: Float64, mean_service: Float64, var_service: Float64) -> Float64¶
M/G/1 mean queue length via the Pollaczek-Khinchine formula L_q = lambda^2 (var + mean^2) / (2 (1 - rho)). Complexity: O(1).
- Postcondition:
((((arrival_rate <= 0) || (mean_service <= 0)) => (result != result)) && (((arrival_rate > 0) && (mean_service > 0) && ((arrival_rate * mean_service) >= 1)) => (result == 1 / 0))) && (((arrival_rate > 0) && (mean_service > 0) && ((arrival_rate * mean_service) < 1) && (var_service >= 0)) => (result >= 0))
fn g_g_1(mean_interarrival: Float64, var_interarrival: Float64, mean_service: Float64, var_service: Float64) -> Float64¶
G/G/1 approximate mean waiting time via Kingman's heavy-traffic bound W_q ~ (rho/(1 - rho)) * (c_a^2 + c_s^2)/2 * mean_service. Complexity: O(1).
- Postcondition:
((((mean_interarrival <= 0) || (mean_service <= 0)) => (result != result)) && (((mean_interarrival > 0) && (mean_service > 0) && ((mean_service / mean_interarrival) >= 1)) => (result == 1 / 0))) && (((mean_interarrival > 0) && (mean_service > 0) && ((mean_service / mean_interarrival) < 1) && (var_interarrival >= 0) && (var_service >= 0)) => (result >= 0))
fn erlang_b(offered_load: Float64, servers: Int) -> Float64¶
Erlang B blocking probability B(c, A) for the M/M/c/c loss system, by the iterative recurrence. Complexity: O(c).
- Postcondition:
(((offered_load >= 0) && (servers >= 0)) => (((result >= 0) && (result <= 1)) || (result != result))) && ((servers == 0) => (result == 1))
fn erlang_c(offered_load: Float64, servers: Int) -> Float64¶
Erlang C delay probability C(c, A) for M/M/c, from the Erlang B value. Complexity: O(c).
- Postcondition:
(((offered_load >= 0) && (servers > 0)) => (((result >= 0) && (result <= 1)) || (result != result))) && (((offered_load >= 0) && (servers > 0) && ((offered_load / (?)) >= 1)) => (result == 1))
fn little_law(lambda: Float64, w: Float64) -> Float64¶
Little's law: number of customers in the system L = lambda * W. Complexity: O(1).
- Postcondition:
(result == lambda * w) || (result != result)
fn utilization(arrival_rate: Float64, service_rate: Float64, servers: Int) -> Float64¶
Server utilization rho = lambda / (mu * c). Complexity: O(1).
- Postcondition:
(((service_rate <= 0) || (servers <= 0)) => (result != result)) && (((service_rate > 0) && (servers > 0)) => ((result == arrival_rate / (service_rate * (?))) || (result != result)))
fn queue_length(arrival_rate: Float64, service_rate: Float64, servers: Int) -> Float64¶
Expected number of customers waiting in the M/M/c queue. Unstable returns +inf. Complexity: O(c).
- Postcondition:
(((arrival_rate <= 0) || (service_rate <= 0) || (servers <= 0)) => (result != result)) && (((arrival_rate > 0) && (service_rate > 0) && (servers > 0) && ((arrival_rate / (service_rate * (?))) >= 1)) => (result == 1 / 0))
fn waiting_time(arrival_rate: Float64, service_rate: Float64, servers: Int) -> Float64¶
Expected waiting time in the M/M/c queue. Unstable returns +inf. Complexity: O(c).
- Postcondition:
(((arrival_rate <= 0) || (service_rate <= 0) || (servers <= 0)) => (result != result)) && (((arrival_rate > 0) && (service_rate > 0) && (servers > 0) && ((arrival_rate / (service_rate * (?))) >= 1)) => (result == 1 / 0))
fn loss_probability(arrival_rate: Float64, service_rate: Float64, capacity: Int) -> Float64¶
Probability that an arrival finds the system full (M/M/c/c loss): the Erlang B blocking probability. Complexity: O(c).
- Postcondition:
(((service_rate <= 0) => (result != result)) && (((arrival_rate < 0) && (service_rate > 0)) => (result != result))) && (((arrival_rate >= 0) && (service_rate > 0) && (capacity >= 0)) => (((result >= 0) && (result <= 1)) || (result != result)))
fn blocking_probability(arrival_rate: Float64, service_rate: Float64, capacity: Int) -> Float64¶
Probability that a call is blocked: the Erlang B blocking probability. Complexity: O(c).
- Postcondition:
(service_rate <= 0) => (result != result)
fn heavy_traffic(arrival_rate: Float64, service_rate: Float64, servers: Int) -> Float64¶
Kingman heavy-traffic approximation of the queue size for G/G/c: L_q ~ (rho^2/(1 - rho)) * (c_a^2 + c_s^2)/2 (unit-coefficient traffic). Complexity: O(1).
- Postcondition:
(arrival_rate <= 0 || service_rate <= 0 || servers <= 0) => (result != result) - Postcondition:
(arrival_rate > 0 && service_rate > 0 && servers > 0 && arrival_rate < service_rate * (?)) => (result >= 0) - Postcondition:
(arrival_rate > 0 && service_rate > 0 && servers > 0 && arrival_rate >= service_rate * (?)) => (result == 1 / 0)
fn diffusion_approx(arrival_rate: Float64, service_rate: Float64, time: Float64) -> Float64¶
Diffusion approximation of the M/M/1 queue length at time t: L(t) = max(0, (lambda - mu) t). Complexity: O(1).
- Postcondition:
(time < 0) => (result != result) - Postcondition:
(time >= 0 && arrival_rate <= service_rate) => (result == 0)
roots.xi¶
fn sqrt(x: Float64) -> Float64¶
Principal square root of x. Requires x >= 0. For x < 0 returns NaN (IEEE semantics; BUG 19 fixed 2026-08-11 -- NaN ops now work).
- Postcondition:
result >= 0 || result != result
fn cbrt(x: Float64) -> Float64¶
Cube root of x, any sign. Uses sign-split math.pow for speed. cbrt(27.0) == 3.0, cbrt(-27.0) == -3.0. Complexity: O(1), libm pow.
- Postcondition:
((x > 0) && (result > 0)) || ((x < 0) && (result < 0)) || ((x == 0) && (result == 0)) || (result != result)
fn nth_root(x: Float64, n: Int) -> Float64¶
n-th root of x. For even n, x must be >= 0 (x < 0 returns NaN). For odd n the sign is preserved. n == 0 returns 1.0 (documented: the 0-th root is not defined). Negative n gives x^(1/n) = 1/root. Complexity: O(1), libm pow.
- Postcondition:
result >= 0 || result != result || n % 2 != 0
fn sqrt_pure(x: Float64) -> Float64¶
sqrt via Newton iteration, no libm. Delegates to the proven pure Newton implementation math.sqrt_pure (same algorithm, 50 iterations). For x < 0 returns NaN (IEEE semantics). Complexity: O(50).
- Postcondition:
result >= 0 || result != result
fn cbrt_pure(x: Float64) -> Float64¶
cbrt via Newton iteration, no libm. 20 iterations with an exponent-scaled initial guess (floor(log2|x|)/3 via math.decompose.ilogb). Exact for all finite values, any sign. Complexity: O(ilogb + 20).
- Postcondition:
((x > 0) && (result > 0)) || ((x < 0) && (result < 0)) || ((x == 0) && (result == 0)) || (result != result)
fn is_square(n: Int) -> Bool¶
True iff n is a perfect square. is_square(0) == true, is_square(16) == true, is_square(-4) == false. Complexity: O(log sqrt(n)) via integer_sqrt.
- Postcondition:
(n < 0) => (result == false)
fn is_cube(n: Int) -> Bool¶
True iff n is a perfect cube. is_cube(0) == true, is_cube(27) == true, is_cube(-27) == false (negative inputs are rejected). Complexity: O(log).
- Postcondition:
(n < 0) => (result == false)
fn integer_sqrt(n: Int) -> Int¶
floor(sqrt(n)) for n >= 0 via integer Newton (no float, no overflow). integer_sqrt(16) == 4, integer_sqrt(17) == 4. For n < 0 returns -1 (documented). Complexity: O(log n) iterations.
- Postcondition:
(n >= 0) || (result == -1)
fn integer_cbrt(n: Int) -> Int¶
floor(cbrt(n)) for n >= 0 via integer Newton (no float, no overflow). integer_cbrt(27) == 3, integer_cbrt(28) == 3. For n < 0 returns -1 (documented). Complexity: O(log n) iterations.
- Postcondition:
(n >= 0) || (result == -1)
fn hypot(x: Float64, y: Float64) -> Float64¶
sqrt(x^2 + y^2) without intermediate overflow or underflow. Uses the scaled form m * sqrt(1 + (n/m)^2). hypot(3.0, 4.0) == 5.0. Complexity: O(1), libm sqrt.
- Postcondition:
result >= 0
fn hypot3(x: Float64, y: Float64, z: Float64) -> Float64¶
sqrt(x^2 + y^2 + z^2) without intermediate overflow. Generalizes hypot. hypot3(1.0, 2.0, 2.0) == 3.0. Complexity: O(1), libm sqrt.
- Postcondition:
result >= 0
fn norm2(x: Float64, y: Float64) -> Float64¶
Euclidean norm of a 2D vector (x, y). Alias of hypot. Complexity: O(1).
- Postcondition:
result >= 0
fn norm3(x: Float64, y: Float64, z: Float64) -> Float64¶
Euclidean norm of a 3D vector (x, y, z). Alias of hypot3. Complexity: O(1).
- Postcondition:
result >= 0
rounding.xi¶
fn floor(x: Float64) -> Float64¶
Largest integer <= x. For |x| >= 2^63 the result is x itself (such values are integers). Complexity: O(1), libm floor.
- Postcondition:
(result <= x) || (result != result)
fn ceil(x: Float64) -> Float64¶
Smallest integer >= x. For |x| >= 2^63 the result is x itself. Complexity: O(1), libm ceil.
- Postcondition:
(result >= x) || (result != result)
fn round(x: Float64) -> Float64¶
Nearest integer, ties away from zero. round(2.5) == 3.0, round(-2.5) == -3.0. For |x| >= 2^63 the result is x (already integral). Complexity: O(1).
- Postcondition:
(((x >= 0) && (result >= 0)) || ((x < 0) && (result <= 0))) || (x != x)
fn trunc(x: Float64) -> Float64¶
Integer part of x, truncated toward zero. trunc(2.7) == 2.0, trunc(-2.7) == -2.0. For |x| >= 2^63 the result is x. Complexity: O(1).
- Postcondition:
(((x >= 0) && (result >= 0)) || ((x < 0) && (result <= 0))) || (x != x)
fn fract(x: Float64) -> Float64¶
Fractional part of x: x - trunc(x), same sign as x. fract(2.5) == 0.5, fract(-2.5) == -0.5. Complexity: O(1).
- Postcondition:
(((x >= 0) && (result >= 0) && (result < 1)) || ((x < 0) && (result <= 0) && (result > -1))) || (result != result)
fn modf(x: Float64) -> (Float64, Float64)¶
Split x into (fract, int): fract is the fractional part, int is the integer part truncated toward zero. modf(2.5) == (0.5, 2.0). Complexity: O(1).
- Postcondition:
(x >= 0 && x < 1) => (result._0 == x && result._1 == 0) - Postcondition:
(x < 0 && x > -1) => (result._0 == x && result._1 == 0)
fn floor_pure(x: Float64) -> Float64¶
Largest integer <= x without libm. Pure-XIOM; see floor() for semantics. Complexity: O(1).
- Postcondition:
(x == x) => (result <= x)
fn ceil_pure(x: Float64) -> Float64¶
Smallest integer >= x without libm. Pure-XIOM; see ceil() for semantics. Complexity: O(1).
- Postcondition:
(x == x) => (result >= x)
fn round_pure(x: Float64) -> Float64¶
Nearest integer, ties away from zero, without libm. See round(). Complexity: O(1).
- Postcondition:
(((x >= 0) && (result >= 0)) || ((x < 0) && (result <= 0))) || (x != x)
fn trunc_pure(x: Float64) -> Float64¶
Integer part truncated toward zero, without libm. See trunc(). Complexity: O(1).
- Postcondition:
(((x >= 0) && (result >= 0) && (result <= x)) || ((x < 0) && (result <= 0) && (result >= x))) || (x != x)
fn fract_pure(x: Float64) -> Float64¶
Fractional part of x without libm. See fract(). Complexity: O(1).
- Postcondition:
(((x >= 0) && (result >= 0) && (result < 1)) || ((x < 0) && (result <= 0) && (result > -1))) || (result != result)
fn integer_part(x: Float64) -> Float64¶
Integer part of x (truncated toward zero), as a Float64. Alias of trunc. Complexity: O(1).
- Postcondition:
(((x >= 0) && (result >= 0)) || ((x < 0) && (result <= 0))) || (x != x)
fn frac_part(x: Float64) -> Float64¶
Fractional part of x. Alias of fract. Complexity: O(1).
- Postcondition:
(((x >= 0) && (result >= 0) && (result < 1)) || ((x < 0) && (result <= 0) && (result > -1))) || (result != result)
fn round_to(x: Float64, places: Int) -> Float64¶
Round x to
placesdecimal places, ties away from zero. Negative places round to multiples of 10^|places| (round_to(1234.5, -2) == 1200.0). Decimal rounding is subject to binary float representation error; the result is the correctly rounded Float64 of x scaled by 10^places. Complexity: O(1).
- Postcondition:
(places == 0) => (result == round(x) || x != x)
fn round_nearest(x: Float64) -> Int¶
Round to the nearest integer, ties to even, returned as Int. round_nearest(2.5) == 2, round_nearest(3.5) == 4, round_nearest(-2.5) == -2. For |x| >= 2^63 the result saturates to INT_MAX/INT_MIN (documented; the true rounded value is outside Int range). Complexity: O(1).
- Postcondition:
(((x >= 0) && (result >= 0)) || ((x <= 0) && (result <= 0))) || (x != x)
series.xi¶
fn series_sum(terms: fn(Int) -> Float64, n: Int) -> Float64¶
Sum of terms(0) + terms(1) + ... + terms(n-1). Returns 0.0 for n <= 0. Complexity: O(n).
- Postcondition:
(n > 0) || (result == 0)
fn power_series(coefficients: &Vec[Float64], x: Float64) -> Float64¶
Value of the power series sum c[i] * x^i over the coefficients. Returns 0.0 for an empty coefficient list. Complexity: O(n log n).
- Postcondition:
(coefficients.len() > 0) || (result == 0)
fn geometric_series(a: Float64, r: Float64, n: Int) -> Float64¶
Sum of the first n terms of the geometric series a, ar, ar^2, ... via the closed form a(1 - r^n)/(1 - r) for r != 1 and an for r == 1. Returns 0.0 for n <= 0. Complexity: O(log n).
- Postcondition:
(n > 0) || (result == 0)
fn arithmetic_series(a: Float64, d: Float64, n: Int) -> Float64¶
Sum of the first n terms of the arithmetic series a, a+d, a+2d, ... via the closed form n/2 * (2a + (n-1)d). Returns 0.0 for n <= 0. Complexity: O(1).
- Postcondition:
(n > 0) || (result == 0)
fn harmonic(n: Int) -> Float64¶
The n-th harmonic number: sum of 1/k for k = 1..n. Returns 0.0 for n <= 0. Complexity: O(n).
- Postcondition:
(n <= 0) || (result > 0)
fn maclaurin_series(f: fn(Float64) -> Float64, order: Int, x: Float64) -> Float64¶
Truncated Maclaurin (Taylor at 0) approximation of f to the given order: sum_{k=0..order} f^(k)(0)/k! * x^k. The derivatives are obtained with the order-2 central-difference stencil at step 0.001, so the approximation is accurate for smooth f and small |x|. Returns 0.0 for order < 0. Complexity: O(order^2). TODO(compiler): NOT IMPLEMENTABLE in this compiler build - the implementation (recursive stencil accumulation over fn-typed params with Int->Float64 casts) makes any program that links it crash at startup with 0xC000001D (BUG 20 AVX-512 codegen on Zen 2), even before main. Keep the frozen signature; revisit when the vectorizer cannot touch this shape.
fn continued_fraction(coeffs: &Vec[Float64]) -> Float64¶
Value of the simple continued fraction [coeffs[0]; coeffs[1], ...] = c0 + 1/(c1 + 1/(c2 + ...)), evaluated from the last coefficient backwards by recursion (one term per frame; the smoke uses a handful of terms). Returns 0.0 for an empty list. A zero partial denominator propagates as +/- infinity (IEEE semantics). Complexity: O(len(coeffs)).
- Postcondition:
(coeffs.len() > 0) || (result == 0)
fn fib(n: Int) -> Int¶
The n-th Fibonacci number F(n), 0-indexed (F(0) = 0, F(1) = 1); returns 0 for n < 0. Delegates to xiom.math.combinatorics.fibonacci. Complexity: O(n).
- Postcondition:
(n < 0) || (n > 92) || (result >= 0)
fn fib_fast(n: Int) -> Int¶
The n-th Fibonacci number via the fast-doubling identities F(2k) = F(k)(2F(k+1) - F(k)), F(2k+1) = F(k)^2 + F(k+1)^2. Returns 0 for n < 0 and 0 (documented) for n > 91, where the doubling intermediates exceed Int range (the plain iteration in math.combinatorics.fibonacci reaches F(92)). Complexity: O(log n).
- Postcondition:
(n < 0) || (n > 91) || (result >= 0)
fn convergence_rate(seq: &Vec[Float64]) -> Float64¶
Estimated order of convergence p of the sequence seq: using the last consecutive-difference triple (e0, e1, e2) with all ratios valid, p = ln(e2/e1) / ln(e1/e0). Returns 0.0 when fewer than 4 terms are supplied or when no valid triple exists (documented; e.g. a zero difference anywhere). Complexity: O(len(seq)). Implemented iteratively (no recursive Bool-accumulator walk) and verified on v0.61.3 on 2026-09-24: linear sequences give ~1.0, quadratically convergent sequences give ~2.0.
- Postcondition:
(seq.len() >= 4) || (result == 0)
set_theory.xi¶
fn set_union(a: &Vec[Int], b: &Vec[Int]) -> Vec[Int]¶
Union of two sets: every element present in either input, deduplicated. Complexity: O((|a| + |b|)^2).
- Postcondition:
result.len() <= a.len() + b.len()
fn set_intersection(a: &Vec[Int], b: &Vec[Int]) -> Vec[Int]¶
Intersection of two sets: elements present in both inputs, deduplicated. Complexity: O(|a| * |b|).
- Postcondition:
result.len() <= a.len()
fn set_difference(a: &Vec[Int], b: &Vec[Int]) -> Vec[Int]¶
Difference of two sets: elements of a not present in b, deduplicated. Complexity: O(|a| * |b|).
- Postcondition:
result.len() <= a.len()
fn set_symmetric_difference(a: &Vec[Int], b: &Vec[Int]) -> Vec[Int]¶
Symmetric difference: elements present in exactly one of the two inputs, deduplicated. Complexity: O(|a| * |b| + |b|).
- Postcondition:
result.len() <= a.len() + b.len()
fn set_subset(a: &Vec[Int], b: &Vec[Int]) -> Bool¶
True iff a is a subset of b: every element of a appears in b (duplicates in the inputs are ignored). The empty set is a subset of everything. Complexity: O(|a| * |b|).
- Postcondition:
(a.len() == 0) => (result == true)
fn set_superset(a: &Vec[Int], b: &Vec[Int]) -> Bool¶
True iff a is a superset of b. Complexity: O(|b| * |a|).
- Postcondition:
(b.len() == 0) => (result == true)
fn set_proper_subset(a: &Vec[Int], b: &Vec[Int]) -> Bool¶
True iff a is a proper subset of b: a is a subset of b and the two sets differ in cardinality. Complexity: O(|a| * |b| + |b|).
- Postcondition:
(a.len() == 0 && b.len() > 0) => (result == true)
fn set_disjoint(a: &Vec[Int], b: &Vec[Int]) -> Bool¶
True iff a and b share no element. Complexity: O(|a| * |b|).
- Postcondition:
(a.len() == 0 || b.len() == 0) => (result == true)
fn set_partition(s: &Vec[Int], blocks: &Vec[Vec[Int]]) -> Bool¶
True iff the blocks form a partition of s: every block is non-empty, the blocks are pairwise disjoint, and their union equals s exactly (each element of s appears in exactly one block and no block contains an element outside s). Complexity: O(|blocks|^2 * max block size + |s| * |blocks|). Whether
blockspartitionss: every element ofsappears in exactly one block and no block carries an element outsides. Implemented with the row-local nested-Vec read (copyblocks[i]into a local before indexing); directblocks[i][j]on a by-ref parameter is miscompiled on the current compiler (BUG 12 family). Re-verified on v0.61.3 with the row-copy shape, so the previous NOT-IMPLEMENTABLE stub is closed. Complexity: O(|s| * total block elements).
- Postcondition:
(s.len() == 0 && blocks.len() == 0) => (result == true)
fn set_power_set(s: &Vec[Int]) -> Vec[Vec[Int]]¶
All subsets of s (the power set, 2^n subsets). Returns an empty list when |s| > 20 (documented guard against an impractical result set). Complexity: O(2^n * n).
- Postcondition:
s.len() > 20 || result.len() >= 1
fn set_cartesian_product(a: &Vec[Int], b: &Vec[Int]) -> Vec[(Int, Int)]¶
All ordered pairs (x, y) with x in a and y in b. Complexity: O(|a| * |b|).
- Postcondition:
result.len() == a.len() * b.len()
fn set_cardinality(s: &Vec[Int]) -> Int¶
Number of unique elements in s (duplicates in the input are ignored). Complexity: O(|s|^2).
- Postcondition:
result >= 0 && result <= s.len()
fn set_complement(s: &Vec[Int], universe: &Vec[Int]) -> Vec[Int]¶
Complement of s relative to universe: every element of universe not present in s. Complexity: O(|universe| * |s|).
- Postcondition:
result.len() <= universe.len()
fn set_comprehension(pred: fn(Int) -> Bool, universe: &Vec[Int]) -> Vec[Int]¶
Elements of universe satisfying the predicate pred, in universe order. Complexity: O(|universe| * pred).
- Postcondition:
result.len() <= universe.len()
signal.xi¶
fn dft(x: &Vec[Float64]) -> Vec[Float64]¶
Discrete Fourier transform by direct summation. Returns the interleaved complex spectrum [re0, im0, ...] of length 2n; empty for an empty input. Complexity: O(n^2).
- Postcondition:
result.len() == 2 * x.len()
fn idft(x: &Vec[Float64]) -> Vec[Float64]¶
Inverse discrete Fourier transform: the interleaved complex input is inverted and the real part is returned. Empty for an empty input. Complexity: O(n^2).
- Postcondition:
result.len() == x.len() / 2
fn fft(x: &Vec[Float64]) -> Vec[Float64]¶
Fast Fourier transform (iterative radix-2) of a real signal; non-power-of- two lengths fall back to the direct DFT. Returns the interleaved spectrum. Complexity: O(n log n).
- Postcondition:
result.len() == 2 * x.len()
fn ifft(x: &Vec[Float64]) -> Vec[Float64]¶
Inverse fast Fourier transform: inverts the interleaved complex spectrum by the direct inverse DFT (O(n^2)); the real signal is returned. Complexity: O(n^2).
- Postcondition:
result.len() == x.len() / 2
fn fft_real(x: &Vec[Float64]) -> Vec[Float64]¶
FFT specialized for real-valued input (same routine as fft). Complexity: O(n log n).
- Postcondition:
result.len() == 2 * x.len()
fn ifft_real(x: &Vec[Float64]) -> Vec[Float64]¶
Inverse FFT returning the real signal. Complexity: O(n log n).
- Postcondition:
result.len() == x.len() / 2
fn dct(x: &Vec[Float64]) -> Vec[Float64]¶
Orthonormal discrete cosine transform (type II). Complexity: O(n^2).
- Postcondition:
result.len() == x.len()
fn idct(x: &Vec[Float64]) -> Vec[Float64]¶
Inverse discrete cosine transform (type III, unnormalized-compatible with dct). Complexity: O(n^2).
- Postcondition:
result.len() == x.len()
fn dct_type2(x: &Vec[Float64]) -> Vec[Float64]¶
Discrete cosine transform type II (alias of dct). Complexity: O(n^2).
- Postcondition:
result.len() == x.len()
fn dct_type3(x: &Vec[Float64]) -> Vec[Float64]¶
Discrete cosine transform type III (alias of idct). Complexity: O(n^2).
- Postcondition:
result.len() == x.len()
fn dst(x: &Vec[Float64]) -> Vec[Float64]¶
Discrete sine transform (DST-I). Complexity: O(n^2).
- Postcondition:
result.len() == x.len()
fn idst(x: &Vec[Float64]) -> Vec[Float64]¶
Inverse discrete sine transform (IDST-I). Complexity: O(n^2).
- Postcondition:
result.len() == x.len()
fn wavelet_haar(x: &Vec[Float64], level: Int) -> Vec[Float64]¶
Haar discrete wavelet transform to the given level: the approximation coefficients followed by the detail coefficients of each level. Returns the empty vector for level <= 0 or an empty signal. Complexity: O(n).
- Postcondition:
result.len() <= x.len()
fn wavelet_dwt(x: &Vec[Float64], level: Int) -> Vec[Float64]¶
Level multi-resolution discrete wavelet transform (Haar basis). Alias of wavelet_haar. Complexity: O(n).
- Postcondition:
result.len() <= x.len()
fn wavelet_idwt(coeffs: &Vec[Float64], level: Int) -> Vec[Float64]¶
Inverse Haar wavelet transform: the input holds the detail coefficients of each level (level 1 first) followed by the final approximation block, as produced by wavelet_haar. Complexity: O(n).
- Postcondition:
result.len() <= coeffs.len()
fn wavelet_daubechies(x: &Vec[Float64], taps: Int, level: Int) -> Vec[Float64]¶
Daubechies wavelet transform with the D4 filter for taps == 4; other tap counts fall back to the Haar basis. Complexity: O(n).
- Postcondition:
result.len() <= x.len()
fn filter_lowpass(x: &Vec[Float64], cutoff: Float64, order: Int) -> Vec[Float64]¶
One-pass first-order alpha filter: y[n] = y[n-1] + a (x[n] - y[n-1]) with a = cutoff / (1 + cutoff). filter_lowpass applies it
ordertimes. Complexity: O(n * order).
- Postcondition:
order <= 0 || result.len() == x.len()
fn filter_highpass(x: &Vec[Float64], cutoff: Float64, order: Int) -> Vec[Float64]¶
First-order high-pass filter: y[n] = alpha (y[n-1] + x[n] - x[n-1]), applied
ordertimes. Complexity: O(n * order).
- Postcondition:
order <= 0 || result.len() == x.len()
fn filter_bandpass(x: &Vec[Float64], lo: Float64, hi: Float64, order: Int) -> Vec[Float64]¶
Band-pass filter: a low-pass at hi cascaded with a high-pass at lo. Complexity: O(n * order).
- Postcondition:
order <= 0 || result.len() == x.len()
fn filter_bandstop(x: &Vec[Float64], lo: Float64, hi: Float64, order: Int) -> Vec[Float64]¶
Band-stop filter: the input minus the band-passed signal. Complexity: O(n * order).
- Postcondition:
order <= 0 || result.len() == x.len()
fn filter_butterworth(x: &Vec[Float64], cutoff: Float64, order: Int) -> Vec[Float64]¶
Butterworth low-pass filter (maximally flat): implemented as the cascaded first-order alpha low-pass of filter_lowpass. Complexity: O(n * order).
- Postcondition:
order <= 0 || result.len() == x.len()
fn filter_chebyshev(x: &Vec[Float64], cutoff: Float64, ripple: Float64, order: Int) -> Vec[Float64]¶
Chebyshev low-pass filter with passband ripple: implemented as the cascaded alpha low-pass (the ripple parameter shapes the alpha gain). Complexity: O(n * order).
- Postcondition:
order <= 0 || result.len() == x.len()
fn filter_bessel(x: &Vec[Float64], cutoff: Float64, order: Int) -> Vec[Float64]¶
Bessel low-pass filter (maximally flat group delay): implemented as the cascaded alpha low-pass. Complexity: O(n * order).
- Postcondition:
order <= 0 || result.len() == x.len()
fn filter_fir(x: &Vec[Float64], coeffs: &Vec[Float64]) -> Vec[Float64]¶
Finite impulse response filter: y[n] = sum_k coeffs[k] x[n-k]. Complexity: O(n * taps).
- Postcondition:
(x.len() > 0 && coeffs.len() > 0) => (result.len() == x.len())
fn filter_iir(x: &Vec[Float64], b: &Vec[Float64], a: &Vec[Float64]) -> Vec[Float64]¶
Infinite impulse response filter with numerator b and denominator a: y[n] = (sum_k b_k x[n-k] - sum_{k>=1} a_k y[n-k]) / a_0. Complexity: O(n * taps).
- Postcondition:
(x.len() > 0 && a.len() > 0) => (result.len() == 0 || result.len() == x.len())
fn convolve(x: &Vec[Float64], kernel: &Vec[Float64]) -> Vec[Float64]¶
Linear convolution of x with kernel (length n + m - 1). Complexity: O(n*m).
- Postcondition:
(x.len() > 0 && kernel.len() > 0) => (result.len() == x.len() + kernel.len() - 1)
fn correlate(x: &Vec[Float64], kernel: &Vec[Float64]) -> Vec[Float64]¶
Cross-correlation of x with kernel at lags - (m-1) .. (n-1). Complexity: O(n*m).
- Postcondition:
(x.len() > 0 && kernel.len() > 0) => (result.len() == x.len() + kernel.len() - 1)
fn autocorrelate(x: &Vec[Float64]) -> Vec[Float64]¶
Autocorrelation of x at lags 0 .. n-1. Complexity: O(n^2).
- Postcondition:
result.len() == x.len()
fn window_hanning(n: Int) -> Vec[Float64]¶
Length-n Hanning window: 0.5 (1 - cos(2 pi i / (n-1))). Empty for n <= 0. Complexity: O(n).
- Postcondition:
n <= 0 || result.len() == n
fn window_hamming(n: Int) -> Vec[Float64]¶
Length-n Hamming window: 0.54 - 0.46 cos(2 pi i / (n-1)). Complexity: O(n).
- Postcondition:
n <= 0 || result.len() == n
fn window_blackman(n: Int) -> Vec[Float64]¶
Length-n Blackman window. Complexity: O(n).
- Postcondition:
n <= 0 || result.len() == n
fn window_kaiser(n: Int, beta: Float64) -> Vec[Float64]¶
Length-n Kaiser window with shape beta (zeroth-order modified Bessel approximation). Complexity: O(n).
- Postcondition:
n <= 0 || result.len() == n
fn window_bartlett(n: Int) -> Vec[Float64]¶
Length-n Bartlett triangular window. Complexity: O(n).
- Postcondition:
n <= 0 || result.len() == n
fn window_gaussian(n: Int, sigma: Float64) -> Vec[Float64]¶
Length-n Gaussian window with deviation sigma. Complexity: O(n).
- Postcondition:
n <= 0 || result.len() == n
fn spectrum(x: &Vec[Float64]) -> Vec[Float64]¶
Magnitude spectrum |FFT(x)|. Complexity: O(n log n).
- Postcondition:
result.len() == x.len()
fn psd(x: &Vec[Float64]) -> Vec[Float64]¶
Power spectral density |FFT(x)|^2 / N. Complexity: O(n log n).
- Postcondition:
result.len() == x.len()
fn spectrogram(x: &Vec[Float64], win_size: Int, hop: Int) -> Vec[Vec[Float64]]¶
Time-frequency spectrogram matrix: windowed magnitude spectra, one row per frame (frames start every
hopsamples, widthwin_size). Complexity: O(frames * win_size^2).
- Postcondition:
(x.len() == 0 || win_size <= 0 || hop <= 0) => (result.len() == 0)
fn cepstrum(x: &Vec[Float64]) -> Vec[Float64]¶
Cepstrum: |IDFT(ln(|DFT(x)| + eps))|. Complexity: O(n log n).
- Postcondition:
result.len() == x.len()
fn mel_filterbank(n_filters: Int, fft_size: Int, sample_rate: Float64) -> Vec[Vec[Float64]]¶
Mel-scale triangular filter bank: n_filters rows of fft_size/2 + 1 weights. Complexity: O(n_filters * fft_size).
- Postcondition:
(n_filters > 0 && fft_size > 0 && sample_rate > 0) => (result.len() == n_filters)
fn mfcc(x: &Vec[Float64], n_coeffs: Int, sample_rate: Float64) -> Vec[Float64]¶
Mel-frequency cepstral coefficients: the log-mel spectrum of x followed by the DCT, keeping the first n_coeffs coefficients. Empty for degenerate input. Complexity: O(n log n + filters * fft_size + filters^2).
- Postcondition:
result.len() <= 24
special.xi¶
fn gamma(x: Float64) -> Float64¶
Gamma function. Poles (x == 0 and negative integers) return +inf (documented). NaN propagates. Complexity: O(1) Lanczos + reflection.
- Postcondition:
(x <= 0) || (result > 0) || (result != result)
fn lgamma(x: Float64) -> (Float64, Int)¶
Log-gamma: (ln|gamma(x)|, sign of gamma(x)). sign is +1 or -1, or 0 at a pole (value +inf). Complexity: O(1).
- Postcondition:
(result._1 == 0) || (result._1 == 1) || (result._1 == -1)
fn gamma_ln(x: Float64) -> Float64¶
Natural log of the gamma function. Same value as lgamma's first component (sign discarded). Complexity: O(1).
- Postcondition:
(x <= 0) || (result >= -1) || (result != result)
fn beta(a: Float64, b: Float64) -> Float64¶
Beta function B(a, b) = gamma(a) gamma(b) / gamma(a + b) via the Lanczos log-gamma (stable, no overflow). Returns NaN for a <= 0 or b <= 0 (documented domain). Complexity: O(1).
- Postcondition:
(a <= 0) || (b <= 0) || (result > 0) || (result != result)
fn beta_ln(a: Float64, b: Float64) -> Float64¶
Natural log of the beta function. NaN for a <= 0 or b <= 0. Complexity: O(1).
- Postcondition:
(a > 0 && b > 0) || (result != result)
fn incomplete_gamma(a: Float64, x: Float64) -> Float64¶
Regularized lower incomplete gamma P(a, x). NaN for a <= 0 or x < 0; P(a, 0) == 0. Uses the series (x < a + 1) or continued fraction. Complexity: O(iterations).
- Postcondition:
(a <= 0) || (x < 0) || ((result >= 0) && (result <= 1)) || (result != result)
fn incomplete_gamma_low(a: Float64, x: Float64) -> Float64¶
Alias of incomplete_gamma: the regularized lower incomplete gamma P(a, x).
- Postcondition:
(a <= 0) || (x < 0) || ((result >= 0) && (result <= 1)) || (result != result)
fn incomplete_beta(a: Float64, b: Float64, x: Float64) -> Float64¶
Regularized incomplete beta I_x(a, b) for x in [0, 1]. NaN for a <= 0, b <= 0, or x outside [0, 1]. Series/continued-fraction evaluation. Complexity: O(iterations).
- Postcondition:
(a <= 0) || (b <= 0) || (x < 0) || (x > 1) || ((result >= 0) && (result <= 1)) || (result != result)
fn erf(x: Float64) -> Float64¶
Error function erf(x). Maximum absolute error ~3e-8 (NR rational approx). Complexity: O(1).
- Postcondition:
((result >= -1) && (result <= 1)) || (result != result)
fn erfc(x: Float64) -> Float64¶
Complementary error function erfc(x) = 1 - erf(x). Complexity: O(1).
- Postcondition:
((result >= 0) && (result <= 2)) || (result != result)
fn erfi(x: Float64) -> Float64¶
Imaginary error function erfi(x) = -i erf(i x) = (2/sqrt(pi)) sum x^(2n+1)/(n!(2n+1)). Series for |x| <= 3; for larger |x| the asymptotic form erfi(x) ~ exp(x^2)/(sqrt(pi) x) is used. Complexity: O(n^2).
- Postcondition:
((x >= 0) && (result >= 0)) || ((x < 0) && (result <= 0)) || (result != result)
fn dawson(x: Float64) -> Float64¶
Dawson integral D(x) = exp(-x^2) * integral_0^x exp(t^2) dt. Series for |x| <= 3, asymptotic for larger |x|. Complexity: O(n^2).
- Postcondition:
((x >= 0) && (result >= 0)) || ((x < 0) && (result <= 0)) || (result != result)
fn erfinv(x: Float64) -> Float64¶
Inverse error function erfinv(x) by Newton iteration on erf (30 iters, ~1e-12 accuracy away from the endpoints). erfinv(+-1) = +-inf; |x| > 1 returns NaN. Complexity: O(30).
- Postcondition:
((x >= 0) && (result >= 0)) || ((x < 0) && (result <= 0)) || (result != result)
fn erfcinv(x: Float64) -> Float64¶
Inverse complementary error function erfcinv(x) = erfinv(1 - x). x in (0, 2); endpoints return +-inf; outside returns NaN. Complexity: O(erfinv).
- Postcondition:
(((x <= 1) || (result <= 0)) && ((x >= 1) || (result >= 0))) || (result != result)
fn bessel_j0(x: Float64) -> Float64¶
J_0(x) via the alternating power series. Accurate for moderate |x|; for |x| > 30 the asymptotic form is used. Complexity: O(n^2).
- Postcondition:
((result >= -1) && (result <= 1)) || (result != result)
fn bessel_j1(x: Float64) -> Float64¶
J_1(x) via the alternating power series. Complexity: O(n^2).
- Postcondition:
((result >= -1) && (result <= 1)) || (result != result)
fn bessel_j(n: Int, x: Float64) -> Float64¶
J_n(x), Bessel of the first kind of integer order n, by its power series sum (-1)^k (x/2)^(2k+n)/(k!(k+n)!). Negative n uses J_{-n} = (-1)^n J_n. Complexity: O(n^2).
- Postcondition:
(math.abs_float(x) > 30) || ((result >= -1) && (result <= 1)) || (result != result)
fn bessel_jn(n: Int, x: Float64) -> Float64¶
Alias of bessel_j for order n. Complexity: O(terms).
- Postcondition:
(math.abs_float(x) > 30) || ((result >= -1) && (result <= 1)) || (result != result)
fn bessel_y0(x: Float64) -> Float64¶
Y_0(x), Bessel of the second kind of order zero: series with the digamma/harmonic terms. NaN for x <= 0 (branch cut). Complexity: O(terms).
- Postcondition:
(x > 0) || (result != result)
fn bessel_y1(x: Float64) -> Float64¶
Y_1(x), Bessel of the second kind of order one, via -d/dx Y_0 (central difference, ~1e-9 relative for moderate x). NaN for x <= 0. Complexity: O(1).
- Postcondition:
(x > 0) || (result != result)
fn bessel_y(n: Int, x: Float64) -> Float64¶
Y_n(x), Bessel of the second kind of integer order n by upward recurrence Y_{n+1} = (2n/x) Y_n - Y_{n-1} from Y_0, Y_1. NaN for x <= 0. Complexity: O(n).
- Postcondition:
(x > 0) || (result != result)
fn bessel_yn(n: Int, x: Float64) -> Float64¶
Y_n(x) for integer order n. NaN for x <= 0 or negative n. Complexity: O(n).
- Postcondition:
(n >= 0 && x > 0) || (result != result)
fn bessel_i(n: Int, x: Float64) -> Float64¶
I_n(x), modified Bessel of the first kind of integer order n (series sum (x/2)^(2k+n)/(k!(k+n)!); I_{-n} == I_n for integer n). Complexity: O(n^2).
- Postcondition:
(x >= 0) || ((n % 2 == 0) && (result >= 0)) || ((n % 2 != 0) && (result <= 0)) || (result != result)
fn bessel_k0(x: Float64) -> Float64¶
K_0(x), modified Bessel of the second kind of order zero: series K_0 = -(ln(x/2) + gamma) I_0 + sum H_k/(k!)^2 (x/2)^{2k}. NaN for x <= 0.
- Postcondition:
(x <= 0) || (x >= 700) || (result > 0) || (result != result)
fn bessel_k1(x: Float64) -> Float64¶
K_1(x) via -d/dx K_0 (central difference). NaN for x <= 0. Complexity: O(1).
- Postcondition:
(x <= 0) || (x >= 700) || (result > 0) || (result != result)
fn bessel_k(n: Int, x: Float64) -> Float64¶
K_n(x), modified Bessel of the second kind of integer order n by upward recurrence K_{n+1} = (2n/x) K_n + K_{n-1}. NaN for x <= 0 or n < 0.
- Postcondition:
(x <= 0) || (n < 0) || (x >= 700) || (result > 0) || (result != result)
fn zeta(x: Float64) -> Float64¶
Riemann zeta via Euler-Maclaurin (9 pre-summed terms + Bernoulli terms to B_16). Exact to ~1e-9 for s in (0, 40]. s == 1 returns +inf; s < 0 uses the functional equation zeta(s) = 2^s pi^(s-1) sin(pi s/2) Gamma(1-s) zeta(1-s). Complexity: O(1).
- Postcondition:
(x <= 1) || (x >= 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) || (result >= 1) || (result != result)
fn riemann_zeta(x: Float64) -> Float64¶
Riemann zeta (alias). Complexity: O(1).
- Postcondition:
(x <= 1) || (x >= 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) || (result >= 1) || (result != result)
fn riemann_zeta_eta(x: Float64) -> Float64¶
Dirichlet eta function: eta(s) = (1 - 2^(1-s)) zeta(s). Complexity: O(1).
- Postcondition:
(x <= 1) || (x >= 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) || ((result >= 0) && (result <= 1)) || (result != result)
fn dirichlet_beta(x: Float64) -> Float64¶
Dirichlet beta function beta(s) = sum (-1)^k (2k+1)^(-s) by direct alternating summation (100k terms; alternating-series tail bound). Complexity: O(100000).
- Postcondition:
(x <= 0) || (x >= 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) || ((result > 0) && (result <= 1)) || (result != result)
fn lerch_phi(z: Float64, s: Float64, a: Float64) -> Float64¶
Lerch transcendent Phi(z, s, a) = sum z^k (k+a)^(-s), |z| < 1, a > 0. At most 2000 terms; NaN for |z| >= 1 (divergent) or a <= 0. Complexity: O(terms).
- Postcondition:
(a <= 0) || (z < 0) || (result > 0) || (result != result)
fn polylog(s: Float64, z: Float64) -> Float64¶
Polylogarithm Li_s(z) = sum z^k k^(-s), |z| < 1 (z == 1 and s > 1 gives zeta(s)). At most 2000 terms; NaN for |z| > 1 (divergent). Complexity: O(2000).
- Postcondition:
(z < 0) || (result >= 0) || (result != result)
fn digamma(x: Float64) -> Float64¶
Digamma psi(x) = d/dx ln gamma(x). NaN at poles (x <= 0 integer); uses the shift recurrence + asymptotic for x >= 6 and the reflection formula for x < 0.5. Complexity: O(ceil(6 - x)) shifts.
- Postcondition:
(x > 0) || (x != x) || (x != (?)) || (result == 1 / 0)
fn trigamma(x: Float64) -> Float64¶
Trigamma psi'(x), second derivative of ln gamma. NaN at poles. Complexity: O(shifts).
- Postcondition:
(x <= 0) || (x >= 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) || (result > 0) || (result != result)
fn polygamma(m: Int, x: Float64) -> Float64¶
Polygamma psi^(m)(x). m == 0 delegates to digamma; m < 0 returns NaN. For x <= 0 non-integer the reflection psi^(m)(x) = (-1)^m psi^(m)(1-x) - pi d^m/dx^m cot(pi x) is used (numerical cot derivative for m >= 2); poles return +inf. Complexity: O(shifts + m^2).
- Postcondition:
(x <= 0) || (x >= 1000000000) || (m < 0) || (m > 8) || (m == 0) || ((m % 2 == 1) && (result > 0)) || ((m % 2 == 0) && (result < 0)) || (result != result)
fn legendre_p(n: Int, x: Float64) -> Float64¶
Legendre polynomial P_n(x) by the recurrence (n+1)P_{n+1} = (2n+1)x P_n - n P_{n-1}. NaN for n < 0. Complexity: O(n).
- Postcondition:
(n < 0) || (x < -1) || (x > 1) || ((result >= -1) && (result <= 1)) || (result != result)
fn legendre_q(n: Int, x: Float64) -> Float64¶
Legendre function of the second kind Q_n(x) for |x| < 1 (Q0 = atanh(x), Q1 = x atanh(x) - 1, then the same recurrence as P). NaN for |x| >= 1 or n < 0. Complexity: O(n).
- Postcondition:
(n >= 0 && x > -1 && x < 1) || (result != result)
fn chebyshev_t(n: Int, x: Float64) -> Float64¶
Chebyshev polynomial of the first kind T_n(x): T_{n+1} = 2x T_n - T_{n-1}. NaN for n < 0. Complexity: O(n).
- Postcondition:
(n < 0) || (x < -1) || (x > 1) || ((result >= -1) && (result <= 1)) || (result != result)
fn hermite_h(n: Int, x: Float64) -> Float64¶
Hermite polynomial (physicists') H_n(x): H_{n+1} = 2x H_n - 2n H_{n-1}. NaN for n < 0. Complexity: O(n).
- Postcondition:
(n >= 0) || (result != result)
fn laguerre_l(n: Int, a: Float64, x: Float64) -> Float64¶
Generalized Laguerre polynomial L_n^(a)(x). NaN for n < 0 or a <= -1. Complexity: O(n).
- Postcondition:
(n >= 0 && a > -1) || (result != result)
fn jacobi_p(n: Int, a: Float64, b: Float64, x: Float64) -> Float64¶
Jacobi polynomial P_n^(a,b)(x). NaN for n < 0, a <= -1, b <= -1. Three-term recurrence (DLMF 18.9.2). Complexity: O(n).
- Postcondition:
(n >= 0 && a > -1 && b > -1) || (result != result)
fn gegenbauer_c(n: Int, a: Float64, x: Float64) -> Float64¶
Gegenbauer (ultraspherical) polynomial C_n^a(x). NaN for n < 0. Complexity: O(n).
- Postcondition:
(n >= 0) || (result != result)
fn spherical_harmonic(l: Int, m: Int, theta: Float64, phi: Float64) -> Float64¶
Real spherical harmonic Y_l^m(theta, phi) using the quantum convention Y_l^m = sqrt((2l+1)/(4 pi) (l-|m|)!/(l+|m|)!) P_l^|m|(cos theta) cos(m phi) (m >= 0; m < 0 uses sin(|m| phi)). NaN for invalid l, m or theta outside [0, pi]. Complexity: O(l).
- Postcondition:
(l >= 0 && m >= -l && m <= l && theta >= 0 && theta <= 3.141592653589793) || (result != result)
fn airy_ai(x: Float64) -> Float64¶
Airy function of the first kind Ai(x). Series for |x| <= 6; for larger |x| the asymptotic forms are used. Complexity: O(60).
- Postcondition:
(math.abs_float(x) > 3) || ((result >= -1) && (result <= 1)) || (result != result)
fn airy_bi(x: Float64) -> Float64¶
Airy function of the second kind Bi(x). Series for |x| <= 6; asymptotic for larger |x|. Complexity: O(60).
- Postcondition:
(x == x) || (result != result)
fn airy_aip(x: Float64) -> Float64¶
Derivative of the Airy function of the first kind Ai'(x). Series for |x| <= 6; for larger |x| a central-difference of airy_ai is used. Complexity: O(60).
- Postcondition:
(math.abs_float(x) > 3) || ((result >= -2) && (result <= 2)) || (result != result)
fn airy_bip(x: Float64) -> Float64¶
Derivative of the Airy function of the second kind Bi'(x). Series for |x| <= 6; for larger |x| a central-difference of airy_bi is used. Complexity: O(60).
- Postcondition:
(x == x) || (result != result)
fn fresnel_s(x: Float64) -> Float64¶
Sine integral S(x) = integral_0^x sin(pi t^2/2) dt. Series to 60 terms (accurate for |x| <= 8); NaN for NaN. Complexity: O(60).
- Postcondition:
(math.abs_float(x) > 2) || ((result >= -1) && (result <= 1)) || (result != result)
fn fresnel_c(x: Float64) -> Float64¶
Cosine integral C(x) = integral_0^x cos(pi t^2/2) dt. Series to 60 terms. Complexity: O(60).
- Postcondition:
(math.abs_float(x) > 2) || ((result >= -1) && (result <= 1)) || (result != result)
fn elliptic_k(k: Float64) -> Float64¶
Complete elliptic integral of the first kind K(k) via the arithmetic- geometric mean: K(k) = pi / (2 AGM(1, sqrt(1-k^2))). NaN for |k| > 1. K(0) = pi/2 exactly. Complexity: O(AGM iterations).
- Postcondition:
(k < -1) || (k > 1) || (result >= 1.5707963267948966) || (result != result)
fn elliptic_e(k: Float64) -> Float64¶
Complete elliptic integral of the second kind E(k) via the Legendre series E(k) = (pi/2) [1 - sum ((2n-1)!!/(2n)!!)^2 k^(2n)/(2n-1)] for k^2 < 0.9; for k^2 >= 0.9 the defining integral is integrated by Simpson's rule. NaN for |k| > 1. Complexity: O(n^2) series / O(panels) quadrature.
- Postcondition:
(k < -1) || (k > 1) || ((result >= 1) && (result <= 1.5707963267948966)) || (result != result)
fn elliptic_pi(n: Float64, k: Float64) -> Float64¶
Complete elliptic integral of the third kind Pi(n, k) = integral_0^(pi/2) dtheta / ((1 - n sin^2 theta) sqrt(1 - k^2 sin^2 theta)) by Simpson quadrature (500 panels). NaN for n > 1 or |k| > 1 (documented domain).
- Postcondition:
(math.abs_float(k) <= 1 && n <= 1) || (result != result)
fn elliptic_f(phi: Float64, k: Float64) -> Float64¶
Incomplete elliptic integral of the first kind F(phi, k) = integral_0^phi dtheta / sqrt(1 - k^2 sin^2 theta) by Simpson quadrature. NaN for |k| > 1. Complexity: O(panels).
- Postcondition:
(phi <= 0) || (result >= 0) || (result != result)
fn elliptic_e_incomplete(phi: Float64, k: Float64) -> Float64¶
Incomplete elliptic integral of the second kind E(phi, k) = integral_0^phi sqrt(1 - k^2 sin^2 theta) dtheta by Simpson quadrature. NaN for |k| > 1. Complexity: O(panels).
- Postcondition:
(phi <= 0) || (result >= 0) || (result != result)
fn elliptic_pi_incomplete(n: Float64, phi: Float64, k: Float64) -> Float64¶
Incomplete elliptic integral of the third kind Pi(n; phi, k) by Simpson quadrature. NaN for n > 1 or |k| > 1. Complexity: O(panels).
- Postcondition:
(n > 1) || (phi <= 0) || (result > 0) || (result != result)
fn theta_1(x: Float64, q: Float64) -> Float64¶
theta_1(x, q) = 2 sum_{n>=0} (-1)^n q^((n+1/2)^2) sin((2n+1)x). Converges for 0 < q < 1 (real-domain); NaN otherwise. Complexity: O(terms).
- Postcondition:
(x <= 0) || (x >= 3.141592653589793) || (q <= 0) || (q >= 0.95) || (result > 0) || (result != result)
fn theta_2(x: Float64, q: Float64) -> Float64¶
theta_2(x, q) = 2 sum_{n>=0} q^((n+1/2)^2) cos((2n+1)x). Converges for 0 < q < 1 (real-domain); NaN otherwise. Complexity: O(terms).
- Postcondition:
(q > 0 && q < 1) || (result != result)
fn theta_3(x: Float64, q: Float64) -> Float64¶
theta_3(x, q) = 1 + 2 sum_{n>=1} q^(n^2) cos(2nx). Complexity: O(terms).
- Postcondition:
(q <= 0) || (q >= 0.95) || (result > 0) || (result != result)
fn theta_4(x: Float64, q: Float64) -> Float64¶
theta_4(x, q) = 1 + 2 sum_{n>=1} (-1)^n q^(n^2) cos(2nx). Complexity: O(terms).
- Postcondition:
(math.abs_float(q) < 1) || (result != result)
fn exponential_integral(x: Float64) -> Float64¶
Exponential integral Ei(x) = gamma + ln|x| + sum x^k/(k k!) (Cauchy principal value for x < 0). At most 80 terms; Ei(0) = -inf. Complexity: O(n^2).
- Postcondition:
(x == x) || (result != result)
fn li(x: Float64) -> Float64¶
Logarithmic integral li(x) = Ei(ln x) for x > 0, x != 1. li(1) = -inf, li(0) = 0, li(x) for x < 0 is NaN (branch cut). Complexity: O(Ei terms).
- Postcondition:
(x <= 1.5) || (result > 0) || (result != result)
fn li_offset(x: Float64) -> Float64¶
Offset logarithmic integral Li(x) = li(x) - li(2). Same domain as li. Complexity: O(Ei terms).
- Postcondition:
(x <= 2) || (result > 0) || (result != result)
fn sin_integral(x: Float64) -> Float64¶
Sine integral Si(x) = integral_0^x sin(t)/t dt via its alternating power series sum (-1)^n x^(2n+1)/((2n+1)(2n+1)!). Complexity: O(n^2).
- Postcondition:
(math.abs_float(x) > 10) || ((result >= -2) && (result <= 2)) || (result != result)
fn cos_integral(x: Float64) -> Float64¶
Cosine integral Ci(x) = gamma + ln x + sum (-1)^n x^(2n)/((2n)(2n)!) for x > 0. NaN for x < 0 (branch cut); Ci(0) = -inf. Complexity: O(n^2).
- Postcondition:
(x >= 0) || (result != result)
fn hypergeometric_2f1(a: Float64, b: Float64, c: Float64, x: Float64) -> Float64¶
Gauss hypergeometric function 2F1(a, b; c; x) by series summation (rising factorials), convergent for |x| < 1. NaN for |x| > 1 (divergent) or c <= 0 (singular). Complexity: O(terms).
- Postcondition:
(c > 0 && math.abs_float(x) <= 1) || (result != result)
fn hypergeometric_1f1(a: Float64, b: Float64, x: Float64) -> Float64¶
Confluent hypergeometric function 1F1(a; b; x) by series summation (converges for all x). NaN for b <= 0. Complexity: O(terms).
- Postcondition:
(a < 0) || (b <= 0) || (x < 0) || (result > 0) || (result != result)
topology.xi¶
fn open_set(tau: &Vec[Vec[Int]], s: &Vec[Int]) -> Bool¶
True iff s is a member of the open-set family tau (set equality, order insensitive). An empty tau never contains a non-empty s. Complexity: O(|tau| * |s|).
- Postcondition:
(tau.len() != 0 || s.len() == 0) || (result == false)
fn closed_set(tau: &Vec[Vec[Int]], s: &Vec[Int], universe: &Vec[Int]) -> Bool¶
True iff the complement of s (within universe) is open in tau. A set is closed when universe \ s is a member of the open-set family. Complexity: O(|tau| * |universe|).
fn compactness(tau: &Vec[Vec[Int]], s: &Vec[Int]) -> Bool¶
True iff every open cover of s has a finite subcover. Over a finite topology every subfamily of tau is itself finite, so this reduces to: tau as a whole covers s (a set outside the union of all open sets cannot be compact). Returns true when s is covered, false otherwise (including an empty s with empty tau). Complexity: O(|tau| * |s|).
- Postcondition:
(s.len() != 0) || (result == true)
fn connectedness(tau: &Vec[Vec[Int]], s: &Vec[Int]) -> Bool¶
True iff s cannot be split into two disjoint non-empty open sets. Checks every pair (a, b) of open sets: s is disconnected when (a | b) covers s, a and b are disjoint on s, and each meets s in a non-empty set. An empty s is vacuously connected. Complexity: O(|tau|^2 * |s|).
- Postcondition:
(s.len() != 0) || (result == true)
fn continuity(f: fn(Int) -> Int, tau_x: &Vec[Vec[Int]], tau_y: &Vec[Vec[Int]]) -> Bool¶
True iff f is continuous from (X, tau_x) to (Y, tau_y): the preimage of every open set in tau_y is open in tau_x. The domain X is taken as the union of all members of tau_x; Y likewise from tau_y. An empty tau_y is vacuously continuous. Complexity: O(|tau_x| * |tau_y| * |X|).
- Postcondition:
(tau_y.len() != 0) || (result == true)
fn homeomorphism(f: fn(Int) -> Int, g: fn(Int) -> Int, tau_x: &Vec[Vec[Int]], tau_y: &Vec[Vec[Int]]) -> Bool¶
True iff f and g form a homeomorphism: f bijective between the domains, both continuous, and g is the two-sided inverse of f. The domains are the unions of the tau_x / tau_y members. Complexity: O(|tau_x||tau_y||X|).
- Postcondition:
(tau_x.len() != 0 || tau_y.len() != 0) || (result == true)
fn topological_space(points: &Vec[Int], open_sets: &Vec[Vec[Int]]) -> Bool¶
Validates the topology axioms of (points, open_sets): every member of the family is a subset of points; the empty set and the full point set are open; the family is closed under finite intersections and arbitrary unions. Returns false for any violation (an empty points with a family containing only the empty set is valid). Complexity: O(2^|tau| * |tau|).
- Postcondition:
(open_sets.len() == 0) => (result == false)
fn metric_space(d: fn(Int, Int) -> Float64, points: &Vec[Int]) -> Bool¶
Validates the metric axioms of d on points: non-negativity, d(x, y) == 0 iff x == y, symmetry, and the triangle inequality, all within a 1e-9 tolerance. An empty point set is vacuously a metric space. Complexity: O(|points|^3).
- Postcondition:
(points.len() != 0) || (result == true)
fn ball(d: fn(Int, Int) -> Float64, center: Int, radius: Float64, points: &Vec[Int]) -> Vec[Int]¶
Open ball of radius around center: every point p with d(center, p) < radius. Returns the empty ball for a negative radius (documented). Complexity: O(|points|).
- Postcondition:
result.len() <= points.len()
fn interior(tau: &Vec[Vec[Int]], s: &Vec[Int]) -> Vec[Int]¶
Largest open set contained in s: the union of all members of tau that are subsets of s. Returns the empty set when no open subset exists. Complexity: O(|tau| * |s|).
- Postcondition:
result.len() <= s.len()
fn closure(tau: &Vec[Vec[Int]], s: &Vec[Int]) -> Vec[Int]¶
Smallest closed set containing s: the intersection of every closed set (complement of an open set in tau) that contains s. Returns s itself when no closed superset exists. Complexity: O(|tau| * |s|).
- Postcondition:
(tau.len() != 0) || (result.len() == s.len())
fn boundary(tau: &Vec[Vec[Int]], s: &Vec[Int]) -> Vec[Int]¶
Boundary of s: the points in the closure but not the interior of s. Complexity: O(|tau| * |s|).
- Postcondition:
(tau.len() != 0) || (result.len() == s.len())
fn limit_point(tau: &Vec[Vec[Int]], s: &Vec[Int], x: Int) -> Bool¶
True iff x is a limit point of s: every neighborhood of x (open set containing x) meets s in a point other than x. When x has no neighborhoods the condition is vacuously true. Complexity: O(|tau| * |s|).
- Postcondition:
(tau.len() != 0) || (result == true)
fn neighborhood(tau: &Vec[Vec[Int]], x: Int, s: &Vec[Int]) -> Bool¶
True iff s contains an open set that contains x (s is a neighborhood of x). Complexity: O(|tau| * |s|).
- Postcondition:
(tau.len() != 0) || (result == false)
tower.xi¶
fn lerp[T](a: T, b: T, t: T) -> T¶
Linear interpolation: a(1-t) + bt. Generic over every Num width.
fn average[T](a: T, b: T) -> T¶
Arithmetic mean of two values. Generic over every Num width.
- Precondition:
Num[T].add(Num[T].one(), Num[T].one()) != Num[T].zero()
fn sum[T](values: Vec[T]) -> T¶
Sum of a Vec of values. Generic over every Num width.
- Postcondition:
(values.len() != 0) || (result == Num[T].zero())
fn product[T](values: Vec[T]) -> T¶
Product of a Vec of values. Generic over every Num width.
- Postcondition:
(values.len() != 0) || (result == Num[T].one())
fn twice[T](a: T) -> T¶
Double a value. Generic over every Num width.
- Postcondition:
result == Num[T].add(a, a) || (result != result)
fn negate[T](a: T) -> T¶
Negate via zero - a. Generic over every Num width.
- Postcondition:
result == Num[T].sub(Num[T].zero(), a) || (result != result)
fn abs[T](a: T) -> T¶
Absolute value. Generic over widths implementing Real.
fn clamp[T](x: T, lo: T, hi: T) -> T¶
Clamp x into [lo, hi]. Generic over widths implementing Real.
- Precondition:
Real[T].le(lo, hi) - Postcondition:
Real[T].ge(result, lo) - Postcondition:
Real[T].le(result, hi)
fn min2[T](a: T, b: T) -> T¶
Minimum of two values. Generic over widths implementing Real.
- Postcondition:
Real[T].le(result, a) - Postcondition:
Real[T].le(result, b)
fn max2[T](a: T, b: T) -> T¶
Maximum of two values. Generic over widths implementing Real.
- Postcondition:
Real[T].ge(result, a) - Postcondition:
Real[T].ge(result, b)
fn of_int[T](v: Int) -> T¶
Build a value of any FromInt width from an Int literal.
- Postcondition:
result == FromInt[T].from_int(v)
transcendental.xi¶
fn sqrt(x: Float64) -> Float64¶
Square root of x; requires x >= 0. Returns NaN (0.0/0.0) for x < 0. Delegates to math.roots.sqrt. Complexity: O(1), libm sqrt.
- Postcondition:
(((x >= 0) && (result >= 0)) || ((x < 0) && (result != result))) || (x != x)
fn cbrt(x: Float64) -> Float64¶
Cube root of x, any sign. Delegates to math.roots.cbrt. Complexity: O(1), libm pow.
- Postcondition:
(((x >= 0) && (result >= 0)) || ((x <= 0) && (result <= 0))) || (x != x)
fn exp(x: Float64) -> Float64¶
e^x. Returns +inf for x > 700 (overflow) and 0.0 for x < -745 (underflow). Delegates to math.exponential.exp. Complexity: O(1), libm.
- Postcondition:
(result >= 0) || (result != result)
fn exp2(x: Float64) -> Float64¶
2^x. Delegates to math.exponential.exp2. Complexity: O(1), libm pow.
- Postcondition:
(result >= 0) || (result != result)
fn expm1(x: Float64) -> Float64¶
e^x - 1, accurate for small x (series for |x| <= 1e-4). Returns -1.0 for x < -700 and +inf for x > 700. Delegates to math.exponential.expm1. Complexity: O(20) series terms / O(1) libm.
- Postcondition:
(result >= -1) || (result != result)
fn ln(x: Float64) -> Float64¶
Natural logarithm of x; requires x > 0. Returns NaN (0.0/0.0) for x <= 0. Delegates to math.exponential.ln. Complexity: O(1), libm.
- Postcondition:
(result != result) || (x > 0)
fn log2(x: Float64) -> Float64¶
Base-2 logarithm of x; requires x > 0. Returns NaN for x <= 0. Delegates to math.exponential.log2. Complexity: O(1), libm.
- Postcondition:
(result != result) || (x > 0)
fn log10(x: Float64) -> Float64¶
Base-10 logarithm of x; requires x > 0. Returns NaN for x <= 0. Delegates to math.exponential.log10. Complexity: O(1), libm.
- Postcondition:
(result != result) || (x > 0)
fn log1p(x: Float64) -> Float64¶
ln(1 + x), accurate for small x (series for |x| <= 1e-4). log1p(-1.0) is -inf and log1p(x < -1) returns NaN (IEEE). Delegates to math.exponential.log1p. Complexity: O(30) series terms / O(1) libm.
- Postcondition:
((result != result) || (x > -1)) || (result == -1 / 0)
fn pow(a: Float64, b: Float64) -> Float64¶
a raised to the power b (libm pow). A negative base with a non-integral exponent returns NaN (IEEE). Delegates to math.exponential.pow. Complexity: O(1), libm.
- Postcondition:
(a > 0) => (result >= 0 || result != result)
fn pow_int(a: Float64, n: Int) -> Float64¶
a raised to the integer power n via binary exponentiation. pow_int(2, 10) == 1024, pow_int(2, -2) == 0.25; 0^0 == 1.0, 0^negative == +inf. Delegates to math.exponential.pow_int. Complexity: O(log |n|).
- Postcondition:
(n == 0) => (result == 1)
fn root(x: Float64, n: Int) -> Float64¶
n-th root of x. Even roots require x >= 0 (NaN otherwise); odd roots preserve the sign. n == 0 returns 1.0 (documented). Delegates to math.roots.nth_root. Complexity: O(1), libm pow.
- Postcondition:
(result >= 0 || result != result || n % 2 != 0)
fn gamma(x: Float64) -> Float64¶
Gamma function via the Lanczos approximation (g = 7, n = 9, error < 2e-10 for x > 0). gamma(5) == 24, gamma(0.5) == sqrt(pi). Non-positive integer arguments are poles and return NaN; other x <= 0 values are handled by the reflection formula. Complexity: O(1), ~9 rational terms.
- Postcondition:
(x == 1) => (result == 1) - Postcondition:
(x == 2) => (result == 1) - Postcondition:
(x == 0.5) => (result > 1)
fn lgamma(x: Float64) -> (Float64, Int)¶
Log-gamma: (ln |gamma(x)|, sign(gamma(x))) with sign in {-1, 1}. Returns (NaN, 0) when gamma is a pole (x a non-positive integer). The sign is 1 for positive values and -1 for negative ones. Complexity: O(gamma).
- Postcondition:
(x == 1) => (result._1 == 1) - Postcondition:
(x == 2) => (result._1 == 1)
fn erf(x: Float64) -> Float64¶
Error function erf(x). Uses erfc via the Numerical-Recipes continued fraction (relative error < 1.2e-7). erf(0) ~= 0 (approximation, not exact), erf(1) ~= 0.8427. Complexity: O(1).
- Postcondition:
((result >= -1) && (result <= 1)) || (result != result)
fn erfc(x: Float64) -> Float64¶
Complementary error function erfc(x) = 1 - erf(x). erfc(0) == 1, erfc(3) ~= 2.2e-5. Uses the Numerical-Recipes continued-fraction approximation. Complexity: O(1).
- Postcondition:
((result >= 0) && (result <= 2)) || (result != result)
fn lambert_w(x: Float64) -> Float64¶
Principal (W0) branch of the Lambert W function, the real solution of w * e^w = x. lambert_w(0) == 0, lambert_w(e) == 1, lambert_w(1) ~= 0.567143. Returns NaN for x < -1/e (no real branch exists). Newton iteration on the standard Halley-ish update converges quadratically. Complexity: O(100) iterations, O(1) each.
- Postcondition:
(x == 0) => (result == 0) - Postcondition:
(x < -0.36787944117144233) => (result != result)
trig.xi¶
fn sin(x: Float64) -> Float64¶
Sine of x in radians. NaN and infinite inputs propagate. Complexity: O(1).
- Postcondition:
((result >= -1) && (result <= 1)) || (result != result)
fn cos(x: Float64) -> Float64¶
Cosine of x in radians. NaN and infinite inputs propagate. Complexity: O(1).
- Postcondition:
((result >= -1) && (result <= 1)) || (result != result)
fn tan(x: Float64) -> Float64¶
Tangent of x in radians; a pole (cos(x) == 0) yields +-infinity (IEEE). Complexity: O(1).
- Postcondition:
(x != 0) || (result == 0)
fn asin(x: Float64) -> Float64¶
Arc sine of x in radians, result in [-pi/2, pi/2]. For x outside [-1, 1] returns NaN (documented domain error). Complexity: O(1).
- Postcondition:
((result >= -1.5708) && (result <= 1.5708)) || (result != result)
fn acos(x: Float64) -> Float64¶
Arc cosine of x in radians, result in [0, pi]. For x outside [-1, 1] returns NaN (documented domain error). Complexity: O(1).
- Postcondition:
((result >= 0) && (result <= 3.1416)) || (result != result)
fn atan(x: Float64) -> Float64¶
Arc tangent of x in radians, result in (-pi/2, pi/2). Complexity: O(1).
- Postcondition:
((result >= -1.5708) && (result <= 1.5708)) || (result != result)
fn atan2(y: Float64, x: Float64) -> Float64¶
Four-quadrant arc tangent of y/x in radians. When both y and x are zero returns NaN (documented; the angle is undefined there). Complexity: O(1).
- Postcondition:
((result >= -3.1416) && (result <= 3.1416)) || (result != result)
fn sinh(x: Float64) -> Float64¶
Hyperbolic sine of x: (exp(x) - exp(-x))/2. Large |x| propagates as +- infinity. Complexity: O(1). Delegates to xiom.math.hyperbolic (the pure-exp composition is gate-green there; the old inline-arithmetic stub refreshed 2026-09-24).
- Postcondition:
(x != 0) || (result == 0)
fn cosh(x: Float64) -> Float64¶
Hyperbolic cosine of x: (exp(x) + exp(-x))/2. Complexity: O(1). Delegates to xiom.math.hyperbolic.
- Postcondition:
(result >= 0) || (result != result)
fn tanh(x: Float64) -> Float64¶
Hyperbolic tangent of x: sinh(x)/cosh(x). Saturated to +-1 for |x| > 20 to avoid a NaN from inf/inf at the exponent overflow boundary. Complexity: O(1). Delegates to xiom.math.hyperbolic.
- Postcondition:
((result >= -1) && (result <= 1)) || (result != result)
fn asinh(x: Float64) -> Float64¶
Inverse hyperbolic sine of x: ln(x + sqrt(x^2 + 1)). Well-defined for every x. Complexity: O(1).
- Postcondition:
(x >= 0) => (result >= 0)
fn acosh(x: Float64) -> Float64¶
Inverse hyperbolic cosine of x: ln(x + sqrt(x^2 - 1)). For x < 1 returns NaN (documented domain error). Complexity: O(1).
- Postcondition:
(result >= 0) || (result != result)
fn atanh(x: Float64) -> Float64¶
Inverse hyperbolic tangent of x: ln((1+x)/(1-x))/2. For |x| >= 1 returns NaN (documented domain error; the function is undefined at the poles). Complexity: O(1). Delegates to xiom.math.hyperbolic.
- Postcondition:
(x != 0) || (result == 0)
fn sec(x: Float64) -> Float64¶
Secant of x: 1/cos(x). A pole (cos(x) == 0) yields +-infinity (IEEE). Complexity: O(1).
- Postcondition:
((result <= -1) || (result >= 1)) || (result != result)
fn csc(x: Float64) -> Float64¶
Cosecant of x: 1/sin(x). A pole (sin(x) == 0) yields +-infinity (IEEE). Complexity: O(1).
- Postcondition:
((result <= -1) || (result >= 1)) || (result != result)
fn cot(x: Float64) -> Float64¶
Cotangent of x: cos(x)/sin(x). A pole (sin(x) == 0) yields +-infinity (IEEE). Complexity: O(1).
- Postcondition:
(x != 0) || (result == 1 / 0 || result == -1 / 0 || result != result)
fn degrees(x: Float64) -> Float64¶
Convert radians to degrees: x * 180/pi. Complexity: O(1).
- Postcondition:
(x != 0) || (result == 0)
fn radians(x: Float64) -> Float64¶
Convert degrees to radians: x * pi/180. Complexity: O(1).
- Postcondition:
(x != 0) || (result == 0)
fn sin_deg(x: Float64) -> Float64¶
Sine of x in degrees. Complexity: O(1).
- Postcondition:
((result >= -1) && (result <= 1)) || (result != result)
fn cos_deg(x: Float64) -> Float64¶
Cosine of x in degrees. Complexity: O(1).
- Postcondition:
((result >= -1) && (result <= 1)) || (result != result)
fn tan_deg(x: Float64) -> Float64¶
Tangent of x in degrees. Complexity: O(1).
- Postcondition:
(x != 0) || (result == 0)
trigonometric_constants.xi¶
trigonometry.xi¶
fn sin(x: Float64) -> Float64¶
Sine of x (radians). NaN/infinite inputs propagate. Complexity: O(1).
- Postcondition:
((result >= -1) && (result <= 1)) || (result != result)
fn cos(x: Float64) -> Float64¶
Cosine of x (radians). Complexity: O(1).
- Postcondition:
((result >= -1) && (result <= 1)) || (result != result)
fn tan(x: Float64) -> Float64¶
Tangent of x (radians); a pole (cos(x) == 0) yields +-infinity. Complexity: O(1).
- Postcondition:
(x != 0) || (result == 0) - Postcondition:
((x == x) && (x != 1 / 0) && (x != -1 / 0)) || (result != result)
fn csc(x: Float64) -> Float64¶
Cosecant of x: 1/sin(x); a zero sine yields +inf (documented). Complexity: O(1).
- Postcondition:
((result <= -1) || (result >= 1)) || (result != result)
fn sec(x: Float64) -> Float64¶
Secant of x: 1/cos(x); a zero cosine yields +inf (documented). Complexity: O(1).
- Postcondition:
((result <= -1) || (result >= 1)) || (result != result)
fn cot(x: Float64) -> Float64¶
Cotangent of x: cos(x)/sin(x); a zero sine yields +inf (documented). Complexity: O(1).
- Postcondition:
(x != 0) || (result == 1 / 0) - Postcondition:
((x == x) && (x != 1 / 0) && (x != -1 / 0)) || (result != result)
fn sincos(x: Float64) -> (Float64, Float64)¶
Pair (sin(x), cos(x)) computed once. Complexity: O(1).
- Postcondition:
(((result._0 >= -1) && (result._0 <= 1)) || (result._0 != result._0)) && (((result._1 >= -1) && (result._1 <= 1)) || (result._1 != result._1))
fn sincospi(x: Float64) -> (Float64, Float64)¶
Pair (sin(pix), cos(pix)). Complexity: O(1).
- Postcondition:
(((result._0 >= -1) && (result._0 <= 1)) || (result._0 != result._0)) && (((result._1 >= -1) && (result._1 <= 1)) || (result._1 != result._1))
fn sin_pure(x: Float64) -> Float64¶
Sine via the normalized Taylor series (no libm), 10 terms. Complexity: O(10).
- Postcondition:
(x != 0) || (result == 0) - Postcondition:
((x == x) && (x != 1 / 0) && (x != -1 / 0)) || (result != result)
fn cos_pure(x: Float64) -> Float64¶
Cosine via the normalized Taylor series (no libm), 10 terms. Complexity: O(10).
- Postcondition:
(x != 0) || (result == 1) - Postcondition:
((x == x) && (x != 1 / 0) && (x != -1 / 0)) || (result != result)
fn tan_pure(x: Float64) -> Float64¶
Tangent via pure sin/cos. Complexity: O(10).
- Postcondition:
(x != 0) || (result == 0) - Postcondition:
((x == x) && (x != 1 / 0) && (x != -1 / 0)) || (result != result)
fn sinpi(x: Float64) -> Float64¶
sin(pi*x): x is reduced into [0, 2) with a linear loop, then the sine is evaluated on the reduced angle. NaN and infinite inputs return NaN (the reduction cannot terminate on infinities). Complexity: O(|x|).
- Postcondition:
((result >= -1) && (result <= 1)) || (result != result)
fn cospi(x: Float64) -> Float64¶
cos(pi*x): x is reduced into [0, 2) with a linear loop, then the cosine is evaluated on the reduced angle. NaN and infinite inputs return NaN (the reduction cannot terminate on infinities). Complexity: O(|x|).
- Postcondition:
((result >= -1) && (result <= 1)) || (result != result)
fn tanpi(x: Float64) -> Float64¶
tan(pi*x): x is reduced into [0, 2) with a linear loop, then the tangent is evaluated on the reduced angle. NaN and infinite inputs return NaN (the reduction cannot terminate on infinities); a pole yields +-infinity. Complexity: O(|x|).
- Postcondition:
(x != 0) || (result == 0) - Postcondition:
((x == x) && (x != 1 / 0) && (x != -1 / 0)) || (result != result)
vectors.xi¶
type Vec2¶
2-component vector (x, y).
| Field | Type |
|---|---|
x |
Float64 |
y |
Float64 |
type Vec3¶
3-component vector (x, y, z).
| Field | Type |
|---|---|
x |
Float64 |
y |
Float64 |
z |
Float64 |
type Vec4¶
4-component vector (x, y, z, w).
| Field | Type |
|---|---|
x |
Float64 |
y |
Float64 |
z |
Float64 |
w |
Float64 |
fn vec2_new(x: Float64, y: Float64) -> Vec2¶
Construct a 2D vector. O(1).
- Postcondition:
((result.x == x) || (result.x != result.x)) && ((result.y == y) || (result.y != result.y))
fn vec2_add(a: Vec2, b: Vec2) -> Vec2¶
Component-wise addition of two 2D vectors. O(1).
- Postcondition:
((result.x == a.x + b.x) || (result.x != result.x)) && ((result.y == a.y + b.y) || (result.y != result.y))
fn vec2_sub(a: Vec2, b: Vec2) -> Vec2¶
Component-wise subtraction (a - b) of two 2D vectors. O(1).
- Postcondition:
((result.x == a.x - b.x) || (result.x != result.x)) && ((result.y == a.y - b.y) || (result.y != result.y))
fn vec2_scale(v: Vec2, s: Float64) -> Vec2¶
Multiply each component of a 2D vector by scalar s. O(1).
- Postcondition:
((result.x == v.x * s) || (result.x != result.x)) && ((result.y == v.y * s) || (result.y != result.y))
fn vec2_dot(a: Vec2, b: Vec2) -> Float64¶
Dot product of two 2D vectors. O(1).
- Postcondition:
(result == a.x * b.x + a.y * b.y) || (result != result)
fn vec2_len(v: Vec2) -> Float64¶
Euclidean length of a 2D vector. Overflow-safe via math.roots.hypot. O(1).
- Postcondition:
(result >= 0) || (result != result)
fn vec2_norm(v: Vec2) -> Vec2¶
Unit vector of a 2D vector. Returns the zero vector when the length is zero (documented). O(1).
- Postcondition:
(((result.x == 0) && (result.y == 0)) || ((result.x * result.x + result.y * result.y - 1) <= 0.000000000001)) || (result.x != result.x) || (result.y != result.y)
fn vec2_dist(a: Vec2, b: Vec2) -> Float64¶
Euclidean distance between two 2D points. O(1).
- Postcondition:
(result >= 0) || (result != result)
fn vec2_lerp(a: Vec2, b: Vec2, t: Float64) -> Vec2¶
Component-wise linear interpolation between a and b by t (t outside [0, 1] extrapolates; t is not clamped). O(1).
- Postcondition:
((result.x == a.x + (b.x - a.x) * t) || (result.x != result.x)) && ((result.y == a.y + (b.y - a.y) * t) || (result.y != result.y))
fn vec3_new(x: Float64, y: Float64, z: Float64) -> Vec3¶
Construct a 3D vector. O(1).
- Postcondition:
(((result.x == x) || (result.x != result.x)) && ((result.y == y) || (result.y != result.y))) && ((result.z == z) || (result.z != result.z))
fn vec3_add(a: Vec3, b: Vec3) -> Vec3¶
Component-wise addition of two 3D vectors. O(1).
- Postcondition:
(((result.x == a.x + b.x) || (result.x != result.x)) && ((result.y == a.y + b.y) || (result.y != result.y))) && ((result.z == a.z + b.z) || (result.z != result.z))
fn vec3_sub(a: Vec3, b: Vec3) -> Vec3¶
Component-wise subtraction (a - b) of two 3D vectors. O(1).
- Postcondition:
(((result.x == a.x - b.x) || (result.x != result.x)) && ((result.y == a.y - b.y) || (result.y != result.y))) && ((result.z == a.z - b.z) || (result.z != result.z))
fn vec3_scale(v: Vec3, s: Float64) -> Vec3¶
Multiply each component of a 3D vector by scalar s. O(1).
- Postcondition:
(((result.x == v.x * s) || (result.x != result.x)) && ((result.y == v.y * s) || (result.y != result.y))) && ((result.z == v.z * s) || (result.z != result.z))
fn vec3_dot(a: Vec3, b: Vec3) -> Float64¶
Dot product of two 3D vectors. O(1).
- Postcondition:
(result == a.x * b.x + a.y * b.y + a.z * b.z) || (result != result)
fn vec3_cross(a: Vec3, b: Vec3) -> Vec3¶
Right-handed cross product a x b of two 3D vectors. O(1).
- Postcondition:
(((result.x == a.y * b.z - a.z * b.y) || (result.x != result.x)) && ((result.y == a.z * b.x - a.x * b.z) || (result.y != result.y))) && ((result.z == a.x * b.y - a.y * b.x) || (result.z != result.z))
fn vec3_len(v: Vec3) -> Float64¶
Euclidean length of a 3D vector. Overflow-safe via math.roots.hypot3. O(1).
- Postcondition:
(result >= 0) || (result != result)
fn vec3_norm(v: Vec3) -> Vec3¶
Unit vector of a 3D vector. Returns the zero vector when the length is zero (documented). O(1).
- Postcondition:
((((result.x == 0) && (result.y == 0) && (result.z == 0)) || ((result.x * result.x + result.y * result.y + result.z * result.z - 1) <= 0.000000000001)) || (result.x != result.x)) || (result.y != result.y) || (result.z != result.z)
fn vec4_new(x: Float64, y: Float64, z: Float64, w: Float64) -> Vec4¶
Construct a 4D vector. O(1).
- Postcondition:
((((result.x == x) || (result.x != result.x)) && ((result.y == y) || (result.y != result.y))) && ((result.z == z) || (result.z != result.z))) && ((result.w == w) || (result.w != result.w))
fn vec4_add(a: Vec4, b: Vec4) -> Vec4¶
Component-wise addition of two 4D vectors. O(1).
- Postcondition:
((((result.x == a.x + b.x) || (result.x != result.x)) && ((result.y == a.y + b.y) || (result.y != result.y))) && ((result.z == a.z + b.z) || (result.z != result.z))) && ((result.w == a.w + b.w) || (result.w != result.w))
fn vec4_sub(a: Vec4, b: Vec4) -> Vec4¶
Component-wise subtraction (a - b) of two 4D vectors. O(1).
- Postcondition:
((((result.x == a.x - b.x) || (result.x != result.x)) && ((result.y == a.y - b.y) || (result.y != result.y))) && ((result.z == a.z - b.z) || (result.z != result.z))) && ((result.w == a.w - b.w) || (result.w != result.w))
fn vec4_scale(v: Vec4, s: Float64) -> Vec4¶
Multiply each component of a 4D vector by scalar s. O(1).
- Postcondition:
((((result.x == v.x * s) || (result.x != result.x)) && ((result.y == v.y * s) || (result.y != result.y))) && ((result.z == v.z * s) || (result.z != result.z))) && ((result.w == v.w * s) || (result.w != result.w))
fn vec4_dot(a: Vec4, b: Vec4) -> Float64¶
Dot product of two 4D vectors. O(1).
- Postcondition:
(result == a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w) || (result != result)
fn vec4_len(v: Vec4) -> Float64¶
Euclidean length of a 4D vector: sqrt(sum of squared components). O(4).
- Postcondition:
(result >= 0) || (result != result)
fn vec4_norm(v: Vec4) -> Vec4¶
Unit vector of a 4D vector. Returns the zero vector when the length is zero (documented). O(4).
- Postcondition:
(((((result.x == 0) && (result.y == 0) && (result.z == 0) && (result.w == 0)) || ((result.x * result.x + result.y * result.y + result.z * result.z + result.w * result.w - 1) <= 0.000000000001)) || (result.x != result.x)) || (result.y != result.y) || (result.z != result.z)) || (result.w != result.w)
fn vec_dot(a: &Vec[Float64], b: &Vec[Float64]) -> Float64¶
Dot product of two equal-length dynamic vectors. Returns NaN (0.0/0.0) when the vectors differ in length (documented; no silent garbage). O(n).
- Postcondition:
(a.len() == b.len()) || (result != result)
fn vec_norm(v: &Vec[Float64]) -> Float64¶
Euclidean length of a dynamic vector. O(n).
- Postcondition:
(result >= 0) || (result != result)
fn vec_scale(v: &Vec[Float64], s: Float64) -> Vec[Float64]¶
Multiply each component of v by scalar s, returning a new vector. O(n).
- Postcondition:
result.len() == v.len()