tang mascot

tang.

differentiable computing in Rust.

GitHub quick mafs
no_std WASM GPU
Dual<f64> f(x) = x · sin(x)
x = 0.00
val = 0.00
dual = 0.00

Evaluating f(x) = x·sin(x) with Dual<f64> computes the value and exact derivative in a single pass — no finite differences, no symbolic engine. The green tangent line is the dual field: the slope, computed exactly for free.

this is actually Rust code running in your browser!
tang-train The Quantum Poet
// build the model
let mut model = Sequential::<f64>::new(vec![
    Box::new(Linear::new(240, 64, 42)),
    Box::new(Tanh::new()),
    Box::new(Linear::new(64, 64, 137)),
    Box::new(Tanh::new()),
    Box::new(Linear::new(64, 30, 256)),
]);

// train
let losses = Trainer::new(&mut model, ModuleAdam::new(0.005))
    .loss_fn(|p, t| (cross_entropy_loss(p, t), cross_entropy_loss_grad(p, t)))
    .epochs(200)
    .fit(&mut loader);
click Train to start...

The Scalar trick.

Write your math once with S: Scalar. Swap the type to change what it does.

Compute
fn spring_energy<S: Scalar>(
    k: S, x: S
) -> S {
    k * x * x * S::from_f64(0.5)
}

spring_energy(10.0_f64, 0.3)
// → 0.45
Differentiate
// same function, different type
let x = Dual::var(0.3);

spring_energy(10.0.into(), x)
// → Dual {
//     val:  0.45,  // energy
//     dual: 3.0,   // ∂E/∂x = kx
// }

Crates.

Use only what you need.

Benchmarks.

Apple M-series, single-threaded. cargo bench -p tang-bench

view benchmark source →

Geometry & physics primitives (f64 unless noted)
tang nalgebra
source →

nalgebra → tang.

Drop-in aliases. Minimal call-site changes.

nalgebra tang
Vector3<f64>Vec3<f64>
Point3<f64>Point3<f64>
Unit<Vector3>Dir3<f64>
Matrix4<f64>Mat4<f64>
UnitQuaternionQuat<f64>
DVector<f64>DVec<f64>
DMatrix<f64>DMat<f64>