Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Nonanti/mathcore/llms.txt

Use this file to discover all available pages before exploring further.

MathCore lets you go beyond purely numeric expressions by injecting named variables at evaluation time. Whether you’re computing a distance formula, evaluating a polynomial at multiple points, or building a reusable context with physical constants, MathCore’s variable system is straightforward and composable — and works identically whether you’re on std or a bare-metal no_std target.

Evaluating with Variables

evaluate_with_vars()

The most direct way to substitute variables is evaluate_with_vars, which accepts a reference to a HashMap<String, f64> alongside the expression string.
pub fn evaluate_with_vars(
    &self,
    expression: &str,
    vars: &HashMap<String, f64>,
) -> Result<f64, MathError>
The method parses the expression, substitutes every key in vars with its corresponding f64 value, and then runs the evaluator. The result is either a numeric f64 or a MathError if a variable is undefined, the expression is malformed, or evaluation would overflow. Example — Pythagorean distance:
use mathcore::MathCore;
use mathcore::prelude::*;

let math = MathCore::new();
let mut vars = HashMap::new();
vars.insert("a".to_string(), 3.0);
vars.insert("b".to_string(), 4.0);

let result = math.evaluate_with_vars("sqrt(a^2 + b^2)", &vars).unwrap();
println!("Distance: {}", result); // 5
evaluate_with_vars only replaces symbols that appear in vars. Any symbol not present in the map that is also not a built-in constant (like pi) will cause a MathError::UndefinedVariable.

Multivariate Expressions

You can include as many variables as your expression requires. All of them are substituted in a single pass before evaluation.
use mathcore::MathCore;
use mathcore::prelude::*;

let math = MathCore::new();
let mut vars = HashMap::new();
vars.insert("x".to_string(), 3.0);
vars.insert("y".to_string(), 4.0);

// Computes sqrt(9 + 16) = 5
let dist = math.evaluate_with_vars("sqrt(x^2 + y^2)", &vars).unwrap();
assert_eq!(dist, 5.0);
This pattern extends naturally to any number of dimensions — just keep adding entries to the map.

The Context Type

For more structured use-cases — where you want a persistent set of named values, or you need to pre-load constants before evaluating a batch of expressions — MathCore provides the Context type defined in mathcore::types.

Creating a Context

use mathcore::types::Context;

// Empty context — no variables defined yet
let ctx = Context::new();

Context::with_defaults()

The recommended starting point is with_defaults(), which pre-populates the context with MathCore’s three built-in mathematical constants:
ConstantValueSource
pi3.141592653589793core::f64::consts::PI
e2.718281828459045core::f64::consts::E
tau6.283185307179586core::f64::consts::TAU
use mathcore::types::Context;

let ctx = Context::with_defaults();

// "pi", "e", and "tau" are ready to use
let pi_val = ctx.get_var("pi");
assert!(pi_val.is_some());
The Engine created by MathCore::new() already uses a Context::with_defaults() internally, so pi, e, and tau are always available in expressions without any extra setup.

Setting and Retrieving Variables

use mathcore::types::{Context, Expr};

let mut ctx = Context::with_defaults();

// Store a named value
ctx.set_var("radius", Expr::Number(5.0));

// Retrieve it later
if let Some(r) = ctx.get_var("radius") {
    println!("radius = {}", r); // radius = 5
}
set_var takes a &str name and an Expr value. Any Expr variant is valid, including symbolic expressions, so you can store unevaluated sub-expressions for later composition. get_var returns Option<&Expr>None if the name has never been set.

Building a Context for Multiple Evaluations

1
Create a context with defaults
2
use mathcore::types::{Context, Expr};

let mut ctx = Context::with_defaults();
3
Insert your domain variables
4
ctx.set_var("g", Expr::Number(9.81));   // gravitational acceleration (m/s²)
ctx.set_var("m", Expr::Number(10.0));   // mass in kg
5
Construct an engine from the context and evaluate
6
use mathcore::engine::Engine;

let engine = Engine::with_context(ctx);
let expr = mathcore::MathCore::parse("m * g").unwrap();
let force = engine.evaluate(&expr).unwrap();
println!("Force: {} N", force); // Force: 98.1 N

Using Built-in Constants in Expressions

Because pi, e, and tau live in the default context, you can reference them directly in any expression string passed to calculate, evaluate, or evaluate_with_vars:
use mathcore::MathCore;

let math = MathCore::new();

// pi is pre-defined in the default context
println!("{:.4}", math.calculate("cos(pi)").unwrap());   // -1.0000
println!("{:.4}", math.calculate("sin(tau/4)").unwrap()); // 1.0000
println!("{:.4}", math.calculate("exp(1) - e").unwrap()); // 0.0000

no_std HashMap Compatibility

MathCore is #![no_std] at its core. The HashMap<K, V> type exported from mathcore and re-exported through mathcore::prelude is feature-conditional:
// When the "std" feature is active:
pub type HashMap<K, V> = std::collections::HashMap<K, V>;

// When running no_std (alloc only):
pub type HashMap<K, V> = alloc::collections::BTreeMap<K, V>;
Your call-site code does not need to change — just import from the prelude and the right backing type is selected at compile time:
use mathcore::prelude::*; // always gives you the right HashMap

let mut vars = HashMap::new();
vars.insert("x".to_string(), 2.0);
BTreeMap requires its keys to implement Ord, which String already does, so variable maps work without modification. Be aware that BTreeMap has O(log n) lookup instead of O(1), but for typical variable counts this is negligible.

Build docs developers (and LLMs) love