or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

arithmetic.mddata-types.mdexpressions.mdindex.mdmatrices.mdprobability.mdstatistics.mdtrigonometry.mdunits.md

expressions.mddocs/

0

# Expression Parser and Evaluation

1

2

This document covers Math.js's powerful expression parser and evaluation system, including parsing mathematical expressions, compiling for performance, working with Abstract Syntax Trees (AST), symbolic operations, and advanced expression manipulation.

3

4

## Import

5

6

```typescript

7

import {

8

// Core parsing and evaluation

9

evaluate, parse, compile,

10

// Parser creation

11

parser,

12

// Symbolic operations

13

derivative, simplify, simplifyConstant, simplifyCore, rationalize,

14

resolve, leafCount,

15

// AST Node constructors

16

AccessorNode, ArrayNode, AssignmentNode, BlockNode, ConditionalNode,

17

ConstantNode, FunctionAssignmentNode, FunctionNode, IndexNode,

18

ObjectNode, OperatorNode, ParenthesisNode, RangeNode,

19

RelationalNode, SymbolNode,

20

// Utility

21

symbolicEqual

22

} from 'mathjs'

23

```

24

25

## Basic Expression Evaluation

26

27

### Direct Evaluation

28

29

```typescript

30

evaluate(expr: string | string[], scope?: object): any

31

```

32

{ .api }

33

34

```typescript

35

// Simple arithmetic

36

evaluate('2 + 3') // 5

37

evaluate('2 * 3 + 4') // 10 (follows order of operations)

38

evaluate('sqrt(16)') // 4

39

40

// Complex expressions

41

evaluate('sin(pi/2) + cos(0)') // 2

42

evaluate('2^3 * (4 + 1)') // 40

43

44

// With variables (scope)

45

evaluate('a * x + b', { a: 2, b: 3, x: 4 }) // 11

46

47

// Multiple expressions

48

evaluate(['a = 3', 'b = 4', 'a * b']) // [3, 4, 12]

49

50

// Matrix and array operations in expressions

51

evaluate('[[1,2],[3,4]] * [5,6]') // Matrix-vector multiplication

52

evaluate('sum([1,2,3,4,5])') // 15

53

```

54

55

### Expression Syntax

56

57

Math.js supports a rich expression syntax:

58

59

```typescript

60

// Arithmetic operators

61

evaluate('5 + 3') // Addition: 8

62

evaluate('5 - 3') // Subtraction: 2

63

evaluate('5 * 3') // Multiplication: 15

64

evaluate('5 / 3') // Division: 1.667...

65

evaluate('5 ^ 3') // Exponentiation: 125

66

evaluate('5 % 3') // Modulo: 2

67

68

// Comparison operators

69

evaluate('5 > 3') // true

70

evaluate('5 < 3') // false

71

evaluate('5 >= 5') // true

72

evaluate('5 == 5') // true

73

evaluate('5 != 3') // true

74

75

// Logical operators

76

evaluate('true and false') // false

77

evaluate('true or false') // true

78

evaluate('not true') // false

79

80

// Bitwise operators (with integers)

81

evaluate('5 & 3') // Bitwise AND: 1

82

evaluate('5 | 3') // Bitwise OR: 7

83

evaluate('5 xor 3') // Bitwise XOR: 6

84

evaluate('~5') // Bitwise NOT: -6

85

evaluate('5 << 2') // Left shift: 20

86

evaluate('5 >> 1') // Right shift: 2

87

```

88

89

## Parsing to AST

90

91

### Parse Function

92

93

```typescript

94

parse(expr: string, options?: ParseOptions): MathNode

95

parse(exprs: string[], options?: ParseOptions): MathNode[]

96

```

97

{ .api }

98

99

```typescript

100

interface ParseOptions {

101

nodes?: Record<string, MathNode>

102

}

103

```

104

105

