functionx 2.0.3
functionx: ^2.0.3 copied to clipboard
A powerful equation parser and solver for Dart — f(x) for your code. Parse, evaluate, and solve mathematical functions with ease.
functionx #
A powerful equation parser and solver for Dart — f(x) for your code.
Features #
- 🧮 Expression Parsing - Strictly explicit parsing (e.g.
2*x,m*a) for maximum predictability - 📊 Variable Extraction - Intelligently extract variables while filtering constants
- 🔢 Expression Evaluation - Multi-mode evaluation (Real, Complex, and Mixed)
- ⚡ Equation Solving - Algebraic and numerical solvers
- 🔗 System Solver - Solve systems of non-linear equations (Real & Complex)
- 📈 Symbolic Calculus - Differentiation and integration
- 🔬 Auto-resolve Constants - Automatic identification of symbols like
SOL,PCandBC - 🇬🇷 LaTeX Support - Greek letters and subscripts, via
EquationParser
Installation #
Add to your pubspec.yaml:
dependencies:
functionx: ^2.0.3
Two API tiers #
This is the thing to understand before anything else.
| Tier | Class | Use when |
|---|---|---|
| Primary | EquationParser |
Almost always. Handles LaTeX, Greek letters and natural constants, and returns exact values where it can. |
| Core components | ExpressionParser, Evaluator, Solver, SystemSolver, Cas |
You want one specific stage on already-clean input. |
EquationParser is a façade over the core components that adds LaTeX cleaning and
constant resolution. The lower tier does not understand LaTeX:
EquationParser.extractVariables(r'\Delta E = h*\nu'); // [DeltaE, h, nu]
ExpressionParser.extractVariables(r'\Delta E = h*\nu'); // [] ← no LaTeX handling
The two also differ in precision. The core Solver falls back to numerical methods:
Solver.solve('F = m*a', {'F': 10, 'm': 2}, solveFor: 'a').value;
// 5.000000000032756 ← numerically approximated
EquationParser.solve('F = m*a', {'F': 10, 'm': 2}, solveFor: 'a').solvedValue;
// 5.0 ← exact
Quick Start #
import 'package:functionx/functionx.dart';
void main() {
// Extract variables from an equation
final vars = EquationParser.extractVariables('y = m*x + b');
print(vars); // [b, m, x, y]
// Evaluate an expression
final result = EquationParser.evaluate('x^2 + 2*x + 1', {'x': 3});
print(result); // 16.0
// Solve for an unknown
final solution = EquationParser.solve(
'F = m*a',
{'F': 10, 'm': 2},
solveFor: 'a',
);
print(solution.solvedValue); // 5.0
// Solve a system of equations
final system = SystemSolver.solve(['x^2 + y^2 = 1', 'y = x']);
print(system.values); // {x: 0.7071, y: 0.7071}
// Use physical constants
final c = EquationParser.getConstant('SOL');
print('${c?.name}: ${c?.value} ${c?.unit}'); // Speed of Light: 299792458.0 m/s
}
EquationParser #
The primary API. Every method is static.
// Variables — `excludeConstants` drops recognised constant keys
EquationParser.extractVariables('F = m*a'); // [F, a, m]
EquationParser.extractVariables('E = m*SOL^2', excludeConstants: true);
// Evaluate (supports complex results, e.g. sqrt(-1))
EquationParser.evaluate('x^2 + y', {'x': 3, 'y': 5}); // 14.0
// Solve. Give every known value; name the unknown with `solveFor`.
final r = EquationParser.solve('y = 2*x + 3', {'x': 5.0}, solveFor: 'y');
r.solvedValue; // the answer
r.allValues; // every root, when there is more than one
r.steps; // List<SolutionStep> derivation
r.error; // non-null if solving failed
// Systems — takes the equations *and* a map of already-known values
EquationParser.solveSystem(['x + y = 10', 'x - y = 2'], {}); // solvedValue: 6.0
// Constants appearing in an equation, pre-filled and ready to substitute
EquationParser.getPrefilledValues('E = m*SOL^2'); // {SOL: 299792458.0}
EquationParser.getConstant('GC'); // NaturalConstant
EquationParser.naturalConstants; // the whole map
// Strip LaTeX down to plain notation
EquationParser.cleanLatex(r'\Delta E = h*\nu');
solveForis effectively required. Without it,solvereturns a result whosesolvedValueisnulland whoseerroris alsonull— it does not infer the unknown from a missing map entry.
EquationResult #
| Field | Type | Meaning |
|---|---|---|
solvedValue |
dynamic |
The computed value (double or Complex) |
allValues |
List<dynamic>? |
All roots, where applicable |
steps |
List<SolutionStep> |
Derivation steps (type + data map) |
error |
String? |
Message if solving failed |
NaturalConstant #
Fields: value, name, unit, symbol.
EquationParser.naturalConstants carries its own set of 37 keys, which is not the
same set as the Constants class below — it additionally includes the parser tokens
PI, EN, IN and INF.
Expression Syntax #
This parser is designed to be ergonomic but strictly explicit:
| ✅ Notation | 📝 Example |
|---|---|
| Explicit | 2*x + 3*y |
| Parentheses | 3*(x+1)*(x-1) |
| Complex | (1+IN)*IN → -1 + i |
Greek (via EquationParser) |
\Delta E = h*\nu |
| Subscripts | x_1 + x_2 |
Subscripts may be words, not just digits: ATP_total = ATP_gly + ATP_etc parses fine.
Supported Operators #
| Operator | Description |
|---|---|
+ |
Addition |
- |
Subtraction |
* |
Multiplication |
/ |
Division |
^ |
Exponentiation |
Supported Functions #
All verified working: sin(x), cos(x), tan(x), asin(x), acos(x), atan(x),
sqrt(x), abs(x), log(x), ln(x), exp(x), pow(x, n).
Note that log is the natural logarithm, identical to ln — log(EN) is 1.0.
Parser Tokens #
| Token | Value |
|---|---|
PI |
3.14159... |
EN |
2.71828... |
INF |
Infinity |
IN |
i (√-1) |
Reserved Words & Aliases #
To avoid ambiguity (like c for the speed of light vs c for a variable), functionx
uses strict constant lookup. You must use the specific keys below for a symbol to
resolve to a constant; common letters like c, g and h stay plain variables.
- Functions:
sin,cos,tan,asin,acos,atan,sqrt,abs,log,ln,exp,pow - Parser tokens:
PI,EN,INF,IN - Natural constants (keys):
SOL(Speed of Light),GC(Gravitational),PC(Planck),SG(Standard Gravity),AN(Avogadro),BC(Boltzmann), and others listed below
Avogadro's key is
AN, notNA.NAis its symbol;Constants.get('NA')returnsnull.
Core Components #
Use these when you want a single stage and your input is already plain notation.
ExpressionParser #
final result = ExpressionParser.parse('y = m*x + b');
print(result.isEquation); // true
// also: result.expression, result.left, result.right
ExpressionParser.extractVariables('F = m*a'); // [F, a, m]
Evaluator #
Evaluator.evaluate('x^2 + y', {'x': 3, 'y': 5}); // 14.0 (returns double)
Evaluator.evaluateNumeric('2 + 3 * 4'); // 14.0
Evaluator.evaluateMixed('(1+IN)*IN'); // -1 + i
Evaluator.canEvaluate('x + 1', {'x': 1}); // true
Solver #
Returns a SolveResult with value, variable, steps (List<String>),
isNumeric, error and success. Results are numerically approximated — compare
with a tolerance rather than for equality.
final result = Solver.solve('2*x + 5 = 11', {'x': null});
print(result.value); // 2.9999999999752447
print(result.success); // true
SystemSolver #
Returns a SystemSolveResult with values (a Map<String, Complex>), success,
error and iterations.
final system = SystemSolver.solve(['x^2 + y^2 = 1', 'y = x']);
print(system.values); // {x: 0.7071, y: 0.7071}
Cas (Computer Algebra System) #
Symbolic differentiation and integration. Output is unsimplified, so expect mathematically correct but verbose results:
Cas.differentiate('x^2', 'x'); // ((x^2.0) * (2.0 * (1.0 / x)))
Cas.differentiate('x^3', 'x'); // ((x^3.0) * (3.0 * (1.0 / x)))
Cas.integrate('x', 'x'); // 0.5*x^2
Cas.simplify('x + x'); // (x + x) ← does not collect like terms
Cas.evaluate('2 + 3'); // (2.0 + 3.0) ← also unevaluated
Cas.simplify currently normalises structure rather than reducing an expression;
do not rely on it to collapse x + x into 2*x.
Constants #
A separate collection of physical and mathematical constants, indexed by key.
final c = Constants.speedOfLight;
print(c.value); // 299792458.0
print(c.symbol); // c
print(c.unit); // m/s
print(c.name); // Speed of Light
Constants.get('GC')?.value; // 6.6743e-11
Constants.search('mass'); // 6 matches
// byCategory returns Constant objects, not keys
Constants.byCategory('fundamental').map((c) => c.key); // (SOL, PC, HBAR, GC)
Categories #
| Category | Keys |
|---|---|
mathematical |
PI, EN, IN, PHI, SQRT2 |
fundamental |
SOL, PC, HBAR, GC |
electromagnetic |
EC, VP, VPM, CC |
atomic |
ME, MP, MN, BR, FSC, RYD, BM, NM, PEM |
thermodynamic |
BC, AN, RG, ATM, SBC, WIE, C1, C2 |
quantum |
MFQ, CQ, JC, VK |
electrochemical |
FC |
earth |
SG, EM, ER |
celestial |
SM, SR, AU, LY |
INF is a parser token only — it is not in Constants, and Constants.get('INF')
returns null.
Common Constants #
| Property | Key | Symbol | Value |
|---|---|---|---|
Constants.speedOfLight |
SOL |
c | 299792458.0 m/s |
Constants.planck |
PC |
h | 6.62607015e-34 J⋅s |
Constants.gravitationalConstant |
GC |
G | 6.6743e-11 N⋅m²/kg² |
Constants.boltzmann |
BC |
kB | 1.380649e-23 J/K |
Constants.avogadro |
AN |
NA | 6.02214076e23 1/mol |
Constants.faraday |
FC |
F | 96485.33212 C/mol |
Constants.rydberg |
RYD |
R∞ | 10973731.56816 1/m |
Constants.standardGravity |
SG |
g | 9.80665 m/s² |
Constants.elementaryCharge |
EC |
e | 1.602176634e-19 C |
Constants.coulomb |
CC |
k | 8987551792.3 N⋅m²/C² |
Constants.pi |
PI |
π | 3.141592653589793 |
Constants.e |
EN |
e | 2.718281828459045 |
Constants.imaginaryUnit |
IN |
i | √-1 (.value is NaN) |
License #
MIT License - see LICENSE for details.