2 releases
Uses new Rust 2024
| 0.1.1 | May 3, 2026 |
|---|---|
| 0.1.0 | Apr 14, 2026 |
#569 in Math
Used in scirs2-symbolic
525KB
10K
SLoC
OxiEML
All elementary functions from a single binary operator.
A Pure Rust crate that implements the EML operator eml(x, y) = exp(x) - ln(y)
and builds uniform binary trees expressing all elementary functions using only
this operator and the constant 1.
Based on arXiv:2603.21852 — "All elementary functions from a single binary operator" by Andrzej Odrzywolek (Jagiellonian University, Institute of Theoretical Physics).
Key Capabilities
-
Uniform Tree Representation — Every elementary function (exp, ln, sin, cos, +, -, *, /, ^, sqrt, abs, ...) is expressed via the grammar
S -> 1 | eml(S, S). -
Symbolic Regression — Discover closed-form mathematical formulas from input/output data using gradient-based search over EML tree topologies.
-
Lowering & Code Generation — Convert discovered EML trees to standard operation trees for efficient evaluation, pretty-printing, and Rust code emission.
-
CLI Tool — Parse, evaluate, and generate EML expressions from the command line.
-
SMT Integration — Constraint solving via EML tree interval narrowing (feature-gated for oxiz integration).
-
Gradient / Jacobian / Hessian — Symbolic differentiation on
LoweredOpwithLoweredOp::grad(wrt),grad_all(),jacobian(n),hessian(n). -
Extended Transcendentals —
LoweredOphasTan,Sinh,Cosh,Tanh,Arcsin,Arccos,Arctan,Arcsinh,Arccosh,Arctanhwith canonical EML shape recognition. -
Interval Arithmetic —
LoweredOp::eval_intervalfor range analysis and symreg pruning. -
JIT Compilation — Cranelift-based JIT for hot evaluation paths (feature:
jit). -
ODE Discovery — SINDy-style ODE/PDE discovery from trajectory data (
SymRegEngine::discover_ode). -
Multi-output Symbolic Regression —
SymRegEngine::discover_multifor vector-valued formulas. -
Dimensional Analysis — SI unit-aware regression with
Unitsalgebra; rejects dimensionally-inconsistent formulas. -
Python Bindings — PyO3-based Python bindings via maturin (feature:
python). -
WASM Bindings — wasm-bindgen target with npm package
@cool-japan/oxieml(feature:wasm). -
Noise-Robust Loss — Huber and TrimmedMSE loss functions (
SymRegLossenum). -
Constants Extraction — Post-Adam rounding of floats to π, e, simple rationals.
-
Beam Search —
SymRegStrategy::Beam{width}for depth > 4 topology exploration. -
MCTS Search — Monte Carlo Tree Search topology exploration (
symreg/mcts.rs). -
Serde Serialization — JSON + oxicode binary for
EmlTree/LoweredOp/DiscoveredFormula(feature:serde). -
TensorLogic Integration — Bidirectional
LoweredOp ↔ TLExprmapping + soft-prior export (feature:tensorlogic). -
SciRS2 Integration — ndarray adapter (feature:
scirs2).
CLI Tool
The oxieml CLI can evaluate EML expressions, generate EML from function names,
and verify claims about mathematical constants.
# Evaluate an EML expression
oxieml "E(1, 1)"
#=> MATCH: e (Euler's number) = 2.718281828459045
# Generate EML from a function/constant name
oxieml -g pi
#=> E(1,E(E(1,E(E(1,E(E(1,E(1,E(1,1))),1)),E(E(1,1),1))),1))
#=> MATCH: Im ~ pi (diff = 0.00e0)
oxieml -g e
#=> E(1,1)
oxieml -g sin x0=0.5
#=> Result: 0.4794255386042034
# Evaluate with variables
oxieml "E(x0, 1)" x0=2.0
#=> Result: 7.38905609893065 (= exp(2))
# Read from file
oxieml --file expression.txt
# List all available functions and constants
oxieml -l
# Show help / version
oxieml --help
oxieml --version
If the input is not a valid EML expression, the CLI auto-detects function names:
oxieml pi # same as: oxieml -g pi
oxieml sin # generates sin(x0) template
Quick Start (Library)
use oxieml::{EmlTree, Canonical, EvalCtx};
// Build exp(x) = eml(x, 1)
let x = EmlTree::var(0);
let exp_x = Canonical::exp(&x);
// Evaluate at x = 1.0 -> e
let ctx = EvalCtx::new(&[1.0]);
let result = exp_x.eval_real(&ctx).unwrap();
assert!((result - std::f64::consts::E).abs() < 1e-10);
// Euler's number: eml(1, 1) = exp(1) - ln(1) = e
let e = Canonical::euler();
println!("{}", e); // "eml(1, 1)"
// Negation, addition, multiplication — all from eml and 1
let y = EmlTree::var(1);
let sum = Canonical::add(&x, &y);
let product = Canonical::mul(&x, &y);
// Lower to standard operations for efficient evaluation
let lowered = exp_x.lower();
println!("{}", lowered.to_pretty()); // "exp(x0)"
let fast_result = lowered.eval(&[1.0]);
// Generate Rust source code
let code = oxieml::compile::compile_to_rust(&exp_x, "my_exp");
println!("{code}");
Parser
Parse EML expressions from strings and convert back:
use oxieml::parser::{parse, to_compact_string};
// Parse E(x, y) notation
let tree = parse("E(E(1, 1), 1)").unwrap();
assert_eq!(tree.depth(), 2);
// Also accepts eml(x, y) notation
let tree = parse("eml(E(1, x0), 1)").unwrap();
// Convert back to compact string
let compact = to_compact_string(&tree);
assert_eq!(parse(&compact).unwrap(), tree); // roundtrip
Symbolic Regression
use oxieml::symreg::{SymRegConfig, SymRegEngine};
// Generate data from an unknown function
let inputs: Vec<Vec<f64>> = (0..50).map(|i| vec![i as f64 * 0.1]).collect();
let targets: Vec<f64> = inputs.iter().map(|x| x[0].exp()).collect();
let config = SymRegConfig {
max_depth: 2,
learning_rate: 1e-2,
tolerance: 1e-8,
..Default::default()
};
let engine = SymRegEngine::new(config);
let formulas = engine.discover(&inputs, &targets, 1).unwrap();
println!("Best formula: {}", formulas[0].pretty);
println!("MSE: {:.2e}", formulas[0].mse);
SMT / Constraint Solving
With the smt feature, oxieml integrates OxiZ 0.2
as a backend for deciding EML constraints. The solver uses interval propagation
(EML-aware forward/backward rules for exp/ln) followed by linear relaxation
(secant + tangent bounds) for OxiZ's LRA theory.
use oxieml::{EmlTree, Canonical, EmlConstraint, EmlSmtSolver, SmtResult};
// Constraint: exp(x) > 0 — trivially true for all x
let x = EmlTree::var(0);
let one = EmlTree::one();
let exp_x = EmlTree::eml(&x, &one);
let c = EmlConstraint::GtZero(exp_x);
let solver = EmlSmtSolver::new(vec![(-10.0, 10.0)]);
match solver.check_sat(&c).unwrap() {
SmtResult::Sat(sol) => println!("SAT: x = {}", sol.assignments[0]),
SmtResult::Unsat => println!("UNSAT — impossible"),
SmtResult::Unknown => println!("unknown"),
}
The EmlSmtSolver can prove UNSAT for cases the legacy EmlNraSolver
(interval bisection) cannot — e.g., ln(x) > 0 with x ∈ [-2, -1] (ln
undefined for non-positive reals). It falls back to bisection on OxiZ-tightened
bounds to extract concrete SAT witnesses, since extracting real-valued models
from OxiZ 0.2 is not yet ergonomic.
Enable with:
[dependencies]
oxieml = { version = "0.1", features = ["smt"] }
The IntervalDomain type is always available (no feature) for lightweight
propagation use-cases.
What's New in v0.1.1
Released 2026-05-03.
- Symbolic gradient, Jacobian, and Hessian on
LoweredOp - Extended transcendentals in
LoweredOp(Tan,Sinh,Cosh,Tanh,Arcsin,Arccos,Arctan,Arcsinh,Arccosh,Arctanh) - Interval arithmetic on
LoweredOpfor domain analysis and symreg pruning - Noise-robust loss (
Huber,TrimmedMSE) and constants extraction (π, e, rationals) - Beam search and MCTS topology strategies for depth > 4
- ODE/PDE discovery via
SymRegEngine::discover_ode - Multi-output symbolic regression via
SymRegEngine::discover_multi - Dimensional analysis: SI unit-aware regression with hard pruning
- JIT compilation (Cranelift,
jitfeature): 5–20× speedup on long batches - Serde serialization for all types (
serdefeature) - Python bindings (
pythonfeature, maturin-packaged) - WASM bindings (
wasmfeature, npm:@cool-japan/oxieml) - TensorLogic integration (
tensorlogicfeature): soft-prior export - SciRS2 integration (
scirs2feature): ndarray adapters - Constraint-guided symreg pruning via
EmlSmtSolver(UNSAT-prune topologies) - CLI:
--grad/-d,--symreg/-s,--format,--output,--strategyflags
Canonical Constructions (Complete Phylogenetic Tree)
All functions from the paper's phylogenetic tree (Figure 1) are implemented:
Table 1: Basic Operations
| Function | EML Construction | Depth |
|---|---|---|
exp(x) |
eml(x, 1) |
1 |
e |
eml(1, 1) |
1 |
ln(x) |
eml(1, eml(eml(1, x), 1)) |
3 |
-x |
via (e-x) - e composition |
6 |
0 |
ln(1) |
3 |
Table 2: Arithmetic
| Function | EML Construction | Depth |
|---|---|---|
x + y |
sub(x, neg(y)) |
~12 |
x - y |
eml(ln(x), eml(y, 1)) |
~7 |
x * y |
exp(ln(x) + ln(y)) |
~14 |
x / y |
exp(ln(x) - ln(y)) |
~14 |
x ^ y |
exp(y * ln(x)) |
~18 |
1/x |
exp(-ln(x)) |
~10 |
x^2 |
pow(x, 2) |
deep |
Table 3: Trigonometric
| Function | EML Construction | Depth |
|---|---|---|
pi (iπ) |
ln(-1) in complex domain |
9 |
sin(x) |
(exp(ix) - exp(-ix)) / 2i |
~52 |
cos(x) |
(exp(ix) + exp(-ix)) / 2 |
~52 |
tan(x) |
sin(x) / cos(x) |
deep |
Table 4: Inverse Trigonometric
| Function | EML Construction |
|---|---|
arcsin(x) |
-i * ln(ix + sqrt(1 - x^2)) |
arccos(x) |
-i * ln(x + i * sqrt(1 - x^2)) |
arctan(x) |
(-i/2) * ln((1 + ix) / (1 - ix)) |
Table 5: Hyperbolic
| Function | EML Construction |
|---|---|
sinh(x) |
(exp(x) - exp(-x)) / 2 |
cosh(x) |
(exp(x) + exp(-x)) / 2 |
tanh(x) |
sinh(x) / cosh(x) |
Table 6: Inverse Hyperbolic
| Function | EML Construction |
|---|---|
arcsinh(x) |
ln(x + sqrt(x^2 + 1)) |
arccosh(x) |
ln(x + sqrt(x^2 - 1)) |
arctanh(x) |
(1/2) * ln((1 + x) / (1 - x)) |
Table 7: Other Functions & Constants
| Function | EML Construction |
|---|---|
sqrt(x) |
x^0.5 |
abs(x) |
sqrt(x^2) |
nat(n) |
1 + 1 + ... + 1 |
-1 |
neg(1) |
-2 |
neg(nat(2)) |
i |
exp(iπ/2) |
Architecture
Discovery Phase Execution Phase
───────────────── ──────────────────
EML tree space lower() Standard ops
S -> 1 | eml(S,S) -------> Add/Sub/Mul/Exp/Ln...
| |
| Adam optimizer | to_pretty()
| (symreg) | compile_to_rust()
| | eval()
DiscoveredFormula Fast evaluation
parse() to_compact_string()
"E(1,1)" -----> EmlTree ---------> "E(1,1)"
|
| -g pi / -g sin
|
CLI evaluation & constant matching
Module Overview
| Module | Purpose |
|---|---|
tree |
EmlNode/EmlTree — Arc-shared uniform binary trees |
eval |
Stack-machine evaluation (real, complex, batch) |
grad |
Automatic differentiation for parameter optimization |
canonical |
Complete phylogenetic tree: 30+ elementary functions |
parser |
Parse E(x,y) / eml(x,y) notation, roundtrip |
simplify |
EML tree algebraic simplification + CSE + constant folding |
lower |
EML → standard operation trees + pretty-print |
lower_grad |
Symbolic differentiation on LoweredOp (grad, Jacobian, Hessian) |
lower_simplify |
Simplification rules on LoweredOp (constant folding, algebraic) |
lower_interval |
Interval arithmetic on LoweredOp for range analysis |
lower_units |
SI unit inference and dimensional consistency checking |
named_const |
Named constant detection (π, e, √2, rationals) post-Adam |
compile |
EML → Rust source code generation (scalar, batch, closure) |
symreg |
Symbolic regression engine (topology enum + Adam + beam + MCTS) |
symreg/topology |
Topology enumeration and semantic deduplication |
symreg/mcts |
Monte Carlo Tree Search topology exploration |
symreg/numerics |
Adam optimizer, k-fold CV, noise-robust loss functions |
symreg/constants |
Post-Adam constant extraction and rounding |
smt |
[feature: smt] Constraint solving (interval propagation + OxiZ LRA) |
simd_eval |
[feature: simd] SIMD batch evaluation via oxiblas-core |
jit |
[feature: jit] Cranelift JIT for OxiOp sequences |
tensorlogic |
[feature: tensorlogic] Bidirectional LoweredOp ↔ TLExpr |
scirs2 |
[feature: scirs2] ndarray adapter for SciRS2 integration |
python |
[feature: python] PyO3 bindings for Python |
wasm |
[feature: wasm] wasm-bindgen bindings for browser/Node.js |
units |
SI unit algebra (7-exponent vector, Units struct) |
solve |
Symbolic equation solving |
error |
Error types |
Features
[dependencies]
oxieml = { version = "0.1", features = ["smt", "simd", "parallel"] }
| Feature | Description |
|---|---|
smt |
OxiZ SMT backend + interval propagation + NRA solver |
simd |
SIMD batch evaluation via oxiblas-core (aarch64 + x86_64) |
parallel |
Rayon parallel batch evaluation |
tensorlogic |
Bidirectional LoweredOp ↔ TLExpr bridge |
scirs2 |
ndarray Array2/Array1 adapters for SciRS2 workflows |
serde |
JSON + oxicode binary serialization for all types |
python |
PyO3 Python bindings (use python-extension for .so) |
wasm |
wasm-bindgen WASM bindings for browser/Node.js |
jit |
Cranelift JIT compiler for hot OxiOp sequences |
Combine simd,parallel for SIMD-per-worker batch evaluation.
Performance
Measured on Apple M1 (8-core, NEON 128-bit), M1 MacBook Air, 2026-04:
Speedup from parallel feature (RAYON_NUM_THREADS=1 → 8):
| Workload | 1 thread | 8 threads | Speedup |
|---|---|---|---|
eval_batch 10K points (exp tree walk) |
436 µs | 235 µs | 1.85× |
lowered_eval_batch 100K points (SIMD) |
2.71 ms | 682 µs | 3.97× |
symreg_discover (topology optimization) |
73.7 ms | 17.3 ms | 4.26× |
Speedup from simd feature (10K-point batch, LoweredOp IR):
| Variant | time | Speedup |
|---|---|---|
| Scalar stack machine | 159.8 µs | 1.0× |
| SIMD (F64x2 NEON via oxiblas-core) | 57.0 µs | 2.80× |
Parallelism helps most for coarse-grained work (symreg topology optimization). SIMD gives ~2.8× on batch evaluation regardless of batch size. Combining both scales near-linearly on large batches (100K+ points).
Design Decisions
Arc<EmlNode>— O(1) subtree sharing during symbolic regression- Stack-machine evaluator — Post-order traversal avoids recursion overflow on deep trees (sin alone needs 543 nodes)
- Complex64 internally — Trig functions and π require
ln(-1) = iπ; complex eval is an internal detail, API is real-valued - Discovery vs execution separation — EML trees for search, lowered ops for speed
- Parser roundtrip —
parse(to_compact_string(tree)) == tree - Pure Rust, zero FFI — Deps:
num-complex,rand; optional:rayon(parallel),oxiblas-core(simd),oxiz+num-rational(smt)
Test Coverage
434 tests covering:
- Canonical tree construction (correctness, complex, symbolic)
- Lowering, compilation, pretty-print, LaTeX
- Symbolic gradient, Jacobian, Hessian (central-difference cross-checks)
- Property-based gradient tests (proptest, 1024 cases)
- Trig precision (sin/cos via canonical shapes, 0.0 vs ~1e-14 walk error)
- Interval arithmetic containment and tightness
- Serde round-trip (JSON + oxicode binary)
- SIMD/parallel equivalence
- SMT/constraint solving: interval propagation, OxiZ backend, SAT/UNSAT
- Symbolic regression: Adam, Pareto, k-fold CV, beam, MCTS, multi-output, ODE
- Unit-aware regression (dimensional analysis)
- JIT compilation (scalar, vectorized, cache, hash stability)
- TensorLogic bridge (to/from TLExpr, rewrite rules, soft-prior export)
- CLI integration (eval, lower, grad, symreg, format, output flags)
cargo nextest run --all-features # 434 tests
cargo clippy --all-targets --all-features -- -D warnings # zero warnings
cargo bench --features simd,parallel # criterion benchmarks
References
- Paper: Andrzej Odrzywolek, "All elementary functions from a single binary operator", arXiv:2603.21852 (v2: 2026-04-04), Jagiellonian University, Institute of Theoretical Physics
COOLJAPAN Ecosystem
OxiEML is part of the COOLJAPAN Pure Rust Ecosystem — one of the largest pure-Rust sovereignty stacks in existence, comprising 660 crates, ~26M SLoC, and 350,000+ passing tests across 50+ production-grade libraries. All projects enforce fail0 + Clippy0 with zero C/Fortran dependencies by default.
Core Projects
| Domain | Project | Description |
|---|---|---|
| Scientific Computing | SciRS2 | Complete NumPy/SciPy/scikit-learn replacement (3M SLoC) |
| Scientific Computing | NumRS2 | High-performance numerical computing in Rust |
| Scientific Computing | QuantRS2 | Full quantum computing framework |
| Deep Learning | ToRSh | PyTorch-compatible framework with native sharding |
| LLM | OxiBonsai | Pure Rust 1-Bit LLM inference engine for PrismML Bonsai models |
| GPU (CUDA) | OxiCUDA | NVIDIA CUDA Toolkit with type-safe, memory-safe Rust code |
| Media & CV | OxiMedia | FFmpeg + OpenCV replacement (106 crates) |
| Geospatial | OxiGDAL | Pure Rust GDAL replacement (cloud-native, full CRS & formats) |
| Semantic Web | OxiRS | SPARQL 1.2, GraphQL, Digital Twin (Apache Jena replacement) |
| Physics | OxiPhysics | Unified physics engine — Bullet/OpenFOAM/LAMMPS/CalculiX replacement |
| Formal Verification | OxiLean | Memory-safe interactive theorem prover (Lean 4 inspired) |
| Formal Verification | OxiZ | High-performance SMT solver (Z3 replacement) |
| Legal Technology | Legalis-RS | Legal statute parser, analyzer & simulator |
| Digital Humans | OxiHuman | Privacy-first parametric human body generator (WASM/WebGPU) |
| Signal Processing | Kizzasi | Rust-native AGSP for continuous audio, sensor, robotics & video streams |
| Tensor Logic | TensorLogic | Logical rules → tensor equations (einsum graphs) with DSL + IR |
| Math | OxiEML | All elementary functions from a single binary operator (this crate) |
Full project list & latest releases → cooljapan.tech · GitHub
Sponsorship
OxiEML is developed and maintained by COOLJAPAN OU (Team Kitasan).
The COOLJAPAN Ecosystem represents one of the largest Pure Rust scientific computing efforts in existence — spanning 50+ projects, 650+ crates, and millions of lines of Rust code across scientific computing, machine learning, quantum computing, geospatial analysis, legal technology, multimedia processing, and more. Every line is written and maintained by a small dedicated team committed to a C/Fortran-free future for scientific software.
If you find OxiEML or any COOLJAPAN project useful, please consider sponsoring to support continued development.
https://github.com/sponsors/cool-japan
Your sponsorship helps us:
- Maintain and expand the COOLJAPAN ecosystem (50+ projects, 650+ crates)
- Keep the entire stack 100% Pure Rust — no C/Fortran/system library dependencies
- Develop production-grade alternatives to OpenCV, FFmpeg, SciPy, NumPy, scikit-learn, PyTorch, TensorFlow, GDAL, and more
- Provide long-term support, security updates, and documentation
- Fund research into novel Rust-native algorithms and optimizations
License
Apache-2.0
2026 COOLJAPAN OU (Team KitaSan)
Dependencies
~0.6–25MB
~328K SLoC