```typescript

106

// Parse to Abstract Syntax Tree

107

const node = parse('2 * x + 1')

108

console.log(node.type) // 'OperatorNode'

109

console.log(node.op) // '+'

110

111

// Parse multiple expressions

112

const nodes = parse(['x = 5', 'y = x^2', 'y + 1'])

113

nodes.forEach(node => console.log(node.type))

114

115

// With custom nodes

116

const customNodes = {

117

myFunction: new FunctionNode('myCustomFunction', [])

118

}

119

const nodeWithCustom = parse('myFunction(x)', { nodes: customNodes })

120

```

121

122

### Working with AST Nodes

123

124

```typescript

125

// Navigate the AST

126

const expr = parse('a * (b + c)')

127

console.log(expr.type) // 'OperatorNode'

128

console.log(expr.fn) // 'multiply'

129

console.log(expr.args.length) // 2

130

131

// First argument is 'a'

132

console.log(expr.args[0].type) // 'SymbolNode'

133

console.log(expr.args[0].name) // 'a'

134

135

// Second argument is '(b + c)'

136

console.log(expr.args[1].type) // 'ParenthesisNode'

137

console.log(expr.args[1].content.type) // 'OperatorNode'

138

139

// Evaluate AST with scope

140

const result = expr.evaluate({ a: 2, b: 3, c: 4 }) // 14

141

```

142

143

## Compilation for Performance

144

145

### Compile Function

146

147

```typescript

148

compile(expr: string | MathNode): EvalFunction

149

```

150

{ .api }

151

152

```typescript

153

interface EvalFunction {

154

evaluate(scope?: object): any

155

}

156

```

157

158

```typescript

159

// Compile expression for repeated evaluation

160

const compiled = compile('a * x^2 + b * x + c')

161

162

// Evaluate multiple times (much faster than parsing each time)

163

const results = [

164

compiled.evaluate({ a: 1, b: 2, c: 3, x: 0 }), // 3

165

compiled.evaluate({ a: 1, b: 2, c: 3, x: 1 }), // 6

166

compiled.evaluate({ a: 1, b: 2, c: 3, x: 2 }), // 11

167

compiled.evaluate({ a: 1, b: 2, c: 3, x: 3 }) // 18

168

]

169

170

// Compile from parsed node

171

const node = parse('sin(x) + cos(y)')

172

const compiledFromNode = compile(node)

173

compiledFromNode.evaluate({ x: pi/2, y: 0 }) // 2

174

175

// Performance comparison

176

const expr = 'sqrt(x^2 + y^2)'

177

const compiled_expr = compile(expr)

178

179

// Fast: compile once, evaluate many times

180

const fastResults = points.map(({x, y}) => compiled_expr.evaluate({x, y}))

181

182

// Slow: parse and evaluate each time

183

const slowResults = points.map(({x, y}) => evaluate(expr, {x, y}))

184

```

185

186

## Parser Instance

187

188

### Creating Parser

189

190

```typescript

191

parser(): Parser

192

```

193

{ .api }

194

195

```typescript

196

interface Parser {

197

evaluate(expr: string): any

198

get(variable: string): any

199

getAll(): object

200

set(variable: string, value: any): void

201

remove(variable: string): void

202

clear(): void

203

}

204

```

205

206

```typescript

207

// Create parser instance with persistent scope

208

const mathParser = parser()

209

210

// Set variables

211

mathParser.set('a', 3)

212

mathParser.set('b', 4)

213

214

// Evaluate with persistent scope

215

mathParser.evaluate('c = a^2 + b^2') // 25

216

mathParser.evaluate('sqrt(c)') // 5

217

218

// Get variables

219

mathParser.get('c') // 25

220

mathParser.getAll() // { a: 3, b: 4, c: 25 }

221

222

// Remove and clear

223

mathParser.remove('c')

224

mathParser.clear() // Remove all variables

225

226

// Multi-line expressions

227

mathParser.evaluate(`

228

x = 5

229

y = x^2

230

z = sqrt(y)

231

`) // 5 (returns last expression result)

232

```

233

234

