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.

The mathcore::calculus module provides symbolic differentiation, symbolic integration, and numerical integration over arbitrary expressions. It also exposes a limits submodule for computing one-sided and two-sided limits, evaluating continuity, and applying L’Hôpital’s rule. All operations work on the Expr AST type and return Result values carrying a MathError on failure.

pub struct Calculus

A zero-sized unit struct that acts as a namespace for all calculus operations. Every method is a free associated function — no instance is required.
pub struct Calculus;

differentiate

Symbolically differentiates expr with respect to the variable named var. The result is automatically simplified with basic algebraic identities (elimination of zero/one coefficients, double-negation collapse, etc.) before being returned. Supported expression forms include constants, symbols, polynomials, quotients, the power rule (including the chain rule for composite exponents), negation, absolute value, and the standard transcendental functions sin, cos, tan, sec, ln, exp, and sqrt. Encountering an unsupported form returns Err(MathError::InvalidOperation).
pub fn differentiate(expr: &Expr, var: &str) -> Result<Expr, MathError>
expr
&Expr
required
The symbolic expression to differentiate. Must be a valid Expr node; complex sub-expressions are handled recursively.
var
&str
required
The name of the differentiation variable. Any Expr::Symbol whose string matches var is treated as the independent variable; all other symbols are treated as constants.
Returns Ok(Expr) containing the derivative, or Err(MathError) if the expression contains an unsupported operation.
use mathcore::calculus::Calculus;
use mathcore::parser::Parser;

// Differentiate x^3 + 2*x with respect to x → 3*x^2 + 2
let expr = Parser::parse("x^3 + 2*x").unwrap();
let deriv = Calculus::differentiate(&expr, "x").unwrap();
println!("{}", deriv); // 3 * x^2 + 2

// Differentiate sin(x^2) with respect to x → cos(x^2) * 2*x  (chain rule)
let expr2 = Parser::parse("sin(x^2)").unwrap();
let deriv2 = Calculus::differentiate(&expr2, "x").unwrap();
println!("{}", deriv2);

// Differentiate ln(x) → 1/x
let expr3 = Parser::parse("ln(x)").unwrap();
let deriv3 = Calculus::differentiate(&expr3, "x").unwrap();
println!("{}", deriv3);

integrate

Computes the symbolic (indefinite) integral of expr with respect to var. The following patterns are handled analytically:
Input formResult
constant nn * var
varvar^2 / 2
var^n (n ≠ −1)var^(n+1) / (n+1)
var^(−1)ln(var)
sin(var)−cos(var)
cos(var)sin(var)
exp(var)exp(var)
sum / differenceterm-by-term integration
constant × f(var)constant extracted outside
Expressions that do not match a known pattern are returned as an unevaluated Expr::Integral node so downstream code can represent the result symbolically.
pub fn integrate(expr: &Expr, var: &str) -> Result<Expr, MathError>
expr
&Expr
required
The integrand expression. Must be a valid Expr node.
var
&str
required
The integration variable name. Symbols matching this name are treated as the variable; all others are constants pulled outside the integral.
Returns Ok(Expr) with the antiderivative (no constant of integration is appended), or Err(MathError) on failure.
use mathcore::calculus::Calculus;
use mathcore::parser::Parser;

// Integrate x^2 → x^3/3
let expr = Parser::parse("x^2").unwrap();
let integral = Calculus::integrate(&expr, "x").unwrap();
println!("{}", integral);

// Integrate sin(x) → -cos(x)
let expr2 = Parser::parse("sin(x)").unwrap();
let integral2 = Calculus::integrate(&expr2, "x").unwrap();
println!("{}", integral2);

// Integrate 3*x^4 + 2*x - 7 → term-by-term
let expr3 = Parser::parse("3*x^4 + 2*x - 7").unwrap();
let integral3 = Calculus::integrate(&expr3, "x").unwrap();
println!("{}", integral3);

numerical_integrate

