EquationSystem

Struct EquationSystem 

Source
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: CombinedJITFunction

The 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

Source

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();
Source

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 strings
  • variable_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();
Source

pub fn eval_into<V: Vector, R: Vector>( &self, inputs: &V, results: &mut R, ) -> Result<(), EquationError>

Evaluates all equations in the system with the given input values into a pre-allocated buffer.

§Arguments
  • inputs - Input vector implementing the Vector trait
  • results - Pre-allocated vector to store results
§Returns

Reference to the results vector containing the evaluated values

Source

pub fn eval<V: Vector>(&self, inputs: &V) -> Result<V, EquationError>

Evaluates all equations in the system with the given input values. Allocates a new vector for results.

§Arguments
  • inputs - Input vector implementing the Vector trait
§Returns

Vector of results, one for each equation in the system

Source

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 trait
  • results - Pre-allocated matrix to store results
§Returns

Ok(()) if successful, or an error if the system is not configured for matrix output

Source

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

Source

pub fn eval_parallel<V: Vector + Send + Sync>( &self, input_sets: &[V], ) -> Result<Vec<V>, EquationError>

Evaluates the equation system in parallel for multiple input sets.

§Arguments
  • input_sets - Slice of input vectors, each must match the number of variables
§Returns

Vector of result vectors, one for each input set

Source

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 gradient
  • variable - 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)
Source

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 Jacobian
  • variables - 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/∂y
Source

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]
Source

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 = 2y
Source

pub fn validate_matrix_dimensions( &self, n_rows: usize, n_cols: usize, ) -> Result<(), EquationError>

Source

pub fn sorted_variables(&self) -> &[String]

Returns the sorted variables in the system.

Source

pub fn variables(&self) -> &HashMap<String, u32>

Returns the map of variable names to their indices.

Source

pub fn equations(&self) -> &[String]

Returns the original equation strings.

Source

pub fn fun(&self) -> &CombinedJITFunction

Returns the compiled evaluation function.

Source

pub fn jacobian_funs(&self) -> &HashMap<String, CombinedJITFunction>

Returns the map of variable names to their derivative functions.

Source

pub fn gradient_fun(&self, variable: &str) -> &CombinedJITFunction

Returns the derivative function for a specific variable.

Source

pub fn num_equations(&self) -> usize

Returns the number of equations in the system.

Trait Implementations§

Source§

impl Clone for EquationSystem

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.