## AST Node Types and Construction

235

236

### Symbol and Constant Nodes

237

238

```typescript

239

SymbolNode(name: string): SymbolNode

240

ConstantNode(value: any): ConstantNode

241

```

242

{ .api }

243

244

```typescript

245

// Create symbol (variable reference)

246

const xSymbol = new SymbolNode('x')

247

xSymbol.evaluate({ x: 5 }) // 5

248

249

// Create constant

250

const constPi = new ConstantNode(pi)

251

constPi.evaluate() // π

252

253

// Create complex constants

254

const constComplex = new ConstantNode(complex(2, 3))

255

const constMatrix = new ConstantNode(matrix([[1, 2], [3, 4]]))

256

```

257

258

### Operator Nodes

259

260

```typescript

261

OperatorNode(op: string, fn: string, args: MathNode[], implicit?: boolean): OperatorNode

262

```

263

{ .api }

264

265

```typescript

266

// Create binary operation: x + y

267

const addNode = new OperatorNode('+', 'add', [

268

new SymbolNode('x'),

269

new SymbolNode('y')

270

])

271

addNode.evaluate({ x: 3, y: 4 }) // 7

272

273

// Create unary operation: -x

274

const negNode = new OperatorNode('-', 'unaryMinus', [

275

new SymbolNode('x')

276

], false)

277

negNode.evaluate({ x: 5 }) // -5

278

279

// Implicit multiplication: 2x

280

const implicitMult = new OperatorNode('*', 'multiply', [

281

new ConstantNode(2),

282

new SymbolNode('x')

283

], true) // implicit = true

284

```

285

286

### Function Nodes

287

288

```typescript

289

FunctionNode(fn: string | MathNode, args: MathNode[]): FunctionNode

290

```

291

{ .api }

292

293

```typescript

294

// Create function call: sin(x)

295

const sinNode = new FunctionNode('sin', [

296

new SymbolNode('x')

297

])

298

sinNode.evaluate({ x: pi/2 }) // 1

299

300

// Function with multiple arguments: pow(x, y)

301

const powNode = new FunctionNode('pow', [

302

new SymbolNode('x'),

303

new ConstantNode(2)

304

])

305

powNode.evaluate({ x: 3 }) // 9

306

307

// Custom function reference

308

const customFn = new SymbolNode('myFunction')

309

const customCall = new FunctionNode(customFn, [new SymbolNode('x')])

310

```

311

312

### Assignment Nodes

313

314

```typescript

315

AssignmentNode(object: MathNode, index?: IndexNode, value: MathNode): AssignmentNode

316

```

317

{ .api }

318

319

```typescript

320

// Simple assignment: x = 5

321

const assign = new AssignmentNode(

322

new SymbolNode('x'),

323

undefined,

324

new ConstantNode(5)

325

)

326

const scope = {}

327

assign.evaluate(scope) // 5, and scope.x = 5

328

329

// Array element assignment: arr[2] = 10

330

const arrAssign = new AssignmentNode(

331

new SymbolNode('arr'),

332

new IndexNode([new ConstantNode(2)]),

333

new ConstantNode(10)

334

)

335

arrAssign.evaluate({ arr: [1, 2, 3, 4] }) // Sets arr[2] = 10

336

```

337

338

### Array and Object Nodes

339

340

```typescript

341

ArrayNode(items: MathNode[]): ArrayNode

342

ObjectNode(properties: Record<string, MathNode>): ObjectNode

343

```

344

{ .api }

345

346

```typescript

347

// Create array: [1, 2, x]

348

const arrayNode = new ArrayNode([

349

new ConstantNode(1),

350

new ConstantNode(2),

351

new SymbolNode('x')

352

])

353

arrayNode.evaluate({ x: 3 }) // [1, 2, 3]

354

355

// Create object: {a: 1, b: x+1}

356

const objectNode = new ObjectNode({

357

a: new ConstantNode(1),

358

b: new OperatorNode('+', 'add', [

359

new SymbolNode('x'),

360

new ConstantNode(1)

361

])

362

})

363

objectNode.evaluate({ x: 2 }) // {a: 1, b: 3}

364

```

