EvalExpr-JIT
A high-performance mathematical expression evaluator with JIT compilation and automatic differentiation support. Builds on top of evalexpr and Cranelift.
Features
- š JIT compilation for fast expression evaluation
- š Automatic differentiation (up to any order)
- š¢ Support for multiple variables with consistent ordering
- š§® Higher-order partial derivatives
- š Jacobian matrix computation
- š Batch evaluation of equation systems
This crate is still under development and the API is subject to change.
Installation
Install the crate from crates.io:
or add this to your Cargo.toml:
[]
= "0.1.2" # Replace with actual version
Quick Start
Single Equation
The Equation struct provides a simple way to evaluate mathematical expressions and compute their derivatives. Variables are automatically detected from the expression and ordered alphabetically.
use Equation;
System of Equations
The EquationSystem struct allows you to evaluate multiple equations simultaneously, sharing variables across equations for efficient computation. Variables are automatically collected from all equations and consistently ordered.
use EquationSystem;
Advanced Usage
Single Equation Derivatives
The Equation struct provides multiple ways to compute derivatives, from simple partial derivatives to higher-order mixed derivatives:
use Equation;
System Derivatives and Jacobian
The EquationSystem struct provides tools for analyzing the derivatives of multiple equations simultaneously:
use EquationSystem;
Notes on Parameters and Variables
When working with expressions that contain both parameters and independent variables, you can use derive_wrt_stack to compute derivatives with respect to parameters only. This is particularly useful for parameter estimation and optimization problems.
use Equation;
Note that variables are always sorted alphabetically when providing input values, if no specific order is provided. In the example above, the order is [a, b, x, y]. You can check the ordering using eq.sorted_variables. If you want to provide a specific order, you can use from_var_map and provide a map of variable names to indices:
let eq = from_var_map?;
API Reference
Equation
The basic struct for single equation evaluation:
new(equation: String) -> Result<Self, EquationError>eval(&self, values: &[f64]) -> Result<f64, EquationError>gradient(&self, values: &[f64]) -> Result<Vec<f64>, EquationError>hessian(&self, values: &[f64]) -> Result<Vec<Vec<f64>>, EquationError>derivative(&self, variable: &str) -> Result<JITFunction, EquationError>derive_wrt(&self, variables: &[&str]) -> Result<JITFunction, EquationError>derive_wrt_stack(&self, variables: &[&str]) -> Result<JITFunction, EquationError>
EquationSystem
For evaluating systems of equations:
new(expressions: Vec<String>) -> Result<Self, EquationError>from_var_map(expressions: Vec<String>, variable_map: &HashMap<String, u32>) -> Result<Self, EquationError>eval(&self, inputs: &[f64]) -> Result<Vec<f64>, EquationError>eval_into(&self, inputs: &[f64], output: &mut [f64]) -> Result<(), EquationError>eval_parallel(&self, input_sets: &[Vec<f64>]) -> Result<Vec<Vec<f64>>, EquationError>gradient(&self, inputs: &[f64], variable: &str) -> Result<Vec<f64>, EquationError>jacobian(&self, inputs: &[f64]) -> Result<Vec<Vec<f64>>, EquationError>jacobian_wrt(&self, inputs: &[f64], variables: &[&str]) -> Result<MatrixJITFunction, EquationError>derive_wrt(&self, variables: &[&str]) -> Result<CombinedJITFunction, EquationError>
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.