nufast
Three-flavor neutrino oscillation probabilities in vacuum and constant-density matter.
Implementations in Rust, Zig, and WebAssembly, based on NuFast by P.B. Denton (arXiv:2405.02400).
Overview
This repository provides implementations of the NuFast algorithm for computing neutrino oscillation probabilities. The algorithm achieves sub-microsecond performance while maintaining numerical accuracy suitable for experimental analyses.
The original NuFast is used in production by T2K (via MaCH3) and JUNO.
Implementations
| Platform | Location | Features |
|---|---|---|
| Rust | src/lib.rs |
crates.io, no_std, VacuumBatch |
| Zig | benchmarks/zig/ |
SIMD, f32 mode, MatterBatch |
| WASM | benchmarks/zig/wasm/ |
Browser, Node.js, TypeScript, batch API |
All implementations support:
- Vacuum oscillations (exact analytic)
- Matter effects via the DMP approximation with optional Newton refinement
- Anti-neutrino mode (sign-flipped δCP and matter potential)
- Batch APIs for pre-computed mixing matrices
Usage
Rust
[]
= "0.5"
use ;
use PI;
let params = VacuumParameters ;
let probs = probability_vacuum_lbl;
// probs[1][0] = P(νμ → νe)
Zig
const nufast = @import("nufast");
const params = nufast.VacuumParams.default;
const probs = nufast.vacuumProbability(params, 1300.0, 2.5);
// probs[1][0] = P(νμ → νe)
// SIMD: compute 4 energies simultaneously
const batch = nufast.VacuumBatch.init(params);
var energies: nufast.F64Vec = .{ 1.0, 2.0, 3.0, 4.0 };
const p_vec = nufast.vacuumProbabilitySimd(batch, 1300.0, energies);
WebAssembly (TypeScript)
import { loadNuFast } from '@nufast/wasm';
const nufast = await loadNuFast();
const Pme = nufast.vacuumPmeDefault(1300, 2.5);
console.log(`P(νμ → νe) = ${(Pme * 100).toFixed(2)}%`);
// Batch mode (2× faster)
const energies = new Float64Array([0.5, 1.0, 1.5, 2.0, 2.5]);
nufast.initVacuumBatch();
const results = nufast.vacuumBatchPme(1300, energies);
Benchmarks
AMD Ryzen, WSL2, 10M iterations per measurement.
Scalar Performance
| Implementation | Vacuum | Matter (N=0) |
|---|---|---|
| Zig | 42 ns | 108 ns |
| Rust | 61 ns | 95 ns |
| C++ (original) | 49 ns | 130 ns |
| Fortran (original) | 51 ns | 107 ns |
| Python (original) | 14.7 µs | 21.9 µs |
Zig SIMD
| Mode | f64 (4 lanes) | f32 (8 lanes) |
|---|---|---|
| Vacuum | 44 ns/calc | 21 ns/calc |
| Matter | 56 ns/calc | 37 ns/calc |
Throughput with f32 SIMD: ~48M vacuum/sec, ~27M matter/sec.
WebAssembly
| Mode | Single-point | Batch (1000) |
|---|---|---|
| Vacuum | ~100 ns | ~50 ns/point |
| Matter | ~150 ns | ~110 ns/point |
Batch mode gives 2× speedup by amortizing JS↔WASM overhead.
Physics
The probability matrix probs[α][β] gives P(ν_α → ν_β):
e μ τ
┌───────────────────────┐
e │ P_ee P_eμ P_eτ │
μ │ P_μe P_μμ P_μτ │
τ │ P_τe P_τμ P_ττ │
└───────────────────────┘
Default parameters use NuFit 5.2 (2022) best-fit values for normal ordering.
For anti-neutrinos, set antineutrino = true. This flips the sign of δCP and the matter potential.
The N_Newton parameter controls matter eigenvalue accuracy:
- 0: DMP approximation (~0.1% accuracy)
- 1: One Newton iteration (~0.01%)
- ≥2: Machine precision
Repository Structure
src/ Rust implementation
benchmarks/
zig/ Zig implementation + WASM
src/ Core physics + WASM exports
wasm/ WASM binaries, TypeScript, npm package
cpp/ C++ (original NuFast)
fortran/ Fortran (original NuFast)
python/ Python (original NuFast)
paper/ Benchmark methodology and results
Building WASM
# Build WASM (baseline + SIMD)
# Copy to wasm/ directory
# Test
&&
References
- P.B. Denton, arXiv:2405.02400 (2024)
- NuFast — original implementations
- NuFit 5.2 (2022)
License
MIT