365

366

### Conditional Nodes

367

368

```typescript

369

ConditionalNode(condition: MathNode, trueExpr: MathNode, falseExpr: MathNode): ConditionalNode

370

```

371

{ .api }

372

373

```typescript

374

// Create ternary: x > 0 ? x : -x (absolute value)

375

const absNode = new ConditionalNode(

376

new OperatorNode('>', 'larger', [

377

new SymbolNode('x'),

378

new ConstantNode(0)

379

]),

380

new SymbolNode('x'),

381

new OperatorNode('-', 'unaryMinus', [new SymbolNode('x')])

382

)

383

384

absNode.evaluate({ x: 5 }) // 5

385

absNode.evaluate({ x: -3 }) // 3

386

```

387

388

### Range Nodes

389

390

```typescript

391

RangeNode(start: MathNode, end: MathNode, step?: MathNode): RangeNode

392

```

393

{ .api }

394

395

```typescript

396

// Create range: 1:5

397

const rangeNode = new RangeNode(

398

new ConstantNode(1),

399

new ConstantNode(5)

400

)

401

rangeNode.evaluate() // [1, 2, 3, 4, 5]

402

403

// Range with step: 0:2:10

404

const stepRange = new RangeNode(

405

new ConstantNode(0),

406

new ConstantNode(10),

407

new ConstantNode(2)

408

)

409

stepRange.evaluate() // [0, 2, 4, 6, 8, 10]

410

```

411

412

## Symbolic Operations

413

414

### Symbolic Differentiation

415

416

```typescript

417

derivative(expr: MathNode | string, variable: MathNode | string, options?: DerivativeOptions): MathNode

418

```

419

{ .api }

420

421

```typescript

422

interface DerivativeOptions {

423

simplify?: boolean

424

}

425

```

426

427

```typescript

428

// Basic differentiation

429

derivative('x^2', 'x') // Returns AST for '2*x'

430

derivative('sin(x)', 'x') // Returns AST for 'cos(x)'

431

derivative('a*x + b', 'x') // Returns AST for 'a'

432

433

// Multi-variable expressions

434

derivative('x^2 + y^2', 'x') // Returns AST for '2*x'

435

derivative('x*y + y^2', 'y') // Returns AST for 'x + 2*y'

436

437

// Complex expressions

438

const expr = 'sin(x^2) * cos(y)'

439

const dfdx = derivative(expr, 'x') // 2*x*cos(x^2)*cos(y)

440

const dfdy = derivative(expr, 'y') // -sin(x^2)*sin(y)

441

442

// Chain rule example

443

derivative('sin(cos(x))', 'x') // -cos(cos(x))*sin(x)

444

445

// Product rule example

446

derivative('x^2 * sin(x)', 'x') // 2*x*sin(x) + x^2*cos(x)

447

448

// Evaluate derivative at point

449

const f_prime = derivative('x^3 - 2*x', 'x')

450

f_prime.evaluate({ x: 2 }) // 3*4 - 2 = 10

451

```

452

453

### Expression Simplification

454

455

```typescript

456

simplify(expr: MathNode | string, rules?: MathNode[] | string[], scope?: object, options?: SimplifyOptions): MathNode

457

```

458

{ .api }

459

460

```typescript

461

// Basic simplification

462

simplify('2 + 3') // ConstantNode(5)

463

simplify('x + x') // OperatorNode for '2*x'

464

simplify('x * 1') // SymbolNode('x')

465

simplify('0 + x') // SymbolNode('x')

466

467

// Algebraic simplification

468

simplify('(x + 1)^2') // x^2 + 2*x + 1

469

simplify('x^2 - 1') // (x-1)*(x+1) (if factorization rules applied)

470

471

// Trigonometric simplification

472

simplify('sin(x)^2 + cos(x)^2') // 1

473

simplify('2*sin(x)*cos(x)') // sin(2*x)

474

475

// Custom rules

476

const rules = ['n1*n2 -> n1*n2', 'x + x -> 2*x']

477

simplify('a + a + b + b', rules) // 2*a + 2*b

478

479

// With scope (substitute known values)

480

simplify('a*x + b*x', {}, { a: 2, b: 3 }) // 5*x

481

```