Approximates the definite integral of expr from lower to upper using Simpson’s 3/8 composite rule (also known as the composite Simpson rule with midpoint correction). The interval is divided into steps equal sub-intervals; each sub-interval contributes h * (y1 + 4*y_mid + y2) / 6. The expression is evaluated numerically at each grid point using the engine’s variable substitution.
pub fn numerical_integrate(
    expr: &Expr,
    var: &str,
    lower: f64,
    upper: f64,
    steps: usize,
) -> Result<f64, MathError>
expr
&Expr
required
The integrand. Must evaluate to a numeric Expr::Number at every sample point; non-numeric results produce Err(MathError::InvalidOperation).
var
&str
required
The integration variable. At each sample point the variable is bound to the current x value before the expression is evaluated.
lower
f64
required
Lower bound of integration.
upper
f64
required
Upper bound of integration.
steps
usize
required
Number of sub-intervals. Higher values increase accuracy. A value of 1000 is typically sufficient for smooth functions.
Returns Ok(f64) with the numerical approximation, or Err(MathError) if evaluation fails at any sample point.
use mathcore::calculus::Calculus;
use mathcore::parser::Parser;

// ∫₀¹ x^2 dx ≈ 0.3333...
let expr = Parser::parse("x^2").unwrap();
let result = Calculus::numerical_integrate(&expr, "x", 0.0, 1.0, 1000).unwrap();
assert!((result - 1.0 / 3.0).abs() < 1e-9);

// ∫₀^π sin(x) dx ≈ 2.0
let expr2 = Parser::parse("sin(x)").unwrap();
let pi = std::f64::consts::PI;
let result2 = Calculus::numerical_integrate(&expr2, "x", 0.0, pi, 1000).unwrap();
assert!((result2 - 2.0).abs() < 1e-6);

pub mod limits

The limits submodule exposes LimitDirection, the Limits struct, and supporting helpers for numerically evaluating limits and checking continuity. Import it as mathcore::calculus::limits.
use mathcore::calculus::limits::{LimitDirection, Limits};

pub enum LimitDirection

Specifies the approach direction when computing a limit.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum LimitDirection {
    /// Approach from values less than the target point (x → c⁻)
    Left,
    /// Approach from values greater than the target point (x → c⁺)
    Right,
    /// Verify both one-sided limits agree; return the common value or error
    Both,
}
VariantDescription
LeftUses sample points slightly below point (offset −1e-10 divided over 10 steps).
RightUses sample points slightly above point (offset +1e-10 divided over 10 steps).
BothComputes left and right limits independently; returns the value when they agree within 1e-9, or Err when they diverge.

pub struct Limits

A zero-sized unit struct namespacing all limit operations.
pub struct Limits;

Limits::limit

Numerically approximates lim_{var → point} expr from the requested direction. The implementation evaluates the expression at up to ten probe points approaching point from the given side, then returns the converged numerical value (or the appropriate infinity symbol when divergent).
pub fn limit(
    expr: &Expr,
    var: &str,
    point: f64,
    direction: LimitDirection,
) -> Result<Expr, MathError>
expr
&Expr
required
The expression whose limit is to be computed.
var
&str
required
The variable approaching point.
point
f64
required
The value that var approaches.
direction
LimitDirection
required
Whether to approach from the left, right, or verify both sides agree.
Returns Ok(Expr::Number(n)) when the limit converges, Ok(Expr::Symbol("∞")) or Ok(Expr::Symbol("-∞")) when it diverges to infinity, or Err(MathError::InvalidOperation) when the limit does not exist or cannot be computed.
use mathcore::calculus::limits::{LimitDirection, Limits};
use mathcore::parser::Parser;
use mathcore::types::Expr;

// lim_{x→2} x^2 = 4
let expr = Parser::parse("x^2").unwrap();
let lim = Limits::limit(&expr, "x", 2.0, LimitDirection::Both).unwrap();
if let Expr::Number(n) = lim {
    assert!((n - 4.0).abs() < 1e-9);
}

// lim_{x→0⁺} 1/x = ∞
let expr2 = Parser::parse("1/x").unwrap();
let lim2 = Limits::limit(&expr2, "x", 0.0, LimitDirection::Right).unwrap();
println!("{}", lim2); // "∞"

