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:
- Variable substitution: Replace symbols with values before evaluation
- Simplification control: Optionally simplify symbolically first
- 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: boolWhether to perform numerical evaluation (evalf-style)
true: Convert to numerical form usingeval_numeric()false: Keep symbolic form (only substitute variables)
precision: u32Precision 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: boolWhether to simplify symbolically before numerical evaluation
true: Callsimplify()beforeeval_numeric()(recommended)false: Evaluate directly without simplification
Simplification often improves numerical stability by reducing expression complexity.
Implementations§
Source§impl EvalContext
impl EvalContext
Sourcepub fn symbolic() -> Self
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 + 1Sourcepub fn numeric(variables: HashMap<String, Expression>) -> Self
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)Sourcepub fn with_precision(self, precision: u32) -> Self
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);Sourcepub fn with_simplify(self, simplify: bool) -> Self
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 callsimplify()beforeeval_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
impl Clone for EvalContext
Source§fn clone(&self) -> EvalContext
fn clone(&self) -> EvalContext
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for EvalContext
impl Debug for EvalContext
Auto Trait Implementations§
impl Freeze for EvalContext
impl RefUnwindSafe for EvalContext
impl Send for EvalContext
impl Sync for EvalContext
impl Unpin for EvalContext
impl UnwindSafe for EvalContext
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