pub struct EquationSystem {
pub equations: Vec<String>,
pub asts: Vec<Expr>,
pub variable_map: HashMap<String, u32>,
pub sorted_variables: Vec<String>,
pub combined_fun: CombinedJITFunction,
pub partial_derivatives: HashMap<String, CombinedJITFunction>,
/* private fields */
}Expand description
Represents a system of mathematical equations that can be evaluated together.
Fields§
§equations: Vec<String>The original string representations of the equations
asts: Vec<Expr>The AST representations of the equations
variable_map: HashMap<String, u32>Maps variable names to their indices in the input array
sorted_variables: Vec<String>Variables in sorted order for consistent input ordering
combined_fun: CombinedJITFunctionThe JIT-compiled function that evaluates all equations
partial_derivatives: HashMap<String, CombinedJITFunction>Partial derivatives of the system - maps variable names to their derivative functions E.g. {“x”: df(x, y, z)/dx, “y”: df(x, y, z)/dy}
Implementations§
Source§impl EquationSystem
impl EquationSystem
Sourcepub fn new(expressions: Vec<String>) -> Result<Self, EquationError>
pub fn new(expressions: Vec<String>) -> Result<Self, EquationError>
Creates a new equation system from a vector of expression strings.
This constructor automatically extracts variables from the expressions and assigns them indices in alphabetical order. The resulting system can evaluate all equations efficiently and compute derivatives with respect to any variable.
§Arguments
expressions- Vector of mathematical expressions as strings
§Returns
A new EquationSystem with JIT-compiled evaluation function and derivative capabilities
§Example
let system = EquationSystem::new(vec![
"2*x + y".to_string(),
"x^2 + z".to_string()
]).unwrap();
// Evaluate system
let results = system.eval(&vec![1.0, 2.0, 3.0]).unwrap();
// Compute derivatives
let dx = system.gradient(&vec![1.0, 2.0, 3.0], "x").unwrap();Sourcepub fn from_var_map(
expressions: Vec<String>,
variable_map: &HashMap<String, u32>,
) -> Result<Self, EquationError>
pub fn from_var_map( expressions: Vec<String>, variable_map: &HashMap<String, u32>, ) -> Result<Self, EquationError>
Creates a new equation system from a vector of expressions and a variable map.
This constructor allows explicit control over variable ordering by providing a map of variable names to their indices. This is useful when you need to ensure specific variable ordering or when integrating with other systems that expect variables in a particular order.
§Arguments
expressions- Vector of mathematical expressions as stringsvariable_map- Map of variable names to their indices, defining input order
§Returns
A new EquationSystem with JIT-compiled evaluation function using the specified variable ordering
§Example
use evalexpr_jit::prelude::*;
use std::collections::HashMap;
let var_map: HashMap<String, u32> = [
("x".to_string(), 0),
("y".to_string(), 1),
("z".to_string(), 2),
].into_iter().collect();
let system = EquationSystem::from_var_map(
vec!["2*x + y".to_string(), "x^2 + z".to_string()],
&var_map
).unwrap();Sourcepub fn eval_into<V: Vector, R: Vector>(
&self,
inputs: &V,
results: &mut R,
) -> Result<(), EquationError>
pub fn eval_into<V: Vector, R: Vector>( &self, inputs: &V, results: &mut R, ) -> Result<(), EquationError>
Sourcepub fn eval_into_matrix<V: Vector, R: Matrix>(
&self,
inputs: &V,
results: &mut R,
) -> Result<(), EquationError>
pub fn eval_into_matrix<V: Vector, R: Matrix>( &self, inputs: &V, results: &mut R, ) -> Result<(), EquationError>
Evaluates all equations in the system with the given input values into a pre-allocated matrix.
This method is used when the equation system is configured to output a matrix rather than a vector. The results matrix must have the correct dimensions matching the system’s output type.
§Arguments
inputs- Input vector implementing the Vector traitresults- Pre-allocated matrix to store results
§Returns
Ok(()) if successful, or an error if the system is not configured for matrix output
Sourcepub fn eval_matrix<V: Vector, R: Matrix>(
&self,
inputs: &V,
) -> Result<R, EquationError>
pub fn eval_matrix<V: Vector, R: Matrix>( &self, inputs: &V, ) -> Result<R, EquationError>
Evaluates all equations in the system with the given input values into a new matrix.
This method allocates a new matrix with the correct dimensions and evaluates the system into it. It should only be used when the equation system is configured to output a matrix.
§Arguments
inputs- Input vector implementing the Vector trait
§Returns
Matrix containing the evaluated results, or an error if the system is not configured for matrix output
Sourcepub fn eval_parallel<V: Vector + Send + Sync>(
&self,
input_sets: &[V],
) -> Result<Vec<V>, EquationError>
pub fn eval_parallel<V: Vector + Send + Sync>( &self, input_sets: &[V], ) -> Result<Vec<V>, EquationError>
Sourcepub fn gradient(
&self,
inputs: &[f64],
variable: &str,
) -> Result<Vec<f64>, EquationError>
pub fn gradient( &self, inputs: &[f64], variable: &str, ) -> Result<Vec<f64>, EquationError>
Returns the gradient of the equation system with respect to a specific variable.
The gradient contains the partial derivatives of all equations with respect to the given variable, evaluated at the provided input values. This is equivalent to one row of the Jacobian matrix.
§Arguments
inputs- Slice of input values at which to evaluate the gradientvariable- Name of the variable to compute derivatives with respect to
§Returns
Vector containing the partial derivatives of each equation with respect to the specified variable, evaluated at the given input values
§Example
use evalexpr_jit::prelude::*;
let system = EquationSystem::new(vec![
"x^2*y".to_string(), // f1
"x*y^2".to_string(), // f2
]).unwrap();
let gradient = system.gradient(&[2.0, 3.0], "x").unwrap();
// gradient contains [12.0, 9.0] (∂f1/∂x, ∂f2/∂x)Sourcepub fn eval_jacobian(
&self,
inputs: &[f64],
variables: Option<&[String]>,
) -> Result<Vec<Vec<f64>>, EquationError>
pub fn eval_jacobian( &self, inputs: &[f64], variables: Option<&[String]>, ) -> Result<Vec<Vec<f64>>, EquationError>
Computes the Jacobian matrix of the equation system at the given input values.
The Jacobian matrix contains all first-order partial derivatives of the system. Each row corresponds to an equation, and each column corresponds to a variable. The entry at position (i,j) is the partial derivative of equation i with respect to variable j.
§Arguments
inputs- Slice of input values at which to evaluate the Jacobianvariables- Optional slice of variable names to include in the Jacobian. If None, includes all variables in sorted order.
§Returns
The Jacobian matrix as a vector of vectors, where each inner vector contains the partial derivatives of one equation with respect to all variables
§Example
use evalexpr_jit::prelude::*;
let system = EquationSystem::new(vec![
"x^2*y".to_string(), // f1
"x*y^2".to_string(), // f2
]).unwrap();
let jacobian = system.eval_jacobian(&[2.0, 3.0], None).unwrap();
// jacobian[0] contains [12.0, 4.0] // ∂f1/∂x, ∂f1/∂y
// jacobian[1] contains [9.0, 12.0] // ∂f2/∂x, ∂f2/∂ySourcepub fn jacobian_wrt(
&self,
variables: &[&str],
) -> Result<EquationSystem, EquationError>
pub fn jacobian_wrt( &self, variables: &[&str], ) -> Result<EquationSystem, EquationError>
Creates a new equation system that computes the Jacobian matrix with respect to specific variables.
This method creates a new equation system optimized for computing partial derivatives with respect to a subset of variables. The resulting system evaluates all equations’ derivatives with respect to the specified variables and arranges them in matrix form.
§Arguments
variables- Slice of variable names to include in the Jacobian matrix
§Returns
A new EquationSystem that computes the Jacobian matrix when evaluated. The output matrix
has dimensions [n_equations × n_variables], where each row contains the derivatives
of one equation with respect to the specified variables.
§Errors
Returns EquationError::VariableNotFound if any of the specified variables doesn’t exist
in the system.
§Example
use evalexpr_jit::prelude::*;
use ndarray::Array2;
let system = EquationSystem::new(vec![
"x^2*y + z".to_string(), // f1
"x*y^2 - z^2".to_string(), // f2
]).unwrap();
// Create Jacobian system for x and y only
let jacobian_system = system.jacobian_wrt(&["x", "y"]).unwrap();
// Prepare matrix to store results (2 equations × 2 variables)
let mut results = Array2::zeros((2, 2));
// Evaluate Jacobian at point (x=2, y=3, z=1)
jacobian_system.eval_into_matrix(&[2.0, 3.0, 1.0], &mut results).unwrap();
// results now contains:
// [
// [12.0, 4.0], // [∂f1/∂x, ∂f1/∂y]
// [9.0, 12.0], // [∂f2/∂x, ∂f2/∂y]
// ]§Performance Notes
- The returned system is JIT-compiled and optimized for repeated evaluations
- Pre-allocate the results matrix and reuse it for better performance
- The matrix dimensions will be
[n_equations × n_variables]
Sourcepub fn derive_wrt(
&self,
variables: &[&str],
) -> Result<EquationSystem, EquationError>
pub fn derive_wrt( &self, variables: &[&str], ) -> Result<EquationSystem, EquationError>
Creates a new equation system containing the higher-order derivatives of all equations with respect to multiple variables.
This method allows computing mixed partial derivatives by specifying the variables in the order of differentiation. For example, passing [“x”, “y”] computes ∂²f/∂x∂y for each equation f.
§Arguments
variables- Slice of variable names to differentiate with respect to, in order
§Returns
A JIT-compiled function that computes the higher-order derivatives
§Example
let system = EquationSystem::new(vec![
"x^2*y".to_string(), // f1
"x*y^2".to_string(), // f2
]).unwrap();
let derivatives = system.derive_wrt(&["x", "y"]).unwrap();
let mut results = Array1::zeros(2);
derivatives.eval_into(&vec![2.0, 3.0], &mut results).unwrap();
assert_eq!(results.as_slice().unwrap(), vec![4.0, 6.0]); // ∂²f1/∂x∂y = 2x, ∂²f2/∂x∂y = 2ypub fn validate_matrix_dimensions( &self, n_rows: usize, n_cols: usize, ) -> Result<(), EquationError>
Sourcepub fn sorted_variables(&self) -> &[String]
pub fn sorted_variables(&self) -> &[String]
Returns the sorted variables in the system.
Sourcepub fn variables(&self) -> &HashMap<String, u32>
pub fn variables(&self) -> &HashMap<String, u32>
Returns the map of variable names to their indices.
Sourcepub fn fun(&self) -> &CombinedJITFunction
pub fn fun(&self) -> &CombinedJITFunction
Returns the compiled evaluation function.
Sourcepub fn jacobian_funs(&self) -> &HashMap<String, CombinedJITFunction>
pub fn jacobian_funs(&self) -> &HashMap<String, CombinedJITFunction>
Returns the map of variable names to their derivative functions.
Sourcepub fn gradient_fun(&self, variable: &str) -> &CombinedJITFunction
pub fn gradient_fun(&self, variable: &str) -> &CombinedJITFunction
Returns the derivative function for a specific variable.
Sourcepub fn num_equations(&self) -> usize
pub fn num_equations(&self) -> usize
Returns the number of equations in the system.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for EquationSystem
impl !RefUnwindSafe for EquationSystem
impl Send for EquationSystem
impl Sync for EquationSystem
impl Unpin for EquationSystem
impl !UnwindSafe for EquationSystem
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more