Limits::limit_at_infinity

Evaluates the limit of expr as var approaches positive or negative infinity by substituting the large proxy value 1e10 (positive) or -1e10 (negative) and calling the numerical limit engine.
pub fn limit_at_infinity(expr: &Expr, var: &str, positive: bool) -> Result<Expr, MathError>
expr
&Expr
required
The expression whose limit at infinity is to be evaluated.
var
&str
required
The variable that tends to infinity.
positive
bool
required
Pass true for var → +∞ or false for var → -∞.
Returns Ok(Expr::Number(n)) when the limit converges to a finite value, Ok(Expr::Symbol("∞")) or Ok(Expr::Symbol("-∞")) when it diverges, or Err(MathError) when the limit cannot be determined.
use mathcore::calculus::limits::Limits;
use mathcore::parser::Parser;
use mathcore::types::Expr;

// lim_{x→+∞} 1/x = 0
let expr = Parser::parse("1/x").unwrap();
let lim = Limits::limit_at_infinity(&expr, "x", true).unwrap();
if let Expr::Number(n) = lim {
    assert!(n.abs() < 1e-6);
}

// lim_{x→-∞} exp(x) ≈ 0
let expr2 = Parser::parse("exp(x)").unwrap();
let lim2 = Limits::limit_at_infinity(&expr2, "x", false).unwrap();
println!("{}", lim2);

Limits::is_continuous_at

Checks whether expr is continuous at var = point by comparing the function’s value at that point to its two-sided limit. Returns true when both exist, are finite, and agree within 1e-9.
pub fn is_continuous_at(
    expr: &Expr,
    var: &str,
    point: f64,
) -> Result<bool, MathError>
expr
&Expr
required
The expression to test for continuity.
var
&str
required
The variable name at which continuity is checked.
point
f64
required
The point at which continuity is tested.
Returns Ok(true) if the function is continuous at point, Ok(false) if it has a discontinuity or the limit does not exist, or Err(MathError) if evaluation fails.
use mathcore::calculus::limits::Limits;
use mathcore::parser::Parser;

// x^2 is continuous everywhere
let expr = Parser::parse("x^2").unwrap();
assert!(Limits::is_continuous_at(&expr, "x", 3.0).unwrap());

// 1/x has a discontinuity at 0
let expr2 = Parser::parse("1/x").unwrap();
assert!(!Limits::is_continuous_at(&expr2, "x", 0.0).unwrap());

Limits::lhopital_rule

Applies L’Hôpital’s rule to the indeterminate form numerator / denominator at the given point. The method first checks whether both the numerator and denominator evaluate to zero (within tolerance 1e-10) at point. If so, it differentiates both expressions symbolically and evaluates the limit of the ratio of their derivatives. Otherwise it evaluates the limit of the original ratio directly.
pub fn lhopital_rule(
    numerator: &Expr,
    denominator: &Expr,
    var: &str,
    point: f64,
) -> Result<Expr, MathError>
numerator
&Expr
required
The numerator expression. Symbolic differentiation is applied when a 0/0 form is detected.
denominator
&Expr
required
The denominator expression. Must not be identically zero at all points.
var
&str
required
The variable with respect to which the limit is taken and which is used for symbolic differentiation.
point
f64
required
The point at which the limit is evaluated. Both expressions are checked for a 0/0 form here.
Returns Ok(Expr) containing the limit value, or Err(MathError) if the limit cannot be computed.
use mathcore::calculus::limits::Limits;
use mathcore::parser::Parser;
use mathcore::types::Expr;

// lim_{x→0} sin(x)/x = 1  (0/0 form → L'Hôpital)
let num = Parser::parse("sin(x)").unwrap();
let den = Parser::parse("x").unwrap();
let lim = Limits::lhopital_rule(&num, &den, "x", 0.0).unwrap();
if let Expr::Number(n) = lim {
    assert!((n - 1.0).abs() < 1e-6);
}

Build docs developers (and LLMs) love