Introduction
JMax — JMax — math-native programming language. 2,502 scientific computing functions on the flowG substrate.
This is the official documentation for JMax. The full source code lives in the private -core mirror; the public release surface is at openIE-dev/jmax.
What you'll find here
- Install — get the
jmaxbinary on your machine - Hello, JMax — first program in 30 seconds
- Tutorial — a 30-minute hands-on guided tour
- Reference — every feature, every flag, every API
- Cookbook — task-oriented recipes
- Design — why JMax exists and how it fits with the rest of openIE-dev
The openIE-dev ecosystem
JMax is one of five public openIE-dev projects. All five share a common substrate (flowG) and energy-metering layer (substrate-energy):
- flow-g — the IR + runtime substrate
- lux-lang — reactive language compiling to flowG
- jmax — math-native language
- joule-lang — energy-budgeted compiled language
- jouledb — energy-metered database
License
JMax binaries are distributed under BSL-1.1. Documentation under CC-BY-4.0. Examples under Apache-2.0.
Install
JMax ships as a self-contained prebuilt binary: no toolchain, no compile step. The quickest path on macOS and Linux is Homebrew; otherwise grab the archive for your platform from the latest GitHub Release. Assets are named jmax-<version>-<target>.tar.gz (.zip on Windows), each with a .sha256 checksum.
Homebrew (macOS / Linux)
brew install openie-dev/jmax/jmax
jmax --version
Download (macOS / Linux)
# Pick your target (see the list below); this example is Apple silicon.
V=0.1.2
T=aarch64-apple-darwin
curl -fsSL "https://github.com/openIE-dev/jmax/releases/download/v$V/jmax-$V-$T.tar.gz" | tar xz
sudo mv "jmax-$V-$T/jmax" /usr/local/bin/
jmax --version
Targets:
| Platform | <target> |
|---|---|
| macOS (Apple silicon) | aarch64-apple-darwin |
| macOS (Intel) | x86_64-apple-darwin |
| Linux x86-64 | x86_64-unknown-linux-gnu |
| Linux arm64 | aarch64-unknown-linux-gnu |
| Windows x86-64 | x86_64-pc-windows-msvc (.zip) |
Windows
Download the x86_64-pc-windows-msvc .zip from the Releases page, unzip it, and put jmax.exe somewhere on your PATH.
No install: run it in your browser
play.charlot-lang.dev runs the JMax evaluator compiled to WebAssembly. Nothing leaves the page.
Verify
jmax --version
Hello, JMax
The smallest useful program: solve a linear system, look at the matrix's spectrum, and return its determinant.
fn main() -> float:
let A = [[2.0, 1.0], [1.0, 3.0]]
let b = [5.0, 10.0]
let x = A \ b # solve A x = b → [1, 3]
let eigenvalues = eig(A) # symmetric eigenvalues
det(A) # the program's result → 5.0
Run it:
jmax run hello.jmax
# → 5.0
Or evaluate an expression directly, no file:
jmax eval "det([[2,1],[1,3]])" # → 5
Or open a REPL:
jmax repl
No imports, no project scaffold, no numerics package to install — A \ b and
eig and det are part of the language.
Prefer not to install? The same program runs in your browser at play.charlot-lang.dev.
For the full walkthrough — calculus, optimization, fitting, and plotting — see
the tutorial. The complete example sources are in
examples/.
Tutorial
A hands-on tour of JMax — from a one-line expression to a fitted model with a plot. Everything here runs in the browser playground if you'd rather not install anything yet.
1. Evaluate an expression
JMax is math-native: matrices, vectors, and scalars are first-class values, and the operators mean what they do in mathematics.
jmax eval "[[2,1],[1,3]] \ [5,10]"
# → [1, 3] (solves the linear system A x = b)
\ is the solve operator, * multiplies matrices, and ' transposes. No
imports, no setup.
2. Write a program
Put a computation in a .jmax file. The last expression is the result.
fn main() -> float:
let A = [[2.0, 1.0], [1.0, 3.0]]
let b = [5.0, 10.0]
let x = A \ b
let eigenvalues = eig(A)
det(A)
jmax run model.jmax
# → 5.0 (det of A; energy-receipted)
3. Differentiate and optimize — exactly
JMax does both symbolic calculus and automatic differentiation, and feeds them into solvers.
jmax eval "integrate(x^2, x)" # → x^3/3 (symbolic)
jmax grad "x^2*y + sin(x)" 1.3 0.7 # reverse-mode AD gradient
jmax minimize "(1-x)^2 + 100*(y-x^2)^2" -1.2 1 --newton # Rosenbrock → (1, 1)
4. Fit data and plot
Plots are statements, not a separate library.
fn main():
let xs = linspace(0.0, 10.0, 100)
let ys = map(xs, \x -> sin(x) * exp(-0.1 * x))
plot line xs, ys, title="damped sine", xlabel="t", ylabel="amplitude"
jmax plot signal.jmax # writes an SVG (and opens it)
Curve fitting is one command:
jmax fit "a*exp(b*x)" data.csv --p0 1,0 # Levenberg–Marquardt, AD Jacobian
5. Measure the energy
Every workload can report a measured energy receipt in joules — the same number the browser sandbox models as wall-clock time. Energy is a first-class observable in JMax, not an afterthought.
Where to go next
- The full built-in function reference — 113 functions.
- The
jmaxcommand line — every subcommand. - The cookbook — task-oriented recipes.
- Runnable code in
examples/.
Reference
The complete JMax surface, in three parts. Everything here also lives on the website — these pages mirror charlot-lang.dev.
- Built-in functions — 113 functions across 15 domains (linear algebra, statistics, signal processing, ML, symbolic math, calculus & autodiff, optimization, ODEs, hypothesis tests, dataframes, units, and plotting). The same set is browsable at docs.charlot-lang.dev.
- The
jmaxcommand line — one binary across the whole scientific-computing surface:eval,run,plot,grad,minimize,ode,fit,verify, andemitto ONNX / StableHLO / WGSL / MLIR. Mirrors api.charlot-lang.dev. - Library crates — embed JMax directly from Rust; pure Rust, no Python or C++ dependencies.
Try it without installing
Every built-in runs in the browser at play.charlot-lang.dev — the JMax evaluator compiled to WebAssembly. Nothing leaves the page.
Embedding API
For the Rust embedding API (types, traits, and per-crate items), see docs.rs/jmax.
Built-in functions
Every function below is built into the jmax binary — no packages to
install. They run identically in the browser playground,
the CLI, and the Rust library. This page mirrors
docs.charlot-lang.dev.
Linear Algebra
| Signature | Description |
|---|---|
A * B | Matrix multiply. Use * operator on matrices. |
A \ b | Solve linear system Ax = b. NxN via LU decomposition. |
eig(A) | Eigenvalues of a symmetric matrix via QR algorithm. |
svd(A) | Singular values via eigendecomposition of A'A. |
qr(A) | QR decomposition via Gram-Schmidt. |
cholesky(A) | Cholesky decomposition. A must be symmetric positive definite. |
inv(A) | Matrix inverse via Gauss-Jordan elimination. |
det(A) | Determinant via LU decomposition. |
trace(A) | Sum of diagonal elements. |
rank(A) | Matrix rank via SVD. |
A' | Matrix transpose. Use postfix apostrophe. |
eye(n) | Identity matrix. |
zeros(m, n) | Zero matrix. |
ones(m, n) | All-ones matrix. |
linspace(start, end, n) | N evenly spaced values. |
Statistics
| Signature | Description |
|---|---|
mean(data) | Arithmetic mean. |
std(data) | Standard deviation (sample). |
var(data) | Variance (sample). |
median(data) | Median value. |
percentile(data, p) | P-th percentile (0-1). |
correlation(x, y) | Pearson correlation coefficient. |
covariance(x, y) | Sample covariance. |
t_test(a, b) | Welch's two-sample t-test. Returns p-value. |
chi_squared(observed, expected) | Chi-squared test statistic. |
linear_regression(x, y) | OLS. Returns [intercept, slope, r_squared]. |
normal_cdf(x) | Standard normal CDF. |
normal_pdf(x) | Standard normal PDF. |
Signal Processing
| Signature | Description |
|---|---|
fft(signal) | Fast Fourier Transform (Cooley-Tukey). Returns magnitude spectrum. |
ifft(spectrum) | Inverse FFT. |
convolve(a, b) | Linear convolution. |
fir_filter(signal, coeffs) | FIR filter. |
spectrogram(signal, win, hop) | STFT magnitude spectrogram. |
hann(n) | Hann window of length n. |
hamming(n) | Hamming window of length n. |
blackman(n) | Blackman window of length n. |
Machine Learning
| Signature | Description |
|---|---|
relu(x) | Rectified linear unit. max(0, x). |
sigmoid(x) | 1 / (1 + exp(-x)). |
tanh_act(x) | Hyperbolic tangent activation. |
gelu(x) | Gaussian error linear unit. |
swish(x) | x * sigmoid(x). |
softmax(logits) | Softmax over a vector. Numerically stable. |
cross_entropy(pred, target) | Cross-entropy loss. |
mse_loss(pred, target) | Mean squared error loss. |
accuracy(pred, target) | Classification accuracy. |
Symbolic Math
| Signature | Description |
|---|---|
sin(x) | Sine. |
cos(x) | Cosine. |
tan(x) | Tangent. |
asin(x) | Arcsine. |
acos(x) | Arccosine. |
exp(x) | e^x. |
log(x) | Natural logarithm. |
log2(x) | Base-2 logarithm. |
log10(x) | Base-10 logarithm. |
sqrt(x) | Square root. |
abs(x) | Absolute value. |
floor(x) | Floor. |
ceil(x) | Ceiling. |
round(x) | Round to nearest integer. |
Finance
| Signature | Description |
|---|---|
black_scholes_call(S, K) | Black-Scholes call option price. T=1yr, r=5%, sigma=20%. |
black_scholes_put(S, K) | Black-Scholes put option price. |
sma(data, window) | Simple moving average. |
ema(data, span) | Exponential moving average. |
sharpe(returns, risk_free) | Sharpe ratio. |
max_drawdown(prices) | Maximum drawdown. |
npv(rate, cash_flows) | Net present value. |
irr(cash_flows) | Internal rate of return. |
Bioinformatics
| Signature | Description |
|---|---|
smith_waterman(seq1, seq2) | Local alignment score. |
needleman_wunsch(seq1, seq2) | Global alignment score. |
gc_content(seq) | GC content ratio (0-1). |
reverse_complement(seq) | DNA reverse complement. |
translate_dna(seq) | Translate DNA to protein. |
Data Analysis
| Signature | Description |
|---|---|
sort(data) | Sort a vector ascending. |
unique(data) | Remove duplicates. |
cumsum(data) | Cumulative sum. |
diff(data) | First differences. |
len(data) | Length of a vector or array. |
Visualization
| Signature | Description |
|---|---|
plot line data | Line chart. |
plot scatter data | Scatter plot. |
plot bar data | Bar chart. |
plot histogram data | Histogram with automatic binning. |
plot heatmap matrix | Heatmap with Viridis colormap. |
plot surface matrix | 3D surface plot. |
plot contour matrix | Contour plot with marching squares. |
plot boxplot data | Box-and-whisker plot. |
plot violin data | Violin plot with KDE. |
plot radar data | Radar/spider chart. |
Calculus & Autodiff
| Signature | Description |
|---|---|
d/dx(f) | Exact symbolic differentiation. |
integrate(f, x) | Rule-based symbolic integration (linearity, power rule, standard functions). |
expand(e) | Distribute products and expand integer powers of sums. |
simplify(e) | Canonical simplification via equality-saturation (e-graph). |
solve(expr, x) | Solve polynomial equations exactly (linear, quadratic). |
grad(f, point) | Gradient by reverse-mode automatic differentiation. |
hessian(f, point) | Full Hessian by second-order AD. |
Optimization
| Signature | Description |
|---|---|
minimize(f, x0) | Unconstrained minimization — gradient descent or Newton (AD Hessian). |
root(f, x0) | Find a root by Newton's method (AD derivative). |
fit(model, data) | Levenberg-Marquardt nonlinear least-squares curve fitting. |
lp(c, A, b) | Linear program by two-phase simplex (Bland anti-cycling). |
qp(G, a, C, d) | Quadratic program — equality (KKT) or inequality (active-set). |
Differential Equations
| Signature | Description |
|---|---|
ode("dy/dt", y0) | Adaptive Dormand-Prince RK45 integrator. |
ode(…, --stiff) | Implicit backward-Euler for stiff systems; Jacobian via AD. |
Hypothesis Tests
| Signature | Description |
|---|---|
anova(g1, g2, …) | One-way ANOVA F-test for equal group means. |
wilcoxon(a, b) | Wilcoxon signed-rank test (paired, nonparametric). |
mann_whitney(a, b) | Mann-Whitney U test (independent samples). |
levene(g1, g2, …) | Levene/Brown-Forsythe test for equal variances. |
friedman(blocks) | Friedman repeated-measures test. |
ks_two_sample(a, b) | Two-sample Kolmogorov-Smirnov test. |
Dataframes
| Signature | Description |
|---|---|
df file.csv | Typed columnar dataframe from CSV (with type inference). |
groupby(key, value, op) | Group-by aggregation: sum, mean, count, min, max. |
pivot(index, cols, value) | Pivot table. |
join(other, on) | Inner, left, or outer join. |
--to-parquet out | Write real Parquet (validated against Apache Arrow). |
Units
| Signature | Description |
|---|---|
convert(v, from, to) | Dimensional unit conversion with compound units and metric prefixes. |
Quantity{value, dim} | Dimension-tracked arithmetic (SI base dimensions). |
The jmax command line
One binary spans the whole scientific-computing surface — symbolic math, automatic differentiation, optimization, differential equations, linear algebra, signal processing, statistics, dataframes, and units. Every command below is real and runs today. This page mirrors api.charlot-lang.dev.
All commands
jmax exposes 83 subcommands spanning symbolic math, numerics, simulation, statistics, and visualization — the whole surface of a MATLAB/NumPy/SciPy-class tool in one binary. Run jmax <command> --help for the full options of any one.
Evaluate & run
| Command | What it does |
|---|---|
jmax run | Run a JMax source file |
jmax eval | Evaluate a single expression |
jmax plot | Run a file and export plots to SVG Plot expression(s) over [from, to] (with --from/--to), or render the plot statements in a source file |
jmax export | Export data/plots to various formats |
jmax emit | Emit the compiled flowG graph to a target IR (onnx |
jmax ingest | Ingest a foreign model format into a flowG ProgramGraph JSON (gguf |
Symbolic & verify
| Command | What it does |
|---|---|
jmax verify | Verify a symbolic identity lhs == rhs (CAS self-check + Lean proof) |
jmax dsolve | Solve an ODE symbolically: y' = |
Calculus & autodiff
| Command | What it does |
|---|---|
jmax grad | Gradient of an expression at a point, by reverse-mode autodiff. Point values bind to the variables in alphabetical order |
jmax hessian | Hessian of an expression at a point, via second-order AD |
jmax quad | Numerically integrate |
jmax quad2 | Double integral ∫∫ f(x,y) over a rectangle, by tensored adaptive Gauss-Kronrod (SciPy dblquad) |
jmax quad3 | Triple integral ∫∫∫ f(x,y,z) over a box, by tensored adaptive Gauss-Kronrod (SciPy tplquad) |
Roots & nonlinear systems
| Command | What it does |
|---|---|
jmax root | Find a root of a single-variable expression near x0 (Newton + AD) |
jmax fsolve | Solve a general nonlinear system (each eqn = 0, ';'-separated) by damped Newton — SciPy's fsolve. Handles sin/exp/etc; needs a square system |
jmax solve-system | Solve a polynomial system (each eqn = 0, ';'-separated) via Gröbner bases |
Optimization
| Command | What it does |
|---|---|
jmax minimize | Minimize an expression from a starting point (gradient descent + AD). Start values bind to the variables in alphabetical order |
jmax lsq | Nonlinear least squares: minimize ½Σrᵢ² over arbitrary residual expressions (';'-separated) — SciPy least_squares / MATLAB lsqnonlin. Handles overdetermined systems |
jmax fit | Fit a model to (x, y) data by Levenberg-Marquardt (Jacobian via AD) |
jmax lp | Solve a linear program: maximize cᵀx s.t. Ax ≤ b, x ≥ 0. File: first row = objective c; each later row = "a₁ … aₙ b" |
jmax qp | Solve a QP: min ½xᵀGx + aᵀx s.t. Cx = d (or Cx ≤ d with --ineq). File has G/a/C/d section headers, each followed by number rows |
ODEs, BVPs, SDEs
| Command | What it does |
|---|---|
jmax ode | Integrate dy/dt = |
jmax bvp | Solve a two-point boundary value problem y''=f(x,y,yp) with y(a),y(b) fixed, by shooting (RK45+Newton) — MATLAB bvp4c / SciPy solve_bvp |
jmax sde | Integrate a stochastic ODE dX = drift dt + diffusion dW over many paths |
Linear algebra — factorization & solve
| Command | What it does |
|---|---|
jmax linsolve | Solve A·x = b. A from matrix file, b from vector file |
jmax lusolve | Solve A·x = b by SPARSE DIRECT factorization: LU, or LDLᵀ/Cholesky with --spd. Exact, unlike the iterative solvers |
jmax svd | Singular values of a matrix (file: rows of numbers) |
jmax det | Determinant of a square matrix (file: rows of numbers) |
jmax rank | Numerical rank of a matrix file (via SVD) |
jmax rrqr | Rank-revealing column-pivoted QR (Businger–Golub): numerical rank + the R diagonal + column permutation |
jmax pinv | Moore-Penrose pseudoinverse of a matrix file |
jmax expm | Matrix exponential e^(A·t) — the state-transition matrix of ẋ=Ax (scaling-and-squaring + Padé). NOT the entrywise exp |
jmax sqrtm | Principal matrix square root √A (X·X = A), by the Denman–Beavers iteration |
jmax logm | Principal matrix logarithm log A (the inverse of expm), by inverse scaling-and-squaring |
Linear algebra — eigenvalues
| Command | What it does |
|---|---|
jmax eig | Eigenvalues of a symmetric matrix (file: rows of numbers) |
jmax eigvals | All eigenvalues (real + complex) of a GENERAL square matrix, by Hessenberg + Francis QR — LAPACK dgeev-class |
jmax eigs | Extreme eigenvalues of a large SYMMETRIC SPARSE matrix by Lanczos (matvec-only, no factorization) — SciPy eigsh / ARPACK |
jmax geneig | Symmetric-definite generalized eigenvalues K x = λ M x (modal analysis; K symmetric, M SPD) |
Matrices & tensors — factorization
| Command | What it does |
|---|---|
jmax nmf | Non-negative matrix factorization A ≈ W H, W,H ≥ 0 (interpretable parts; topic models / unmixing). scikit-learn NMF |
jmax lowrank | Best rank-k approximation of a matrix by truncated SVD (Eckart–Young); --report shows energy + compression |
jmax einsum | Einstein summation over matrix operands (NumPy einsum): matmul "ij,jk->ik", trace "ii->", transpose "ij->ji", etc |
Interpolation & spectral
| Command | What it does |
|---|---|
jmax interp | Interpolate (x, y) samples (spline/linear/pchip/nearest) and plot the curve |
jmax cheb | Chebyshev spectral methods: approximate |
Signal processing
| Command | What it does |
|---|---|
jmax fft | Magnitude spectrum (FFT) of a real signal read from a file |
jmax spectrogram | STFT spectrogram of a real signal: per-frame magnitude spectra |
jmax biquad | Apply a biquad IIR filter to a signal |
jmax wavelet | Discrete wavelet transform: multiresolution energy decomposition or wavelet denoising (SciPy pywt / MATLAB Wavelet Toolbox) |
Statistics & data
| Command | What it does |
|---|---|
jmax stats | Summary statistics of a data sample read from a file |
jmax sample | Sample from a distribution, e.g. sample normal 0 1 -n 5 --seed 42 |
jmax ttest | Welch two-sample t-test on two data files |
jmax wilcoxon | Wilcoxon signed-rank test on two paired data files |
jmax anova | One-way ANOVA across groups — one data file per group |
jmax friedman | Friedman test from a matrix file (rows = blocks, columns = treatments) |
jmax levene | Levene's test for equality of variances — one data file per group |
jmax df | Inspect a CSV dataframe (shape, head, describe), or group-by aggregate |
jmax forecast | Time-series forecasting: fit AR / ARIMA / Holt-Winters and forecast ahead |
jmax kalman | Kalman filter + RTS smoother: 1-D constant-velocity position tracking from noisy measurements |
Simulation — FEM / CFD (2-D & 3-D)
| Command | What it does |
|---|---|
jmax heat | Steady-state heat conduction (FEM) on a rectangle; writes a field SVG. Fix edge temperatures with --left/--right/--top/--bottom (omit = insulated) |
jmax stress | 2-D cantilever (linear elasticity, FEM): clamped left edge, load on the right edge. Reports tip deflection + peak von Mises; writes a stress SVG |
jmax modal | Modal analysis (FEM): natural frequencies + mode shape of a left-clamped plate. Prints the lowest frequencies; plots the chosen mode |
jmax transient | Transient heat (FEM): a hot square cooling with cold edges, integrated implicitly (Crank–Nicolson). Prints the cooling curve; plots the final field |
jmax inverse | Inverse design (differentiable FEM): recover a hidden conductivity inclusion from observed field data via adjoint-gradient descent |
jmax heat3d | 3-D steady heat in a solid box (tetrahedral FEM): hot x=0 face, cold x=length face. Plots the boundary surface temperature (isometric) |
jmax stress3d | 3-D cantilever (solid tetrahedral FEM): clamped x=0 face, downward load on the end face. Reports tip deflection + peak von Mises; plots surface |
jmax modal3d | 3-D modal analysis (tetrahedral FEM): natural frequencies + mode shape of a left-clamped solid. Prints frequencies; plots the deformed mode |
jmax stokes | Incompressible Stokes flow: a lid-driven cavity (top wall slides). Plots the speed field with velocity arrows showing the recirculating vortex |
jmax unsteady | Transient (time-stepped) incompressible Navier–Stokes: a lid-driven cavity spinning up from rest. Prints a kinetic-energy history and plots the final velocity field |
jmax stokes3d | 3-D incompressible Stokes flow in a box "pipe": top face slides in +x, other walls no-slip. Plots the boundary-surface speed field (isometric) |
jmax inverse-design | Multiple-excitation inverse design (differentiable FEM): recover a hidden conductivity inclusion using several boundary excitation patterns at once. Plots true vs recovered conductivity |
jmax advect | Scalar advection–diffusion boundary layer: solved with SUPG vs plain Galerkin to show SUPG removes the high-Péclet oscillations. Writes the SUPG field SVG plus a -galerkin companion |
jmax thermo | Thermo-mechanical coupling (multiphysics): steady heat across a clamped plate, then the thermal stress from constrained expansion. von Mises plot |
jmax topopt | Topology optimization (SIMP + Optimality Criteria): find the stiffest material layout of a cantilever for a given volume budget. Renders the optimized density field |
jmax topopt3d | 3-D topology optimization (SIMP + OC on tetrahedra): the stiffest solid layout of a cantilever for a volume budget. Renders the optimized solid |
jmax energy | Energy receipts for sparse-Poisson solves: a 3-D Laplacian scaling study printing exact FLOPs and estimated joules for each ILU(0)-CG solve |
jmax bench | Benchmark the sparse FEM solver: a 3-D Poisson scaling study reporting DOFs, CG iterations, wall time, and throughput (rayon-parallel SpMV) |
jmax lbm | Lattice-Boltzmann CFD (D2Q9 BGK): lid-driven cavity or Poiseuille channel |
Machine learning for operators
| Command | What it does |
|---|---|
jmax fno | Fourier Neural Operator demo: learn an operator (deriv/integrate/smooth) |
Visualization
| Command | What it does |
|---|---|
jmax chart | Render a publication-quality chart (SVG) from data. kind: line |
jmax project | Project an n-D data matrix down to 2-D (PCA or random) for plotting. Emits x y rows — pipe into jmax chart scatter |
jmax splom | SPLOM-of-projections: emit an interactive bundle with one linked, brushable scatter panel per projection of the same n-D rows |
jmax animate | Animate a transition between two datasets (state-transition tween). Writes frame_NNN.svg you can encode to GIF/MP4, or --interactive for an auto-playing WebGPU bundle |
Units
| Command | What it does |
|---|---|
jmax convert | Convert a value between units, e.g. convert 60 km/hour m/s |
The sections below give worked examples for the most common commands.
Evaluate & Run
jmax eval "<expr>"
Evaluate an expression — scalars, matrices, vectors, symbolic, or composed numeric functions.
jmax eval "[[1,2],[3,4]] * [5,6]" → [17, 39]
jmax run file.jmax
Run a JMax program and print its result.
jmax run fit_model.jmax
jmax plot file.jmax
Run a program and open its plots as SVG.
jmax plot dashboard.jmax
jmax emit <target> file
Lower a function to ONNX, StableHLO, WGSL, Triton, or MLIR-linalg.
jmax emit wgsl kernel.jmax
Symbolic & Verification
jmax eval "expand((x+1)^2)"
Computer-algebra: expand, simplify, differentiate, integrate, solve — exact, canonical.
→ 1 + x^2 + 2*x
jmax eval "integrate(x^2, x)"
Rule-based symbolic integration; the inverse of differentiation.
→ x^3/3
jmax eval "solve(x^2-1, x)"
Solve polynomial equations exactly.
→ x = 1, x = -1
jmax verify "<lhs> == <rhs>"
Prove an identity two ways: a sound CAS self-check, and an emitted Lean 4 theorem.
jmax verify "(x+1)^2 == x^2 + 2*x + 1"
Autodiff
jmax grad "<f>" <point...>
Gradient by reverse-mode automatic differentiation of the computation graph.
jmax grad "x^2*y + sin(x)" 1.3 0.7
jmax hessian "<f>" <point...>
Full Hessian via second-order (forward-over-reverse) AD.
jmax hessian "x^2*y + sin(x)" 1.3 0.7
Optimization
jmax minimize "<f>" <x0...>
Unconstrained minimization (gradient descent; --newton for the AD-Hessian Newton method).
jmax minimize "(1-x)^2 + 100*(y-x^2)^2" -1.2 1 --newton
jmax root "<f>" <x0>
Find a root by Newton's method (derivative via AD).
jmax root "cos(x) - x" 0.5 → 0.7390851
jmax fit "<model>" data.csv
Levenberg-Marquardt curve fitting; Jacobian from AD.
jmax fit "a*exp(b*x)" data.csv --p0 1,0
jmax lp file · jmax qp file [--ineq]
Linear programs (two-phase simplex) and quadratic programs (KKT / active-set).
jmax lp problem.txt → max cᵀx s.t. Ax ≤ b
Differential Equations
jmax ode "<dy/dt>" y0
Integrate an ODE — adaptive Dormand-Prince RK45, or --stiff for an implicit solver with an AD Jacobian.
jmax ode "1000*(cos(t) - y)" 2 --tf 1 --stiff
Linear Algebra
jmax eig file · jmax svd file
Eigenvalues (symmetric, Jacobi) and singular values.
jmax eig sym.txt → 3, 1
jmax det file · jmax rank file
Determinant (LU) and numerical rank (SVD).
jmax det m.txt → 10
jmax linsolve A b · jmax pinv file
Solve A·x = b, and the Moore-Penrose pseudoinverse.
jmax linsolve A.txt b.txt → x
Signal Processing
jmax fft signal.txt
Magnitude spectrum via radix-2 FFT.
jmax fft sig.txt → spectral peak at bin k
jmax spectrogram signal
Short-time Fourier transform — per-frame magnitude spectra.
jmax spectrogram sig.txt --frame 16 --hop 8
jmax biquad signal
Apply an IIR biquad (RBJ low/high-pass) filter.
jmax biquad sig.txt --kind lowpass --fc 0.1
Statistics
jmax stats file
Summary statistics — n, mean, std, min, median, max.
jmax stats data.txt
jmax sample <dist> <params>
Deterministic sampling from Normal / Uniform / Exponential.
jmax sample normal 0 1 -n 5 --seed 42
jmax ttest a b · jmax wilcoxon a b
Welch two-sample t-test; Wilcoxon signed-rank (paired, nonparametric).
jmax ttest a.txt b.txt → t, p
jmax anova g1 g2 … · jmax friedman m
One-way ANOVA, Friedman repeated-measures, Levene, Mann-Whitney, KS.
jmax anova g1.txt g2.txt g3.txt → F, p
Dataframes
jmax df file.csv
Inspect a CSV: shape, inferred types, head, per-column describe.
jmax df cities.csv
jmax df file --groupby c --value v
Group-by aggregation (mean / sum / count / min / max).
jmax df sales.csv --groupby city --value revenue --agg sum
jmax df file --to-parquet out
Read CSV or Parquet; write real Parquet (validated against Apache Arrow).
jmax df data.csv --to-parquet data.parquet
Units
jmax convert <v> <from> <to>
Dimensional unit conversion with compound units and metric prefixes.
jmax convert 60 km/hour m/s → 16.667 m/s
Numerics
Beyond core linear algebra, JMax carries a deep numerical library: special
functions, interpolation, polynomials, matrix decompositions, regression, and
signal processing. The pieces that take and return numbers, vectors, or matrices
are callable directly from jmax eval and jmax run; all of them are pure Rust,
with no BLAS, LAPACK, or SciPy underneath, and each is verified against analytic
or tabulated results.
jmax eval "gamma(0.5)" # 1.7724538509 (sqrt(pi))
jmax eval "roots([-6, 11, -6, 1])" # the roots of x^3 - 6x^2 + 11x - 6: 1, 2, 3
Special functions
Applied elementwise: a scalar maps to a scalar, a vector maps componentwise.
| Builtin | Function |
|---|---|
gamma(x) | gamma function |
lgamma(x) / ln_gamma(x) | log gamma (finite where gamma overflows) |
digamma(x) | digamma (derivative of log gamma) |
erf(x) / erfc(x) | error function and its complement |
beta(a, b) | beta function |
bessel_j0, bessel_j1 | Bessel functions of the first kind |
bessel_y0 | Bessel function of the second kind |
bessel_i0, bessel_k0 | modified Bessel functions |
The Rust library additionally provides higher integer orders (bessel_jn,
bessel_yn, bessel_kn), the inverse error function, the regularized incomplete
gamma and beta integrals (the kernels behind the statistical distributions), and
the complete elliptic integrals.
Polynomials
Coefficients are in ascending powers: [c0, c1, c2] is c0 + c1 x + c2 x^2.
| Builtin | Result |
|---|---|
polyval(coeffs, x) | evaluate at a scalar or vector x |
polyfit(xs, ys, degree) | least-squares polynomial coefficients |
roots(coeffs) | all roots, as an N by 2 matrix of [real, imag] |
# Fit a quadratic to noisy samples, then evaluate the fit.
jmax eval "polyval(polyfit([0,1,2,3], [1,2,5,10], 2), 1.5)"
roots uses the Aberth-Ehrlich method and returns real and complex roots
together; a real root has a near-zero imaginary part.
Interpolation
| Builtin | Scheme |
|---|---|
interp1(xs, ys, xq) | piecewise linear |
spline(xs, ys, xq) | natural cubic spline |
The query xq may be a scalar or a vector. The Rust library also offers clamped
splines, monotone PCHIP, 2D bilinear, and radial-basis-function scattered
interpolation.
The jmax interp command interpolates (x, y) samples from a data file and
plots the sample markers with the interpolant curve overlaid:
jmax interp data.dat --method spline --at 2.5 --plot interp.svg
jmax interp data.dat --method pchip --plot pchip.svg # monotone, no overshoot
Methods: spline (natural cubic, the default), linear, pchip, nearest.
For a known function (not scattered samples), jmax cheb uses Chebyshev
spectral methods: interpolation on Chebyshev–Gauss–Lobatto nodes converges
spectrally (faster than any power of 1/n, with no Runge phenomenon), and the
same representation differentiates and integrates to the same accuracy
(chebfun-style):
jmax cheb approx "exp(x)" -n 20 # max error ~1e-15 with 20 nodes
jmax cheb diff "sin(x)" --at 1 --exact 0.5403 # spectral derivative
jmax cheb integrate "4/(1+x^2)" --from 0 --to 1 --exact 3.14159265 # Clenshaw–Curtis
jmax cheb roots "sin(3.14159*x)" --from -2.5 --to 2.5 # every zero in the interval
cheb roots finds all the real zeros of a smooth function at once — no
bracketing or starting guesses — as the real eigenvalues of the function's
Chebyshev colleague matrix (the chebfun approach), which is what makes it
robust for closely spaced or many roots.
Matrix decompositions
On top of the core det, inv, solve, eig, svd, rank, and pinv:
| Builtin | Result |
|---|---|
chol(A) / cholesky(A) | lower Cholesky factor (symmetric positive-definite) |
qr(A) | the upper-triangular R factor of A = Q R |
cond(A) | 2-norm condition number |
The library exposes the full factorizations (qr returning both Q and R,
explicit (L, U, P), a one-sided Jacobi SVD, eigvalsh, least squares).
jmax eig handles the symmetric eigenproblem. For a general (nonsymmetric)
matrix — whose eigenvalues can be complex — jmax eigvals computes the whole
spectrum by Hessenberg reduction + Francis double-shift QR (the LAPACK dgeev
approach), reporting each eigenvalue as re ± im·i:
jmax eigvals A.dat # every eigenvalue of a general square matrix
Add --vectors to also compute the (complex) eigenVECTORS by inverse iteration.
And jmax rrqr gives a rank-revealing column-pivoted QR — its R diagonal
exposes the numerical rank (trailing near-zeros = rank deficiency):
jmax eigvals A.dat --vectors # eigenpairs (λ, v)
jmax rrqr A.dat # numerical rank + R diagonal + column permutation
jmax geneig solves the symmetric-definite generalized eigenproblem
K x = λ M x — the natural-frequency / mode-shape problem of structural and
vibration analysis (MATLAB eig(K,M) / SciPy eigh(K,M)), with K symmetric
and M symmetric positive-definite:
jmax geneig K.dat M.dat # generalized eigenvalues of K x = λ M x
jmax expm computes the matrix exponential e^{A·t} — the state-transition
matrix of the linear system ẋ = A x (so x(t) = e^{A t} x(0)), and the tool
behind continuous-time control and Markov chains. It is not the entrywise
exponential; it uses scaling-and-squaring with a Padé approximant (MATLAB /
SciPy expm):
jmax expm A.dat --t 0.5 # e^(A·0.5)
Its companions jmax sqrtm and jmax logm compute the principal matrix square
root (X·X = A, Denman–Beavers) and logarithm (the inverse of expm) — the
matrix-function trio behind matrix means and manifold computations:
jmax sqrtm A.dat # principal √A
jmax logm A.dat # principal log A (logm(expm(A)) = A)
jmax eig diagonalizes a matrix densely. For a matrix too large to factor —
where you want only a few eigenvalues at one end of the spectrum — jmax eigs
uses Lanczos, which needs only matrix-vector products (SciPy eigsh / ARPACK):
jmax eigs matrix.dat --k 5 --which LA # 5 largest (algebraic) eigenvalues
jmax eigs matrix.dat --k 3 --which SA # 3 smallest
jmax eigs laplacian.txt --k 2 --triplets # sparse input: "row col value" per line
--which selects the end of the spectrum (LA largest, SA smallest, LM
largest magnitude); --triplets reads coordinate form for a genuinely sparse
matrix; --maxiter raises the Krylov budget for tightly clustered spectra.
To reach eigenvalues buried in the interior of the spectrum — near a
resonance, a design frequency, a bandgap — pass --sigma, which runs
shift-invert Lanczos on (A − σI)⁻¹ and returns the eigenvalues nearest σ
(SciPy eigsh(sigma=…) / ARPACK shift-invert):
jmax eigs matrix.dat --k 3 --sigma 2.0 # the 3 eigenvalues closest to 2.0
The iterative solvers approximate; for an exact solve of a large sparse
system, jmax lusolve factors it directly — sparse LU (Gilbert–Peierls, with
partial pivoting) for a general matrix, or LDLᵀ / sparse Cholesky with --spd
for a symmetric positive-definite one:
jmax lusolve A.dat b.vec # sparse LU: A x = b
jmax lusolve K.dat f.vec --spd # sparse Cholesky (SPD), e.g. an FEM stiffness solve
jmax lusolve big.txt b.vec --triplets # coordinate-format sparse input
Tensors and einsum
Beyond matrices, JMax has N-dimensional tensors with NumPy broadcasting,
reshaping, axis reductions, and a general einsum. On the CLI, jmax einsum
runs Einstein summation over matrix operands — matrix multiply, trace,
transpose, and contraction all in one index notation:
jmax einsum "ij,jk->ik" A.dat B.dat # matrix multiply
jmax einsum "ii->" A.dat # trace
jmax einsum "ij->ji" A.dat # transpose
jmax lowrank compresses a matrix to its best rank-k approximation by
truncated SVD (Eckart–Young); --report shows the singular values, the retained
energy, the Frobenius error ‖A − Aₖ‖, and the storage ratio:
jmax lowrank data.dat --rank 5 --report # rank-5 approximation + compression stats
Where SVD gives signed orthogonal factors, jmax nmf gives non-negative ones
— A ≈ W H with W, H ≥ 0 — so the factors read as additive, interpretable
parts (topics, spectral endmembers, source signals; scikit-learn's NMF):
jmax nmf counts.dat --rank 3 # 3 non-negative parts W and their coefficients H
The library also carries two N-dimensional tensor factorizations: Tucker /
higher-order SVD (hosvd, tucker_reconstruct) for orthogonal subspace
compression, and CP / PARAFAC (cp_als) for a sum of interpretable rank-1
components.
Regression and statistics
| Builtin | Result |
|---|---|
lm(X, y) / ols(X, y) | least-squares regression coefficients (intercept first) |
corr(A) | Pearson correlation matrix of the columns of A |
mean, median, std, var, sum, min, max, sort | over a vector |
The jmax-stat library also returns the full regression summary (R squared,
standard errors, t statistics, p values), one-way ANOVA tables, the percentile
bootstrap, and Gaussian kernel density estimation.
Time series
jmax forecast fits a classical time-series model to a series and projects it
forward — AR(p) (Yule–Walker), ARIMA(p, d, q), or additive Holt–Winters triple
exponential smoothing:
jmax forecast series.dat --model arima --p 2 --d 1 --q 0 --steps 12
jmax forecast sales.dat --model hw --season 12 --steps 24 # trend + seasonality
State estimation
jmax kalman runs a Kalman filter (and, with --smooth, the RTS smoother) over
noisy 1-D position measurements using a constant-velocity model — recovering
position and velocity and de-noising the track:
jmax kalman track.dat --meas-noise 0.4 --proc-noise 1e-3 --smooth --plot k.svg
Signal processing
| Builtin | Result |
|---|---|
fft(x) | magnitude spectrum |
psd(x) | power spectral density |
hann(n), hamming(n), blackman(n) | window functions |
The library adds full convolution and correlation, windowed-sinc FIR design (low,
high, band), Butterworth biquads with zero-phase filtfilt, and the STFT
spectrogram.
Where the FFT trades all time information for frequency, the wavelet
transform keeps both, localizing a transient in time and scale. jmax wavelet
runs the orthonormal fast wavelet transform (Haar, db2, db4) — either a
multiresolution decomposition (energy per scale) or wavelet denoising
(soft-threshold, VisuShrink), the tools of SciPy pywt:
jmax wavelet signal.dat --wavelet db4 --level 4 # energy per scale
jmax wavelet signal.dat --wavelet db4 --denoise --plot d.svg # denoise + overlay
Calculus, ODEs, and optimization
Adaptive quadrature (jmax-quad: Gauss-Kronrod, Gauss-Legendre, Gauss-Hermite),
ODE integration (jmax-ode: adaptive RK45 with dense output and event detection,
plus implicit BDF for stiff systems), and unconstrained optimization
(jmax-optim: Nelder-Mead, L-BFGS, box-constrained L-BFGS) take a function as
input. They are available through the Rust API today and are being surfaced as
dedicated jmax subcommands.
jmax minimize also takes --constraints: a ;-separated list of relations
(<=, >=, =) in the objective's variables, solved by the augmented
Lagrangian method (SciPy minimize(constraints=…) / MATLAB fmincon):
jmax minimize "x^2 + y^2" 0 0 --constraints "x + y = 1" # -> (0.5, 0.5)
jmax minimize "(x-2)^2 + (y-1)^2" 0 0 --constraints "x^2 + y^2 <= 1" # project onto the disk
jmax minimize "x^2+y^2+z^2" 0 0 0 --constraints "x+y+z = 1; x >= 0.6" # equality + inequality
Equalities become g = 0 and inequalities g ≤ 0; the report gives the
solution, the objective, and the worst constraint violation.
The other minimizers are local — they descend to the nearest basin. For a
multimodal objective, --global searches a whole box by Differential Evolution
(SciPy differential_evolution), then polishes the winner with box-constrained
L-BFGS. It is deterministic given its seed, and needs --bounds (one lo,hi
per variable, alphabetical):
# Rastrigin: a lattice of local minima; DE finds the global one at the origin.
jmax minimize "20 + (x^2-10*cos(6.2831853*x)) + (y^2-10*cos(6.2831853*y))" \
--global --bounds "-5.12,5.12; -5.12,5.12"
The numerical definite integral has its own command:
jmax quad "exp(-x^2)" --from -5 --to 5 # 1.7724538509 (sqrt(pi))
jmax quad "x^7" --from 0 --to 1 --method gl --points 4 # 0.125, exact
Multidimensional integrals over a rectangle or box use jmax quad2 and
jmax quad3 (tensored adaptive Gauss-Kronrod; SciPy dblquad/tplquad):
jmax quad2 "exp(-(x^2+y^2))" --xfrom -3 --xto 3 --yfrom -3 --yto 3 # ≈ π
jmax quad3 "x*y*z" # ∫∫∫ over the unit cube = 1/8
Stochastic differential equations integrate over many sample paths with
jmax sde (Euler-Maruyama or Milstein):
# geometric Brownian motion; mean of X(T) approaches X0 * e^(mu*T)
jmax sde "0.05*y" "0.2*y" --y0 1 --t1 1 --paths 4000 --plot path.svg
Ordinary differential equations are solved with jmax ode; --method rosenbrock
selects an L-stable stiff solver, and --events "<g>" reports zero-crossings:
jmax ode "-1000*(y - cos(t)) - sin(t)" 1 --tf 1 --method rosenbrock # stiff -> cos(t)
Where jmax ode marches an initial value forward, jmax bvp solves a
boundary value problem — y'' = f(x, y, yp) on [a, b] with the solution
pinned at both ends, y(a) and y(b). It shoots: the unknown initial slope is
found by driving the far-boundary residual to zero (adaptive RK45 inside a
Newton solve). The right-hand side is written in x, y, and yp (for y'):
jmax bvp "-y" --a 0 --b 1.5708 --ya 0 --yb 1 # y''=-y -> sin(x)
jmax bvp "6*x" --a 0 --b 1 --ya 0 --yb 1 --plot cubic.svg # y''=6x -> x^3
jmax bvp "-sin(y) - 0.1*yp" --a 0 --b 4 --ya 1 --yb -0.3 --slope -0.5 # nonlinear
The default method is single shooting (integrate from one end, Newton-solve for
the initial slope). For stiff or strongly nonlinear problems, where forward
integration amplifies the slope error, --method collocation instead
discretizes the whole trajectory and solves it at once by 4th-order
Hermite-Simpson collocation — the method behind MATLAB bvp4c / SciPy
solve_bvp:
jmax bvp "6*x" --a 0 --b 1 --ya 0 --yb 1 --method collocation --nodes 40
Shooting hits linear problems in one Newton step; collocation returns the whole mesh solution and stays accurate where shooting struggles.
--method adaptive goes further: it starts from a coarse mesh, estimates the
error on each interval, and refines where the solution is hardest to resolve —
automatically capturing boundary layers and sharp features a uniform mesh would
miss, and falling back to homotopy continuation when the nonlinear solve stalls:
jmax bvp "80*sinh(y)" --a 0 --b 1 --ya 0 --yb 1 --method adaptive --nodes 8
# converges by refining ~8 -> ~90 nodes to resolve the boundary layer near x=1
For a linear variable-coefficient problem u'' + p(x)u' + q(x)u = f(x),
--method spectral uses Chebyshev collocation — exponentially accurate for
smooth coefficients (the main expr is f(x); --p/--q are the coefficients):
jmax bvp "0" --a 0 --b 1.5708 --ya 0 --yb 1 --method spectral --q "1" # u''+u=0 -> sin(x)
It reports the initial and final node counts and the largest remaining interval error. Mesh refinement is robust from a plain guess; the continuation fallback widens the basin for hard nonlinear solves but a pathological guess on a multi-solution problem can still need a better start.
Machine learning for operators
jmax fno demonstrates a Fourier Neural Operator learning a solution operator
from example fields (differentiation, integration, or smoothing) rather than a
fixed input/output pair:
jmax fno --operator deriv --plot fno.svg # learns differentiation to ~1e-15
jmax fno --operator smooth # learns a Gaussian-smoothing operator
The spectral convolution (FFT, per-mode complex weights, inverse FFT) and the operator fit are pure Rust; this is the building block for PDE surrogate models.
Symbolic algebra
JMax carries a computer algebra system. From jmax eval, expressions with free
variables are simplified symbolically, and the calculus functions fold to their
results:
jmax eval "d/dx (x^3 + sin(x))" # 3*x^2 + cos(x)
jmax eval "integrate(x*sin(x), x)" # sin(x) - x*cos(x) (by parts)
jmax eval "integrate(1/(x^2 - 1), x)" # partial fractions to logs
jmax eval "expand_trig(sin(2*x))" # 2*cos(x)*sin(x)
jmax eval "sin(x)^2 + cos(x)^2" # 1
Supported symbolic operations include differentiation, integration (power rule, the standard table, integration by parts, u-substitution, partial fractions), Taylor series, limits (continuity, L'Hopital, rational forms at infinity), equation solving (linear, quadratic, cubic, and linear systems), polynomial expand/collect, substitution, and trig rewriting.
Systems of polynomial equations are solved with jmax solve-system, which builds
a Gröbner basis and back-substitutes for the real solutions (Mathematica-class
solving of nonlinear systems):
jmax solve-system "x^2 + y^2 - 1; x - y" --vars x,y # circle meets line: (±0.707, ±0.707)
jmax solve-system "x^2 - y; y - 4" --vars x,y # (±2, 4)
Each ;-separated expression is read as = 0. The solver handles
zero-dimensional systems and reports inconsistent or positive-dimensional ones.
For systems that are not polynomial — anything with sin, exp, log, or
ratios — jmax fsolve finds a root numerically by damped Newton iteration from
a starting guess, converging to the solution nearest the start. This is the
floating-point counterpart to solve-system (SciPy fsolve / MATLAB fsolve):
jmax fsolve "x*cos(y) - 1; x*sin(y) - 1" --vars x,y # -> (√2, π/4)
jmax fsolve "x^2 + y^2 - 1; y - x" --vars x,y --start -2,-0.5 # the negative root
jmax fsolve "x+y+z-6; x^2+y^2+z^2-14; x*y*z-6" --vars x,y,z --start 0.5,1.5,3.5 # (1,2,3)
The system must be square (one equation per variable); a singular Jacobian is
handled by a Levenberg-Marquardt fallback, and --start selects which root a
multi-root system converges to.
When there are more residuals than unknowns — an overdetermined system, the
usual case in fitting and calibration — jmax lsq minimizes the sum of squares
½Σrᵢ² by Levenberg-Marquardt instead of demanding an exact root (SciPy
least_squares / MATLAB lsqnonlin):
# Least-squares line through 4 non-collinear points -> a=1.1, b=1.1
jmax lsq "a+b*0-1; a+b*1-3; a+b*2-2; a+b*3-5" --vars a,b
# Three circles that nearly meet: the best-fit intersection point
jmax lsq "sqrt(x^2+y^2)-1.4142; sqrt((x-2)^2+y^2)-1.4142; sqrt(x^2+(y-2)^2)-1.4142" --vars x,y --start 0,0
Each ;-separated expression is a residual driven toward zero; the report gives
the fitted values, the residual norm ‖r‖, and the cost ½‖r‖².
Ordinary differential equations are solved symbolically with jmax dsolve:
jmax dsolve "1 - y" # y' = 1 - y -> y = exp(-x)*(C + exp(x))
jmax dsolve --linear2 "1,0,1" # y'' + y = 0 -> y = C1*cos(x) + C2*sin(x)
The first-order solver handles separable and linear equations; --linear2
solves the homogeneous constant-coefficient second-order equation
a y'' + b y' + c y = 0 through its characteristic roots (real, repeated, and
complex cases).
Plots
jmax plot graphs one or more single-variable expressions over a domain,
overlaying them in one figure:
jmax plot "sin(x)/x" --from -20 --to 20 --out sinc.svg
jmax plot "sin(x)" "cos(x)" "sin(x)*exp(-x/6)" --from 0 --to 12
jmax plot "bessel_j0(x)" "bessel_j1(x)" --from 0 --to 20
The expressions use the same scalar interpreter as the other commands, so the standard math and special functions are available.
For optimization, minimize --contour draws a 2-variable objective as a contour
with the optimizer's descent path overlaid:
jmax minimize "(1-x)^2 + 100*(y-x^2)^2" -1 1 --method lbfgs --contour rosen.svg
Several numerical commands also write a publication-quality SVG with --plot:
jmax quad "exp(-x^2)" --from -3 --to 3 --plot integral.svg # integrand, area shaded
jmax ode "cos(t)" 0 --tf 7 --plot trajectory.svg # the solution y(t)
jmax ode "cos(t)" 0 --t0 1 --tf 7 --events "y" --plot ev.svg # trajectory + event markers
jmax fit "a*exp(b*x)" data.dat --p0 1,1 --plot fit.svg # data points + fitted curve
jmax spectrogram signal.dat --plot spec.svg # time x frequency heatmap
jmax df data.csv --plot dist.svg # facet of column histograms
jmax df data.csv --groupby region --value sales --plot bar.svg # grouped bar chart
The simulation commands likewise render their fields (jmax heat --out heat.svg,
and so on); see the Simulation reference.
Interactive output
jmax plot, quad, ode, fit, and interp also accept --html <dir>, which
writes a self-contained interactive bundle (an index.html, the figure as
viz.json, and the WebGPU viewer) instead of a static SVG. The same figure is
rendered on a canvas you can drag to pan, scroll to zoom, shift-drag to brush,
and double-click to reset:
jmax plot "sin(x)/x" --from -20 --to 20 --html playground
cd playground && python3 -m http.server # then open the page
jmax df --html writes a multi-canvas facet of interactive column histograms (or
an interactive bar chart for a --groupby result). jmax spectrogram --html
writes an interactive viridis heatmap, and jmax minimize --contour --html writes
an interactive contour of the objective with the descent path overlaid (the same
--contour also writes a static SVG). All support drag-pan, wheel-zoom, and
double-click reset:
jmax df data.csv --html dist
jmax spectrogram signal.dat --html spec
jmax minimize "(1-x)^2 + 100*(y-x^2)^2" -1 1 --contour rosen.svg --html descent
Simulation
JMax ships a native finite-element simulation stack: mesh generation, assembly, sparse Krylov solvers, and a family of physics solvers, all pure Rust with no external BLAS, LAPACK, or PETSc. Every command below solves a real PDE on a generated mesh, prints diagnostics, and writes a publication-quality SVG.
Every solve also reports an energy receipt: the exact floating-point operation count of the linear solve, plus an estimated energy cost. The FLOP count is exact; the joules are an estimate at a documented per-FLOP rate. This is the JoulesPerBit idea made routine, so the cost of a computation is visible next to its result.
energy (est.) : ≈ 96.8 MFLOP, ~5.8 mJ (est.)
Solid mechanics
| Command | Solves | Render |
|---|---|---|
jmax heat | steady heat conduction, -div(k grad T) = f (2D) | temperature field |
jmax stress | linear elasticity, plane stress cantilever (2D) | von Mises stress |
jmax modal | natural frequencies and mode shapes (2D) | deformed mode shape |
jmax transient | time-dependent heat (theta-method) (2D) | cooling field + curve |
jmax heat3d | steady heat in a solid box (3D tetrahedra) | isometric surface field |
jmax stress3d | linear elasticity cantilever (3D tetrahedra) | isometric von Mises |
jmax modal3d | natural frequencies of a solid (3D) | deformed mode shape |
jmax thermo | thermo-mechanical coupling (heat then thermal stress) | von Mises field |
jmax topopt | topology optimization, SIMP + optimality criteria (2D) | grayscale density |
jmax topopt3d | topology optimization (3D tetrahedra) | solid structure |
Examples:
# Steady heat across a plate, hot left edge, cold right edge.
jmax heat --nx 60 --ny 60 --left 100 --right 0 --out heat.svg
# Cantilever stress under a tip load; reports tip deflection and peak von Mises.
jmax stress --nx 80 --ny 26 --load 1000 --out stress.svg
# Lowest five natural frequencies of a clamped plate; plots mode 1.
jmax modal --nx 60 --ny 20 --modes 5 --show 1 --out mode.svg
# Topology optimization: stiffest cantilever at 40% material.
jmax topopt --nx 80 --ny 40 --volfrac 0.4 --iters 60 --out topology.svg
Fluids
| Command | Solves | Render |
|---|---|---|
jmax stokes | incompressible Stokes (creeping) or Navier-Stokes flow (2D) | speed field + arrows |
jmax stokes3d | 3D incompressible Stokes flow in a box | isometric speed field |
jmax unsteady | time-dependent Navier-Stokes (lid-driven cavity) | flow + energy history |
jmax advect | scalar advection-diffusion, SUPG vs Galerkin | scalar field |
jmax lbm | Lattice-Boltzmann (D2Q9 BGK): lid-driven cavity or Poiseuille channel | speed-field heatmap |
jmax lbm is a kinetic-theory CFD solver (the lattice-Boltzmann method, the
approach behind real-time GPU flow tools) that complements the FEM Navier-Stokes
above. It runs a lid-driven cavity or a force-driven channel to steady state and
writes the speed field as a heatmap, static (--plot) or interactive (--html):
jmax lbm --case cavity --nx 64 --ny 64 --re 100 --plot cavity.svg
jmax lbm --case channel --html flow # force-driven Poiseuille, interactive
The fluid solvers use a mixed velocity-pressure formulation with
Brezzi-Pitkaranta pressure stabilization, solved by GMRES with a block
(Silvester-Wathen) preconditioner. jmax stokes --reynolds 0 solves creeping
Stokes flow; any positive Reynolds number switches to the full Navier-Stokes
equations resolved by Picard iteration.
# Creeping lid-driven cavity (Stokes).
jmax stokes --n 40 --out cavity.svg
# Finite-Reynolds cavity (Navier-Stokes); the primary vortex shifts with Re.
jmax stokes --n 48 --reynolds 200 --out cavity-re200.svg
# Advection-diffusion boundary layer; SUPG stays monotone where Galerkin wiggles.
jmax advect --nx 24 --peclet 50 --out advect.svg
Inverse design and differentiable simulation
| Command | Solves | Render |
|---|---|---|
jmax inverse | recover a hidden conductivity inclusion (one experiment) | true vs recovered |
jmax inverse-design | multiple-excitation inverse (recovers amplitude) | true vs recovered |
These use the adjoint method: the gradient of a least-squares objective with respect to every per-element conductivity comes from one extra solve, so the material can be optimized to match observed data. A single experiment localizes a hidden inclusion but cannot recover its amplitude; several excitation patterns together over-determine the field and pin the amplitude down.
jmax inverse-design --n 24 --inclusion 3 --excitations 4 --iters 300 --out recovered.svg
Performance and energy
| Command | Reports |
|---|---|
jmax bench | 3D Poisson solver scaling: DOFs, iterations, time, throughput |
jmax energy | energy-receipt scaling table: FLOPs and estimated joules per solve |
jmax bench --max-n 48
jmax energy --max-n 64
The sparse matrix-vector product is parallel across CPU cores and stays bit-deterministic. A GPU-resident conjugate gradient (wgpu compute) is available for the heterogeneous-compute path.
From the language
Several solvers are callable directly from JMax source (jmax eval and
jmax run), composing with the linear-algebra surface:
# Sparse solve on the GPU (falls back to CPU if no adapter); residual ~ 0.
norm([[4.0,1.0],[1.0,3.0]] * gpu_solve([[4.0,1.0],[1.0,3.0]], [1.0,2.0]) - [1.0,2.0])
# Steady heat on a grid returns a matrix of temperatures.
max(poisson_grid(24, 100.0)) # -> ~7.37 (the 0.0737*f result)
# Natural frequencies of a cantilever as a vector.
modal_freqs(40, 12, 4)
Available builtins: cg_solve, bicgstab_solve, gmres_solve, heat_grid,
poisson_grid, modal_freqs, gpu_solve, stokes_lid.
How it is built
The stack is two pure-Rust crates. jmax-sparse provides CSR/COO matrices,
preconditioned CG / BiCGSTAB / GMRES, ILU(0) and Jacobi preconditioners, and a
subspace-iteration eigensolver. jmax-fem builds the meshes, assembles the
element matrices, and implements the physics solvers on top. Each solver is
verified against closed-form results (patch tests, method of manufactured
solutions, and analytic profiles such as Poiseuille flow and beam theory).
Library crates
JMax is also a set of pure-Rust library crates you can embed directly — no Python, no C++, no LAPACK/BLAS. Each crate is independently useful and published to crates.io.
| Crate | Purpose |
|---|---|
jmax-symbolic | Computer-algebra engine: canonical term algebra, diff, e-graph simplify, integrate, solve. |
jmax-flowg | flowG dataflow substrate: lowering, autodiff (grad/HVP/Hessian), optimization, ODE solvers. |
jmax-linalg | Dense linear algebra: LU, Cholesky, QR, symmetric eigen, SVD, pseudoinverse. |
jmax-dsp | FFT/IFFT, windows, spectrogram, FIR + IIR filtering. |
jmax-stat | Distributions, RNG, and a parametric + nonparametric hypothesis-test suite. |
jmax-frame | Typed dataframes with CSV and real Parquet I/O, group-by, pivot, joins. |
jmax-convex | Linear, quadratic, and nonlinear constrained optimization. |
jmax-units | Dimensional analysis and unit conversion. |
jmax-verify | Formal-verification bridge: emit Lean 4 from symbolic results. |
Full embedding API: docs.rs/jmax.
Cookbook
Task-oriented recipes. Each one is a few lines you can paste into the
playground or a .jmax file.
Solve a linear system
let A = [[2.0, 1.0], [1.0, 3.0]]
let b = [5.0, 10.0]
A \ b # → [1, 3]
Eigenvalues, determinant, inverse
let A = [[2.0, 1.0], [1.0, 3.0]]
eig(A) # eigenvalues (symmetric QR)
det(A) # determinant (LU)
inv(A) # inverse (Gauss–Jordan)
Summary statistics
let x = [4.0, 8.0, 15.0, 16.0, 23.0, 42.0]
mean(x); std(x); median(x); percentile(x, 0.9)
Fit a line
let xs = [1.0, 2.0, 3.0, 4.0, 5.0]
let ys = [2.1, 3.9, 6.2, 7.8, 10.1]
linear_regression(xs, ys) # → [intercept, slope, r_squared]
FFT of a signal
let t = linspace(0.0, 1.0, 256)
let sig = map(t, \x -> sin(2.0 * 3.14159 * 5.0 * x))
fft(sig) # magnitude spectrum — peak at 5 Hz
Symbolic calculus
diff(sin(x) * x^2, x) # exact derivative
integrate(x^2, x) # → x^3/3
simplify((x + 1)^2 - x^2) # → 1 + 2*x
solve(x^2 - 1, x) # → x = 1, x = -1
Gradient-based optimization
# Minimize the Rosenbrock function with the AD-Hessian Newton method
minimize("(1-x)^2 + 100*(y-x^2)^2", [-1.2, 1.0], --newton) # → (1, 1)
Black–Scholes option price
black_scholes_call(100.0, 105.0) # S=100, K=105, T=1yr, r=5%, σ=20%
A dataframe group-by (CLI)
jmax df sales.csv --groupby city --value revenue --agg sum
Plot a chart
let cats = ["NY", "LA", "SF", "CHI"]
let vals = [120.0, 200.0, 90.0, 150.0]
plot bar vals, title="revenue"
JMax plots line, scatter, bar, histogram, density, heatmap,
boxplot, violin, contour, polar, stem, 3-D scatter, and 3-D
surface — see the visualization reference.
Convert units
jmax convert 60 km/hour m/s # → 16.667 m/s
Verify an identity
jmax verify "(x+1)^2 == x^2 + 2*x + 1" # CAS self-check + emitted Lean 4 theorem
Why JMax
Write the math. See the result.
Scientific computing fractured into a stack you assemble before you can begin: a language, a numerics library, a plotting library, an autodiff package, an optimizer, a dataframe, a unit system — each a separate install, each with its own conventions, none of them aware of the others. JMax collapses that stack into one binary where the pieces already fit.
Three ideas
Matrices are values. A matrix, a vector, a symbolic expression, a
dataframe — these are first-class values with the operators mathematics already
gives them. A \ b solves a system; * multiplies matrices; ' transposes;
d/dx differentiates. There is no array library to import because arrays are
the language.
Plots are statements. Visualization isn't a bolted-on package with its own
object model. plot line xs, ys is a statement, the same way let is. One
Scene IR drives publication SVG, native-GPU rendering, and an interactive
WebGPU canvas — line, scatter, bar, histogram, density, heatmap, boxplot,
violin, contour, polar, parallel-coordinates, 3-D scatter, and 3-D surface, plus
PCA / t-SNE / UMAP projections.
Every computation is measured in joules. Energy is a first-class observable. Every workload can attach a measured receipt — picojoules per operation, with the sensor source — because JMax is projected onto flowG, the energy-metered substrate. The same code runs on CPU, Apple-silicon Metal, or WebGPU, and reports what it cost.
What that buys you
- 113 built-in functions across 15 domains — linear algebra, statistics, signal processing, ML primitives, symbolic math, calculus & autodiff, optimization, ODEs, hypothesis tests, dataframes, units, and plotting — with nothing else to install.
- Exact where it can be. Symbolic differentiation, integration, and
simplification (equality-saturation e-graph); identities you can
verifyinto a Lean 4 theorem. - The same code everywhere.
.jmaxruns on the CLI, embeds as a Rust library, and runs in the browser compiled to WebAssembly — try it at play.charlot-lang.dev. - Pure Rust. No Python, no C++ shared libraries, no LAPACK or BLAS to install. One binary.
Position in the openIE-dev ecosystem
JMax is the scientific-computing surface. See How it fits for the full family — flowG (the substrate), Lux and Joule (sibling languages), and JouleDB (metered persistence).
How JMax fits the openIE ecosystem
Five public projects share a common substrate:
lux-lang jmax joule-lang
\ | /
\ | /
▼ ▼ ▼
flow-g ← ← ← jouledb (metered persistence)
▲
│
substrate-energy
(joules)
[Detailed design discussion in v0.2.0 docs.]