viva_math/autodiff

Forward-mode automatic differentiation via dual numbers.

A dual number a + b·ε (where ε² = 0) carries both a value and an infinitesimal derivative. Applying f to a Dual(x, 1) yields Dual(f(x), f'(x))exact gradients without symbolic manipulation or finite-difference truncation error.

When to use

For Vec3 gradients (gradient of a scalar field over PAD space), use Dual3 which carries three partials in parallel.

Example

import viva_math/autodiff as ad

// f(x) = sin(x²)
let x = ad.var(2.0)
let result = ad.sin(ad.mul(x, x))
// result.value ≈ sin(4) ≈ -0.756
// result.tangent = 2x · cos(x²) ≈ -2.614

References

Types

A dual number value + tangent·ε.

value carries the function evaluation; tangent carries the directional derivative w.r.t. the independent variable.

pub type Dual {
  Dual(value: Float, tangent: Float)
}

Constructors

  • Dual(value: Float, tangent: Float)

A dual number carrying three parallel partials. Use this to compute the gradient ∇f of a scalar field f: ℝ³ → ℝ at a point in one evaluation.

pub type Dual3 {
  Dual3(
    value: Float,
    partial_x: Float,
    partial_y: Float,
    partial_z: Float,
  )
}

Constructors

  • Dual3(
      value: Float,
      partial_x: Float,
      partial_y: Float,
      partial_z: Float,
    )

Values

pub fn add(a: Dual, b: Dual) -> Dual
pub fn add3(a: Dual3, b: Dual3) -> Dual3
pub fn add_scalar(a: Dual, s: Float) -> Dual
pub fn const3(value: Float) -> Dual3

Treat value as a constant: all partials = 0.

pub fn constant(value: Float) -> Dual

Constant dual: tangent = 0.

pub fn cos(a: Dual) -> Dual
pub fn div(a: Dual, b: Dual) -> Dual
pub fn exp(a: Dual) -> Dual
pub fn exp3(a: Dual3) -> Dual3
pub fn gelu(a: Dual) -> Dual
pub fn grad(f: fn(Dual) -> Dual, x: Float) -> Float

Compute f’(x) at a point by lifting x to a dual.

pub fn gradient3(
  f: fn(Dual3, Dual3, Dual3) -> Dual3,
  x: Float,
  y: Float,
  z: Float,
) -> #(Float, Float, Float)

Gradient ∇f at point (x, y, z).

pub fn jacobian(
  f: fn(List(Dual)) -> List(Dual),
  point: List(Float),
) -> List(List(Float))

Generic n-d Jacobian via column-by-column forward AD. Given a function f: ℝⁿ → ℝᵐ represented as fn(Dual, ..., Dual) -> List(Dual), returns each row of the Jacobian by sweeping the unit tangent through each input.

This is the canonical forward-mode strategy: O(n) evaluations of f for a full Jacobian, optimal when n ≤ m.

pub fn lift1(
  d: Dual,
  f: fn(Float) -> Float,
  df: fn(Float) -> Float,
) -> Dual

Lift any unary function f together with its derivative f' to a dual.

pub fn ln(a: Dual) -> Dual
pub fn mul(a: Dual, b: Dual) -> Dual
pub fn mul3(a: Dual3, b: Dual3) -> Dual3
pub fn neg(a: Dual) -> Dual
pub fn pow(a: Dual, n: Float) -> Dual
pub fn relu(a: Dual) -> Dual
pub fn scale(a: Dual, s: Float) -> Dual
pub fn sigmoid(a: Dual) -> Dual
pub fn sin(a: Dual) -> Dual
pub fn sqrt(a: Dual) -> Dual
pub fn sub(a: Dual, b: Dual) -> Dual
pub fn tanh(a: Dual) -> Dual
pub fn value_and_grad(
  f: fn(Dual) -> Dual,
  x: Float,
) -> #(Float, Float)

Compute both f(x) and f’(x) in a single pass.

pub fn var(value: Float) -> Dual

A dual number representing an independent variable. var(x)x + 1·ε so that ∂x/∂x = 1.

pub fn var3_x(value: Float) -> Dual3

The independent variable x: ∂x/∂x = 1, others = 0.

pub fn var3_y(value: Float) -> Dual3
pub fn var3_z(value: Float) -> Dual3
Search Document