482

483

### Specific Simplification Functions

484

485

```typescript

486

simplifyConstant(expr: MathNode | string, options?: SimplifyOptions): MathNode

487

simplifyCore(expr: MathNode | string, options?: SimplifyOptions): MathNode

488

```

489

{ .api }

490

491

```typescript

492

// Simplify only constant expressions

493

simplifyConstant('2 + 3 * x') // 5 + 3*x (only 2+3 simplified)

494

simplifyConstant('sin(0) + cos(pi)') // 0 + (-1) = -1

495

496

// Core simplification (basic algebraic rules)

497

simplifyCore('x + 0') // x

498

simplifyCore('x * 1') // x

499

simplifyCore('x * 0') // 0

500

simplifyCore('x + x') // 2*x

501

```

502

503

### Rationalization

504

505

```typescript

506

rationalize(expr: MathNode | string, optional?: object, detailed?: boolean): MathNode

507

```

508

{ .api }

509

510

```typescript

511

// Convert to rational form

512

rationalize('0.125') // 1/8

513

rationalize('0.333333') // 1/3 (approximately)

514

rationalize('sqrt(2)/2') // More rational form

515

516

// Rationalize denominators

517

rationalize('1/sqrt(2)') // sqrt(2)/2

518

rationalize('1/(1+sqrt(2))') // -1 + sqrt(2)

519

```

520

521

## Advanced Expression Manipulation

522

523

### Expression Resolution

524

525

```typescript

526

resolve(node: MathNode, scope?: object): MathNode

527

```

528

{ .api }

529

530

```typescript

531

// Resolve variables in expression

532

const expr = parse('a * x + b')

533

const resolved = resolve(expr, { a: 2, b: 3 })

534

// Returns AST equivalent to '2 * x + 3'

535

536

resolved.evaluate({ x: 4 }) // 11

537

```

538

539

### Leaf Count

540

541

```typescript

542

leafCount(expr: MathNode | string): number

543

```

544

{ .api }

545

546

```typescript

547

// Count leaf nodes (complexity measure)

548

leafCount('x') // 1

549

leafCount('x + y') // 2

550

leafCount('x^2 + 2*x + 1') // 5 (x, 2, x, 2, 1)

551

552

// Useful for measuring expression complexity

553

const expr1 = 'x + 1'

554

const expr2 = '(x + 1)^2'

555

leafCount(expr1) // 2

556

leafCount(expr2) // 4 (after expansion)

557

```

558

559

### Symbolic Equality

560

561

```typescript

562

symbolicEqual(expr1: MathNode | string, expr2: MathNode | string, options?: SymbolicEqualOptions): boolean

563

```

564

{ .api }

565

566

```typescript

567

// Test if expressions are symbolically equivalent

568

symbolicEqual('x + 1', '1 + x') // true (commutative)

569

symbolicEqual('2*x', 'x + x') // true

570

symbolicEqual('(x+1)^2', 'x^2 + 2*x + 1') // true

571

symbolicEqual('sin(x)^2 + cos(x)^2', '1') // true

572

573

// Different but not simplified

574

symbolicEqual('x + 0', 'x') // true

575

symbolicEqual('x * 1', 'x') // true

576

```

577

578

## Working with Units in Expressions

579

580

