EvalContext

Struct EvalContext 

Source
pub struct EvalContext {
    pub variables: HashMap<String, Expression>,
    pub numeric: bool,
    pub precision: u32,
    pub simplify_first: bool,
}
Expand description

Evaluation context

Controls how Expression::evaluate_with_context() behaves. Provides variable substitutions, numerical evaluation control, and simplification options.

This mirrors SymPy’s evalf(subs={...}, ...) high-level API.

§Two-Level Architecture

The context enables separation of concerns:

  1. Variable substitution: Replace symbols with values before evaluation
  2. Simplification control: Optionally simplify symbolically first
  3. Numerical evaluation: Convert to numerical form if requested

§Examples

use mathhook_core::{expr, symbol};
use mathhook_core::core::expression::eval_numeric::EvalContext;
use std::collections::HashMap;

// Symbolic evaluation (no numerical conversion)
let ctx = EvalContext::symbolic();
assert!(!ctx.numeric);
assert!(ctx.variables.is_empty());

// Numerical evaluation with substitutions
let mut vars = HashMap::new();
vars.insert("x".to_string(), expr!(5));
let ctx = EvalContext::numeric(vars);
assert!(ctx.numeric);
assert_eq!(ctx.variables.len(), 1);

// Custom precision
let ctx = EvalContext::symbolic().with_precision(128);
assert_eq!(ctx.precision, 128);

Fields§

§variables: HashMap<String, Expression>

Variable substitutions (symbol name → value)

Before evaluation, all symbols matching these names will be replaced with the provided expressions. This enables parameterized evaluation.

§Examples

use std::collections::HashMap;
use mathhook_core::{expr, Expression};

let mut vars = HashMap::new();
vars.insert("x".to_string(), expr!(3));
vars.insert("y".to_string(), expr!(4));
// Now evaluating "x + y" will substitute → "3 + 4" → "7"
§numeric: bool

Whether to perform numerical evaluation (evalf-style)

  • true: Convert to numerical form using eval_numeric()
  • false: Keep symbolic form (only substitute variables)
§precision: u32

Precision for numerical operations (bits)

Controls accuracy of floating-point operations:

  • 53 bits: f64 precision (default)
  • 64 bits: Extended precision
  • 128+ bits: Arbitrary precision (future)

Note: Current implementation uses f64, so precision >53 has no effect yet. Future versions will support arbitrary precision via rug or mpc.

§simplify_first: bool

Whether to simplify symbolically before numerical evaluation

  • true: Call simplify() before eval_numeric() (recommended)
  • false: Evaluate directly without simplification

Simplification often improves numerical stability by reducing expression complexity.

Implementations§

Source§

impl EvalContext

Source

pub fn symbolic() -> Self

Create context for symbolic evaluation (no numerical conversion)

Returns a context that performs variable substitution but keeps expressions in symbolic form. No numerical evaluation is performed.

§Returns

Context with:

  • No variable substitutions
  • Symbolic mode (numeric = false)
  • Default precision (53 bits)
  • No pre-simplification
§Examples
use mathhook_core::{expr, symbol};
use mathhook_core::core::expression::eval_numeric::EvalContext;

let x = symbol!(x);
let e = expr!((x ^ 2) + (2*x) + 1);

let ctx = EvalContext::symbolic();
let result = e.evaluate_with_context(&ctx).unwrap();
// Result is still symbolic: x^2 + 2*x + 1
Source

pub fn numeric(variables: HashMap<String, Expression>) -> Self

Create context for numerical evaluation with substitutions

Returns a context that substitutes variables and converts to numerical form. Simplification is enabled by default for numerical stability.

§Arguments
  • variables - Map from symbol name to replacement expression
§Returns

Context with:

  • Provided variable substitutions
  • Numerical mode (numeric = true)
  • Default precision (53 bits for f64)
  • Pre-simplification enabled (simplify_first = true)
§Examples
use mathhook_core::{expr, symbol};
use mathhook_core::core::expression::eval_numeric::EvalContext;
use std::collections::HashMap;

let x = symbol!(x);
let e = expr!((x ^ 2) + (2*x) + 1);

let mut vars = HashMap::new();
vars.insert("x".to_string(), expr!(3));

let ctx = EvalContext::numeric(vars);
let result = e.evaluate_with_context(&ctx).unwrap();
// Result is numerical: 16 (= 3^2 + 2*3 + 1)
Source

pub fn with_precision(self, precision: u32) -> Self

Set precision for numerical operations (bits)

Consumes self and returns a new context with the specified precision.

§Arguments
  • precision - Number of bits of precision (53 for f64, 128+ for arbitrary precision)
§Returns

New context with updated precision

§Examples
use mathhook_core::core::expression::eval_numeric::EvalContext;

let ctx = EvalContext::symbolic().with_precision(128);
assert_eq!(ctx.precision, 128);
Source

pub fn with_simplify(self, simplify: bool) -> Self

Control whether to simplify symbolically before numerical evaluation

Consumes self and returns a new context with the specified simplification flag.

§Arguments
  • simplify - Whether to call simplify() before eval_numeric()
§Returns

New context with updated simplification setting

§Examples
use mathhook_core::core::expression::eval_numeric::EvalContext;

// Disable simplification for performance
let ctx = EvalContext::symbolic().with_simplify(false);
assert!(!ctx.simplify_first);

// Enable simplification for numerical stability
let ctx = EvalContext::symbolic().with_simplify(true);
assert!(ctx.simplify_first);

Trait Implementations§

Source§

impl Clone for EvalContext

Source§

fn clone(&self) -> EvalContext

Returns a duplicate of the value. Read more
1.0.0§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for EvalContext

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for EvalContext

Source§

fn default() -> Self

Default context is symbolic (no numerical evaluation)

§Examples
use mathhook_core::core::expression::eval_numeric::EvalContext;

let ctx = EvalContext::default();
assert!(!ctx.numeric);
assert!(ctx.variables.is_empty());

Auto Trait Implementations§

Blanket Implementations§

§

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

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

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

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

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

§

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

Mutably borrows from an owned value. Read more
§

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

§

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
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

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

§

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
§

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

§

type Owned = T

The resulting type after obtaining ownership.
§

fn to_owned(&self) -> T

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

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

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

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

§

type Error = Infallible

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

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

Performs the conversion.
§

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

§

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

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

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

Performs the conversion.