viva_math/common
Common mathematical utilities for VIVA.
Functions not found in gleam_community_maths:
- clamp, lerp, sigmoid, softmax, safe_div
Values
pub fn clamp(value: Float, min: Float, max: Float) -> Float
Clamp a value to a range [min, max].
Examples
clamp(5.0, 0.0, 10.0) // -> 5.0
clamp(-1.0, 0.0, 10.0) // -> 0.0
clamp(15.0, 0.0, 10.0) // -> 10.0
pub fn clamp_bipolar(value: Float) -> Float
Clamp a value to the bipolar interval [-1, 1]. Used for PAD dimensions.
Examples
clamp_bipolar(0.5) // -> 0.5
clamp_bipolar(-1.5) // -> -1.0
clamp_bipolar(1.5) // -> 1.0
pub fn clamp_unit(value: Float) -> Float
Clamp a value to the unit interval [0, 1].
Examples
clamp_unit(0.5) // -> 0.5
clamp_unit(-0.5) // -> 0.0
clamp_unit(1.5) // -> 1.0
pub fn deterministic_noise(step: Int, seed: Int) -> Float
Deterministic pseudo-random noise generator. Uses hash-based seeding for reproducibility (no external RNG needed).
Returns value in [-1, 1] range.
Examples
deterministic_noise(0, 42) // -> some value in [-1, 1]
deterministic_noise(0, 42) // -> same value (deterministic)
pub fn exponential_decay(
value: Float,
rate: Float,
time: Float,
) -> Float
Exponential decay: value * exp(-rate * time)
Examples
exponential_decay(1.0, 0.5, 1.0) // -> ~0.606
exponential_decay(1.0, 0.0, 10.0) // -> 1.0 (no decay)
pub fn inverse_decay(
base_rate: Float,
t: Float,
tau: Float,
) -> Float
Inverse decay rate (pattern from viva_glyph/association.gleam). η(t) = η₀ / (1 + t/τ)
Used for learning rate decay, consolidation, etc.
pub fn inverse_lerp(
a: Float,
b: Float,
value: Float,
) -> Result(Float, Nil)
Inverse linear interpolation - find t given value in range [a, b].
Examples
inverse_lerp(0.0, 10.0, 5.0) // -> Ok(0.5)
inverse_lerp(0.0, 10.0, 2.5) // -> Ok(0.25)
inverse_lerp(0.0, 0.0, 5.0) // -> Error(Nil) (division by zero)
pub fn inverse_sqrt_decay(
base_rate: Float,
t: Float,
tau: Float,
) -> Float
Inverse square root decay. η(t) = η₀ / √(1 + t/τ)
pub fn lerp(a: Float, b: Float, t: Float) -> Float
Linear interpolation between two values.
lerp(a, b, 0.0) = a lerp(a, b, 1.0) = b lerp(a, b, 0.5) = (a + b) / 2
Examples
lerp(0.0, 10.0, 0.5) // -> 5.0
lerp(0.0, 10.0, 0.25) // -> 2.5
pub fn safe_div(a: Float, b: Float, default: Float) -> Float
Safe division with default value on division by zero.
Examples
safe_div(10.0, 2.0, 0.0) // -> 5.0
safe_div(10.0, 0.0, -1.0) // -> -1.0
pub fn sigmoid(x: Float, k: Float) -> Float
Sigmoid function: 1 / (1 + exp(-k * x))
Maps any real number to (0, 1). k controls steepness (k=1 is standard sigmoid).
Examples
sigmoid(0.0, 1.0) // -> 0.5
sigmoid(100.0, 1.0) // -> ~1.0
sigmoid(-100.0, 1.0) // -> ~0.0
pub fn smoothstep(edge0: Float, edge1: Float, x: Float) -> Float
Smooth step function (Hermite interpolation). Returns 0 if x < edge0, 1 if x > edge1, smooth transition otherwise.
Examples
smoothstep(0.0, 1.0, 0.5) // -> 0.5 (roughly)
smoothstep(0.0, 1.0, 0.0) // -> 0.0
smoothstep(0.0, 1.0, 1.0) // -> 1.0
pub fn softmax(values: List(Float)) -> Result(List(Float), Nil)
Softmax function: converts a list of values to probabilities.
softmax([x1, x2, …]) = [exp(x1)/sum, exp(x2)/sum, …] where sum = exp(x1) + exp(x2) + …
Examples
softmax([1.0, 2.0, 3.0]) // -> [0.09, 0.24, 0.67] (approx)
softmax([0.0, 0.0]) // -> [0.5, 0.5]
pub fn wiener_increment(step: Int, seed: Int, dt: Float) -> Float
Generate Wiener process increment (discrete approximation). dW ≈ √dt × N(0,1) where N is approximated by deterministic noise.
Used for stochastic differential equations.
Parameters
- step: Current time step (for determinism)
- seed: Random seed
- dt: Time step size
Examples
wiener_increment(0, 42, 0.01) // -> small noise scaled by √dt