```typescript

581

// Units are first-class citizens in expressions

582

evaluate('5 meter + 3 meter') // 8 meter

583

evaluate('10 km/h * 2 hours') // 20 km

584

evaluate('5 kg * 9.8 m/s^2') // 49 N (automatically converts)

585

586

// Unit conversions in expressions

587

evaluate('5 km to mile') // ~3.1 mile

588

evaluate('to(100 fahrenheit, celsius)') // ~37.8 celsius

589

590

// Complex unit calculations

591

evaluate('(60 mile/hour) * (2 hour) to km') // ~193 km

592

evaluate('force = 10 newton; area = 2 cm^2; force/area to bar') // Pressure calculation

593

```

594

595

## Matrix and Array Expressions

596

597

```typescript

598

// Matrix operations in expressions

599

evaluate('[[1,2],[3,4]] * [[5,6],[7,8]]') // Matrix multiplication

600

evaluate('inv([[1,2],[3,4]])') // Matrix inverse

601

evaluate('det([[1,2],[3,4]])') // Determinant: -2

602

603

// Element access and modification

604

evaluate('A = [[1,2,3],[4,5,6]]; A[1,2]') // 5 (0-indexed)

605

evaluate('A[0,:] = [10,20,30]; A') // Modify first row

606

607

// Array operations

608

evaluate('sum([1,2,3,4,5])') // 15

609

evaluate('mean([1,2,3,4,5])') // 3

610

evaluate('std([1,2,3,4,5])') // ~1.58

611

```

612

613

## Function Definition in Expressions

614

615

```typescript

616

// Define functions within expressions

617

const parser_instance = parser()

618

619

// Simple function

620

parser_instance.evaluate('f(x) = x^2 + 1')

621

parser_instance.evaluate('f(3)') // 10

622

623

// Multi-parameter functions

624

parser_instance.evaluate('g(x,y) = sqrt(x^2 + y^2)')

625

parser_instance.evaluate('g(3,4)') // 5

626

627

// Recursive functions (be careful with stack overflow)

628

parser_instance.evaluate('factorial(n) = n <= 1 ? 1 : n * factorial(n-1)')

629

parser_instance.evaluate('factorial(5)') // 120

630

631

// Functions with conditionals

632

parser_instance.evaluate('abs(x) = x >= 0 ? x : -x')

633

parser_instance.evaluate('abs(-5)') // 5

634

```

635

636

## Error Handling in Expressions

637

638

```typescript

639

import { ArgumentsError, SyntaxError } from 'mathjs'

640

641

try {

642

evaluate('1 / 0') // May return Infinity or throw

643

} catch (error) {

644

console.log('Division by zero')

645

}

646

647

try {

648

evaluate('unknown_function(5)')

649

} catch (error) {

650

if (error instanceof Error) {

651

console.log('Undefined function:', error.message)

652

}

653

}

654

655

try {

656

parse('1 + + 2') // Syntax error

657

} catch (error) {

658

console.log('Parse error:', error.message)

659

}

660

661

// Validate expressions before evaluation

662

function safeEvaluate(expr, scope = {}) {

663

try {

664

const node = parse(expr)

665

return node.evaluate(scope)

666

} catch (error) {

667

return { error: error.message }

668

}

669

}

670

```

671

672

## Performance Optimization

673

674

### Expression Compilation Strategies

675

676

```typescript

677

// Pre-compile frequently used expressions

678

const expressions = {

679

quadratic: compile('a*x^2 + b*x + c'),

680

distance: compile('sqrt((x2-x1)^2 + (y2-y1)^2)'),

681

interest: compile('P * (1 + r/n)^(n*t)')

682

}

683

684

// Batch evaluation

685

function evaluateQuadratic(coefficients, xValues) {

686

return xValues.map(x =>

687

expressions.quadratic.evaluate({ ...coefficients, x })

688

)

689

}

690

691

// Memoization for expensive symbolic operations

692

const memoizedSimplify = (() => {

693

const cache = new Map()

694

return (expr) => {

695

const key = typeof expr === 'string' ? expr : expr.toString()

696

if (!cache.has(key)) {

697

cache.set(key, simplify(expr))

698

}

699

return cache.get(key)

700

}

701

})()

702

```

703

704

### Tree Transformation and Optimization

