formulac
formulac is a Rust library for parsing, evaluating, and differentiating mathematical expressions.
It supports complex numbers, user-defined functions, and higher-order derivatives.
Ideal for symbolic computation, mathematical simulations, and evaluating formulas in Rust applications.
Features
- Complex number support — Evaluate expressions involving real and imaginary components using
num_complex::Complex<f64>. - Reverse Polish Notation (RPN) — Converts infix expressions to RPN using the Shunting-Yard algorithm for efficient evaluation.
- Built-in mathematical operators & functions — Supports
+,-,*,/,^, and standard functions likesin,cos,exp,log, and more. Seesrc/parser.rsor API Overview for the list of available functions, constants, and operator symbols. - Unary & Binary operators — Unary operators (
+,-) and binary operators (+,-,*,/,^) are represented asUnaryOperatorKindandBinaryOperatorKind. - Abstract Syntax Tree (AST) — Expressions are parsed into
AstNodestructures, enabling inspection, simplification, and compilation into executable closures. - User-defined functions — Easily register custom functions or constants at runtime using a simple API (
UserDefinedTable). - Differentiation support — Parse and evaluate differential expressions using the
diffoperator (e.g.,diff(sin(x), x)). - Safe and dependency-light — No use of unsafe Rust or heavyweight external parsers.
Usage
Add to your Cargo.toml:
Basic Example
use Complex;
use ;
Registering a Custom Function
use Complex;
use ;
Differentiation Support
formulac can represent derivative expressions in the AST.
Built-in functions (e.g. sin, cos, exp, log, …) already have derivative rules,
but user-defined functions require the user to explicitly register their derivative form.
Note on Differential Order:
- Only integer-order derivatives are supported; fractional derivatives are not allowed.
- The maximum allowed order is
i8::MAX(127). Attempting to compute a derivative higher than this will result in a runtime error.
Differentiation Example
You can directly write differentiation expressions using the diff operator:
use Complex;
use ;
When computing derivatives of order 2 or higher, specify the order:
use Complex;
use ;
Example: User-defined function with derivative
You can define your own functions and provide derivatives for them. The derivative must be registered in the same order as the function arguments.
use Complex;
use ;
Example: Multi-variable functions (Partial derivatives)
For functions with multiple variables, you can register partial derivatives with respect to each argument. Use the same order as the function arguments.
use Complex;
use ;
Core Types & API Overview
-
compileCompiles a formula string into a Rust closureFn(&[Complex<f64>]) -> Complex<f64>that evaluates the expression for given variable values. -
VariablesA lookup table mapping variable names (strings) toComplex<f64>values, used during parsing. -
UserDefinedTableAllows registration of custom functions under user-defined names for use in expressions.
Available mathematical constants
| String | Value | Description |
|---|---|---|
E |
e |
The base of natural logarithm (≈ 2.71828) |
FRAC_1_PI |
1 / π |
Reciprocal of π |
FRAC_1_SQRT_2 |
1 / √2 |
Reciprocal of square root of 2 |
FRAC_2_PI |
2 / π |
2 divided by π |
FRAC_2_SQRT_PI |
2 / √π |
2 divided by square root of π |
FRAC_PI_2 |
π / 2 |
Half of π |
FRAC_PI_3 |
π / 3 |
One-third of π |
FRAC_PI_4 |
π / 4 |
One-fourth of π |
FRAC_PI_6 |
π / 6 |
One-sixth of π |
FRAC_PI_8 |
π / 8 |
One-eighth of π |
LN_2 |
ln(2) |
Natural logarithm of 2 |
LN_10 |
ln(10) |
Natural logarithm of 10 |
LOG2_10 |
log2(10) |
Base-2 logarithm of 10 |
LOG2_E |
log2(e) |
Base-2 logarithm of e |
LOG10_2 |
log10(2) |
Base-10 logarithm of 2 |
LOG10_E |
log10(e) |
Base-10 logarithm of e |
PI |
π |
Ratio of circle circumference to diameter |
SQRT_2 |
√2 |
Square root of 2 |
TAU |
2 * π |
Full circle in radians |
Available unary operators
| String | Function | Description |
|---|---|---|
+ |
Positive |
Identity operator |
- |
Negative |
Negation operator |
Available binary operators
| String | Function | Description |
|---|---|---|
+ |
Add |
Addition |
- |
Sub |
Subtraction |
* |
Mul |
Multiplication |
/ |
Div |
Division |
^ |
Pow |
Power (x^y) |
Available Functions
| String | Function | Description |
|---|---|---|
sin |
Sin(x) |
Sine function |
cos |
Cos(x) |
Cosine function |
tan |
Tan(x) |
Tangent function |
asin |
Asin(x) |
Arc sine |
acos |
Acos(x) |
Arc cosine |
atan |
Atan(x) |
Arc tangent |
sinh |
Sinh(x) |
Hyperbolic sine |
cosh |
Cosh(x) |
Hyperbolic cosine |
tanh |
Tanh(x) |
Hyperbolic tangent |
asinh |
Asinh(x) |
Hyperbolic arcsine |
acosh |
Acosh(x) |
Hyperbolic arccosine |
atanh |
Atanh(x) |
Hyperbolic arctangent |
exp |
Exp(x) |
Exponential function e^x |
ln |
Ln(x) |
Natural logarithm |
log10 |
Log10(x) |
Base-10 logarithm |
sqrt |
Sqrt(x) |
Square root |
abs |
Abs(x) |
Absolute value |
conj |
Conj(x) |
Complex conjugate |
pow |
Pow(x, y) |
x raised to y (complex exponent) |
powi |
Powi(x, n) |
x raised to integer n |
Available differential operator
| String | Function | Description |
|---|---|---|
diff(f, x) |
diff(f, x) |
First-order derivative of f with respect to x |
diff(f, x, n) |
diff(f, x, n) |
n-th order derivative of f with respect to x (max i8::MAX) |
Benchmarking
The formulac crate provides benchmarks using the Criterion crate to measure both compilation and execution performance.
Note:
- Criterion is a dev-dependency, so benchmarks are only available in development builds.
- :warning: Some benchmarks (e.g., 1000 nested operations) may take longer to run.
- Benchmarks require the
criterioncrate as a dev-dependency and are intended for development/testing purposes only.
Benchmark Source
The benchmarks are located in benches/benches.rs and cover:
- Linear expressions (many operands like polynomials)
- Nested expressions (e.g., sin(sin(...)))
- Numeric literals
- Expressions with and without parentheses
- Many variable references (up to 100 variables)
- Differentiate expressions
- Invalid expressions (error cases)
- Practical expressions (polynomials, wave functions, exponential decay)
- Comparison of direct calls vs. parsed calls for standard functions (sin, cos, pow, etc.)
Run Benchmarks
Run the benchmarks with:
Both compile and exec times are measured. Criterion generates detailed statistics and plots in target/criterion.
Viewing Results
Open the generated HTML report in a browser to view benchmark results and comparisons:
License
Licensed under MIT OR Apache-2.0 — choose the license that best suits your project.
Contribution & Contact
Contributions, feature requests, and bug reports are welcome! Please feel free to open issues or submit pull requests via the GitHub repository.