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’s Solver module gives you a unified interface for finding the roots of polynomial equations — from trivial linear cases all the way to higher-degree polynomials that require numerical approximation. Equations are expressed as strings, treated as equal to zero, and dispatched to the most appropriate solving strategy based on the polynomial degree detected at runtime. The result is always a Vec<Expr>, letting you handle real and complex roots uniformly under the same return type.

MathCore::solve

pub fn solve(equation: &str, var: &str) -> Result<Vec<Expr>, MathError>
solve parses the input string into an Expr, determines the degree of the polynomial in var, and delegates to the correct solver. All equations are interpreted as being set equal to zero — pass the left-hand side only.
ParameterTypeDescription
equation&strExpression string representing the left-hand side (= 0)
var&strThe variable to solve for
Returns: Ok(Vec<Expr>) containing the roots as Expr::Number or Expr::Complex values, or a MathError if solving fails.
Passing an equation like "x^2 - 4" is equivalent to solving x² - 4 = 0. MathCore does not accept equality syntax such as "x^2 = 4" — always rearrange to bring everything to one side.

Solving strategies by degree

MathCore inspects the degree of the expression in the target variable and selects a strategy accordingly:

Degree 0 — Constant equations

If the expression contains no occurrences of the target variable, MathCore evaluates the constant. A result of zero means every value satisfies the equation (infinite solutions); any other constant means no solutions exist.
// Results in MathError::SolverError("Infinite solutions")
let result = MathCore::solve("0", "x");

// Results in Ok([]) — no solutions
let result = MathCore::solve("5", "x");

Degree 1 — Linear equations

Linear equations are solved exactly by extracting the coefficients a and b from a*x + b = 0, then computing x = -b / a.
let roots = MathCore::solve("2*x - 10", "x").unwrap();
// [5.0]

Degree 2 — Quadratic equations

Quadratic equations are solved using the quadratic formula: x = (-b ± √(b²-4ac)) / 2a. The discriminant Δ = b² - 4ac determines the nature of the roots:
  • Δ > 0 — two distinct real roots (Expr::Number)
  • Δ = 0 — one repeated real root (Expr::Number)
  • Δ < 0 — two complex conjugate roots (Expr::Complex)
// Two real roots
let roots = MathCore::solve("x^2 - 4", "x").unwrap();
// [2, -2]

// Complex roots (discriminant < 0)
let roots = MathCore::solve("x^2 + 1", "x").unwrap();
// [Complex(0+1i), Complex(0-1i)]

// General quadratic formula
let roots = MathCore::solve("x^2 + x - 6", "x").unwrap();
// [2, -3]

Higher degree — Newton-Raphson numerical solver

For polynomials of degree 3 and above, MathCore falls back to Newton-Raphson numerical root-finding. The solver searches across multiple initial points spanning [-100, 100] and automatically deduplicates roots that converge within 1e-6 of each other.
let roots = MathCore::solve("x^3 - 6*x^2 + 11*x - 6", "x").unwrap();
// Numerically approximated roots near 1, 2, 3
Newton-Raphson may not find all roots for higher-degree polynomials, especially those with roots outside the search range [-100, 100] or polynomials with closely spaced or complex roots. Check the length of the returned Vec against the expected number of roots.

Factoring polynomials with MathCore::factor

pub fn factor(expression: &str) -> Result<Expr, MathError>
factor attempts to express a polynomial as a product of its linear factors. It currently supports degree-2 polynomials with two distinct real roots. Internally it calls solve to find the roots, then constructs the factored form (x - r₁)(x - r₂).
// x^2 - 5*x + 6 → (x - 2)(x - 3)
let factored = MathCore::factor("x^2 - 5*x + 6").unwrap();
println!("{}", factored); // ((x - 2) * (x - 3))

// x^2 - 4 → (x - 2)(x - -2)
let factored = MathCore::factor("x^2 - 4").unwrap();
println!("{}", factored);
factor returns the original expression unchanged if it cannot factor it — for example, when the polynomial has complex roots, degree ≠ 2, or contains more than one variable. No error is raised in those cases.

Using Solver directly

The underlying solver::Solver struct is also part of the public API if you are working with already-parsed Expr trees rather than raw strings:
use mathcore::solver::Solver;
use mathcore::MathCore;

let expr = MathCore::parse("x^2 - 9").unwrap();
let roots = Solver::solve(&expr, "x").unwrap();
// [3.0, -3.0]
This is useful when you are chaining multiple symbolic operations and want to avoid re-parsing the expression.

Newton-Raphson internals

The numerical solver uses the derivative of the equation (computed symbolically via Calculus::differentiate) to drive each Newton-Raphson iteration:
xₙ₊₁ = xₙ - f(xₙ) / f'(xₙ)
Key parameters baked into the implementation:
SettingValue
Max iterations100
Convergence tolerance1e-10
Initial search points-100, -10, -1, 0, 1, 10, 100
Duplicate threshold1e-6
If the fixed search points all fail to converge, the solver makes up to 5 additional attempts from random starting points within [-100, 100].
For best results with high-degree polynomials, ensure the roots lie within the default search range. If you know your roots are outside [-100, 100], consider substituting a scaled variable before calling solve.

Build docs developers (and LLMs) love