705

706

```typescript

707

// Custom AST transformations

708

function optimizeExpression(node) {

709

// Traverse and transform AST

710

if (node.type === 'OperatorNode') {

711

if (node.op === '*' && node.args.some(arg =>

712

arg.type === 'ConstantNode' && arg.value === 0

713

)) {

714

return new ConstantNode(0) // x * 0 = 0

715

}

716

717

if (node.op === '+' && node.args.some(arg =>

718

arg.type === 'ConstantNode' && arg.value === 0

719

)) {

720

// Remove zero terms

721

return node.args.find(arg => !(arg.type === 'ConstantNode' && arg.value === 0))

722

}

723

}

724

725

// Recursively optimize children

726

if (node.args) {

727

node.args = node.args.map(optimizeExpression)

728

}

729

730

return node

731

}

732

```

733

734

## Integration with Math.js Ecosystem

735

736

### Chain Interface with Expressions

737

738

```typescript

739

// Use expressions in chain operations

740

const result = chain('x^2 + 2*x + 1')

741

.parse()

742

.simplify()

743

.evaluate({ x: 3 })

744

.done() // 16

745

746

// Complex chain with symbolic operations

747

const derivative_result = chain('sin(x^2)')

748

.parse()

749

.derivative('x')

750

.simplify()

751

.evaluate({ x: pi/2 })

752

.done()

753

```

754

755

### Custom Function Registration

756

757

```typescript

758

// Register custom functions for use in expressions

759

const math = create(all)

760

761

math.import({

762

myCustomFunction: (x) => x^2 + 1,

763

factorial: factorial // Re-export built-in

764

})

765

766

evaluate('myCustomFunction(5)', {}, { math }) // 26

767

```

768

769

## Common Expression Patterns

770

771

### Mathematical Modeling

772

773

```typescript

774

// Population growth model

775

const exponentialGrowth = compile('P0 * e^(r * t)')

776

const logisticGrowth = compile('K / (1 + ((K - P0) / P0) * e^(-r * t))')

777

778

// Physical equations

779

const kineticEnergy = compile('0.5 * m * v^2')

780

const gravitationalForce = compile('G * m1 * m2 / r^2')

781

782

// Economic calculations

783

const compoundInterest = compile('P * (1 + r/n)^(n*t)')

784

const presentValue = compile('FV / (1 + r)^t')

785

```

786

787

### Numerical Methods Integration

788

789

```typescript

790

// Newton's method for root finding

791

function newtonMethod(expr, guess, tolerance = 1e-10) {

792

const f = compile(expr)

793

const f_prime = compile(derivative(expr, 'x'))

794

795

let x = guess

796

let iterations = 0

797

798

while (iterations < 100) {

799

const fx = f.evaluate({ x })

800

const fpx = f_prime.evaluate({ x })

801

802

if (Math.abs(fx) < tolerance) break

803

804

x = x - fx / fpx

805

iterations++

806

}

807

808

return x

809

}

810

811

// Find root of x^2 - 2 = 0 (sqrt(2))

812

const root = newtonMethod('x^2 - 2', 1) // ≈ 1.414

813

```

814

815

### Expression Analysis

816

817

```typescript

818

// Extract variables from expression

819

function extractVariables(expr) {

820

const node = parse(expr)

821

const variables = new Set()

822

823

node.traverse((node, path, parent) => {

824

if (node.type === 'SymbolNode' && !isFunction(node.name)) {

825

variables.add(node.name)

826

}

827

})

828

829

return Array.from(variables)

830

}

831

832

// Analyze expression complexity

833

function analyzeExpression(expr) {

834

const node = parse(expr)

835

836

return {

837

leafCount: leafCount(node),

838

variables: extractVariables(expr),

839

hasConstants: node.toString().match(/\d+/) !== null,

840

hasFunctions: node.toString().match(/\w+\(/) !== null,

841

complexity: leafCount(node) + extractVariables(expr).length

842

}

843

}

844

```