multicalc
multicalc is a Rust library for single- and multi-variable calculus: derivatives, integrals,
Jacobians and Hessians, vector-field operators, and Taylor approximation in a no-std environment.
Why use it
- Pure, safe Rust.
no_std, with no heap allocation and no panics — it runs on bare-metal and embedded targets.- Transcendental functions come from
libm, so the math works withoutstd. - Every fallible call returns a typed
CalcError; convenience wrappers fill in sensible defaults. - A runnable example for every module, and a test suite covering each error path.
What it does
- Differentiation of any order (finite differences), total and partial.
- Integration of any order:
- Iterative rules — Boole, Simpson, Trapezoidal — over finite, semi-infinite, and infinite limits.
- Gaussian quadrature — Gauss-Legendre, Gauss-Hermite, Gauss-Laguerre.
- Jacobian and Hessian matrices.
- Vector calculus — line and flux integrals, curl, and divergence.
- Approximation — linear and quadratic (Taylor) models, with goodness-of-fit metrics.
Install
Enable the alloc feature if you want the heap-based methods (see Heap allocation).
A note on no_std
Methods like f64::sin are only available with std. In a no_std crate, call the libm versions
instead — for example libm::sin(x) in place of x.sin(). multicalc re-exports libm, so you can
reach it as multicalc::libm. The examples below use x.sin() because they assume std.
At a glance
Derivatives
use DerivatorSingleVariable;
use FiniteDifferenceSingle;
let f = ; // f(x) = x^3
let d = default; // central difference, default step size
let first = d.get.unwrap; // 12.0
let third = d.get.unwrap; // 6.0
// get_single / get_double are wrappers for orders 1 and 2
For several variables, the derivative order is just the number of indices you pass:
use DerivatorMultiVariable;
use FiniteDifferenceMulti;
// g(x, y, z) = y*sin(x) + x*cos(y) + x*y*e^z
let g = ;
let d = default;
let point = ;
let dx = d.get_single_partial.unwrap; // dg/dx
let mixed = d.get.unwrap; // d(dg/dx)/dy
Integration
use IntegratorSingleVariable;
use IterativeSingle;
let f = ;
let integrator = default; // Boole's rule, 120 intervals
let area = integrator.get_single.unwrap; // 4.0
// infinite and semi-infinite limits are supported for decaying integrands
let bell = integrator
.get_single
.unwrap; // sqrt(pi)
Choose the rule and interval count with from_parameters:
use IterativeMethod;
let integrator = from_parameters;
Gaussian quadrature
Each Gaussian rule integrates over a fixed domain. Pass the bare integrand f(x) — the weights
already carry the weighting factor.
use IntegratorSingleVariable;
use GaussianSingle;
use GaussianQuadratureMethod;
// Gauss-Hermite integrates f(x) * e^(-x^2) over the whole real line.
let hermite = from_parameters;
let val = hermite
.get_single
.unwrap; // sqrt(pi)/2
| Rule | Computes |
|---|---|
| Gauss-Legendre | $\int_a^b f(x), \mathrm{d}x$ |
| Gauss-Laguerre | $\int_0\infty f(x), e{-x}, \mathrm{d}x$ |
| Gauss-Hermite | $\int_{-\infty}\infty f(x), e{-x^2}, \mathrm{d}x$ |
Jacobian and Hessian
use FiniteDifferenceMulti;
use Jacobian;
use Hessian;
let f1 = ;
let f2 = ;
let functions: = ;
let jacobian = default;
let j = jacobian.get.unwrap; // [[6, 3, 2], [2, 4, 0]]
let g = ;
let hessian = default;
let h = hessian.get.unwrap;
Vector calculus
use FiniteDifferenceMulti;
use ;
// field (2xy, 3cos y)
let field: =
;
let derivator = default;
let c = get_2d.unwrap;
let d = get_2d.unwrap;
// field (y, -x) along the unit circle (cos t, sin t)
let g: = ;
let curve: = ;
let limit = ;
let line = get_2d.unwrap; // -2*pi
let flux = get_2d.unwrap; // 0
Approximation
use LinearApproximator;
use FiniteDifferenceMulti;
let f = ;
let model = default
.get
.unwrap;
let y = model.predict;
// model.get_prediction_metrics(&samples, &f) returns RMSE, R^2, and more
QuadraticApproximator works the same way and captures curvature as well.
Error handling
Where a sensible default exists, a "safe" wrapper (such as get_single or get_double) returns the
answer directly. Otherwise the call returns Result<f64, CalcError>, so you decide how to handle bad
input. All variants are listed in error_codes.rs.
Heap allocation
By default everything uses fixed-size stack arrays. Enable the alloc feature for Vec-based methods
that handle inputs too large for the stack. This currently covers the Jacobian's get_on_heap, which
returns a Vec<Vec<f64>>.
Examples
Runnable, self-contained programs for each module live in examples/ — see
examples/README.md. Run one with:
Benchmarks
See BENCHMARKS.md for accuracy figures and measured latency.
Contributing
See CONTRIBUTIONS.md.
License
multicalc is licensed under the MIT license.