nerdamer-prime
Version:
javascript light-weight symbolic math library
1,340 lines (1,228 loc) • 233 kB
TypeScript
/**
* Nerdamer-Prime TypeScript Declaration File
*
* Comprehensive typings for the entire Nerdamer mathematical library, including core functionality, algebra, calculus,
* and solver modules.
*
* @version 1.3.0
* @author Nerdamer-Prime TypeScript Definitions
* @see {@link https://github.com/together-science/nerdamer-prime} ##
*
* Quick Start Guide
*
* ```typescript
* import nerdamer from 'nerdamer-prime';
*
* // Basic expression parsing and evaluation
* const expr = nerdamer('x^2 + 2*x + 1');
* const result = expr.evaluate({x: 3}); // 16
*
* // Symbolic mathematics
* const expanded = nerdamer.expand('(x+1)^2'); // x^2 + 2*x + 1
* const factored = nerdamer.factor('x^2 + 2*x + 1'); // (x + 1)^2
* const simplified = nerdamer.simplify('2*x + 3*x'); // 5*x
*
* // Calculus operations
* const derivative = nerdamer.diff('x^3', 'x'); // 3*x^2
* const integral = nerdamer.integrate('x^2', 'x'); // x^3/3
* const definite = nerdamer.defint('x^2', 0, 1, 'x'); // 1/3
*
* // Equation solving
* const solutions = nerdamer.solve('x^2 - 4 = 0', 'x'); // [-2, 2]
*
* // Vector and matrix operations
* const vec = nerdamer.vector([1, 2, 3]);
* nerdamer.setVar('M', 'matrix([1,2],[3,4])');
* const mat = nerdamer('M');
* const det = nerdamer.determinant(mat); // -2
* ```
*
* ## API Architecture
*
* ### Expression-Centric Design
* Nerdamer uses a unified expression-based architecture:
* - **Everything is an Expression**: Numbers, variables, vectors, matrices are all `NerdamerExpression` instances
* - **Consistent API**: All objects share the same base methods (add, multiply, evaluate, etc.)
* - **Immutable Operations**: Operations return new instances, preserving the original
* - **Semantic Types**: Vectors and Matrices extend NerdamerExpression with semantic meaning
*
* ### Function Organization
* - **Static Functions**: Most mathematical operations (`nerdamer.factor`, `nerdamer.solve`, `nerdamer.diff`)
* - **Instance Methods**: Basic manipulation and evaluation (`expr.add`, `expr.evaluate`, `expr.simplify`)
* - **Chainable Operations**: Many operations can be chained together
*
* ### Type Safety
* These definitions provide full compatibility with the JavaScript runtime:
* - All declared methods exist at runtime or are properly inherited
* - Accurate representation of Nerdamer's expression-based architecture
* - Comprehensive JSDoc documentation with practical examples
* - Full support for modern TypeScript features
*
* ## Module System Support
*
* ```typescript
* // CommonJS
* const nerdamer = require('nerdamer-prime');
*
* // ES6 Modules
* import nerdamer from 'nerdamer-prime';
* import { NerdamerExpression } from 'nerdamer-prime';
*
* // Browser global
* // <script src="nerdamer-prime.js"></script>
* // window.nerdamer is available
* ```
*/
// #region Main Exports
// Import BigInteger types from big-integer library
// We need both the instance type and the static type (constructor/factory)
import type { BigInteger, BigIntegerStatic } from 'big-integer';
// Import Decimal types from decimal.js library for high-precision arithmetic
import type Decimal from 'decimal.js';
// Extend global Math interface with polyfills defined by nerdamer
declare global {
interface Math {
sech?(x: number): number;
csch?(x: number): number;
coth?(x: number): number;
}
}
// Main export for CommonJS compatibility
export = nerdamer;
// UMD global namespace declaration
export as namespace nerdamer;
// #endregion
// #region Core Type Definitions
/** A type alias for strings representing number output formats. */
type OutputType = 'decimals' | 'fractions' | 'scientific' | 'mixed' | 'recurring' | 'decimals_or_scientific' | string;
/** A type alias for common parsing and evaluation options. */
type ParseOption = 'numer' | 'expand';
/** A type alias for accessing items in the expression history. */
type ExpressionHistoryIndex = 'last' | 'first' | number;
/** Options for expand operations */
interface ExpandOptions {
/** Whether to expand the denominator */
expand_denominator?: boolean;
/** Whether to expand functions */
expand_functions?: boolean;
}
/** Union type for arithmetic operands in parser operations. These methods accept symbols, vectors, or matrices. */
type ArithmeticOperand =
| nerdamerPrime.NerdamerCore.NerdamerSymbol
| nerdamerPrime.NerdamerCore.Vector
| nerdamerPrime.NerdamerCore.Matrix;
/** Type alias for cloneable array items */
interface _Cloneable {
clone(): this;
}
/** Represents an item in a LaTeX token stream. Used during LaTeX parsing and generation. */
interface LaTeXToken {
type: string;
value: string;
left?: LaTeXToken;
right?: LaTeXToken;
}
/** Represents a filtered token or token array from LaTeX parsing. */
type FilteredLaTeXToken = LaTeXToken | FilteredLaTeXToken[];
/** Type alias for integer numbers */
type int = number;
/** Type alias for sort comparison functions */
type SortFn<T = unknown> = (a: T, b: T) => number;
// #region Discriminated Union Types for Internal Values
/**
* Base interface for all parseable mathematical objects. This provides common properties shared by NerdamerSymbol,
* Vector, and Matrix.
*/
interface _ParseableBase {
/** Multiplier coefficient */
multiplier: nerdamerPrime.NerdamerCore.Frac;
/** Clone method available on all types */
clone(): this;
/** String representation */
toString(): string;
}
/**
* Union type representing any value that can be returned by the parser. Use type guards (isSymbol, isVector, isMatrix)
* to narrow the type.
*
* @example
* ```typescript
* const result: ParseResult = parser.parse('x + 1');
* if (nerdamer.getCore().Utils.isVector(result)) {
* // result is narrowed to Vector
* console.log(result.elements.length);
* } else if (nerdamer.getCore().Utils.isMatrix(result)) {
* // result is narrowed to Matrix
* console.log(result.rows());
* } else {
* // result is narrowed to NerdamerSymbol
* console.log(result.group);
* }
* ```;
*/
type ParseResult =
| nerdamerPrime.NerdamerCore.NerdamerSymbol
| nerdamerPrime.NerdamerCore.Vector
| nerdamerPrime.NerdamerCore.Matrix;
/**
* Union type for values that can be used in mathematical operations. Includes all ParseResult types plus primitives
* that can be auto-converted.
*/
type _MathOperand = ParseResult | string | number;
// #endregion
/**
* A type alias for common expression inputs accepted throughout the Nerdamer API.
*
* @example
* ```typescript
* // All of these are valid ExpressionParam values:
* nerdamer.add('x + 1', 'y + 2') // strings
* nerdamer.add(5, 10) // numbers
* nerdamer.add(expr1, expr2) // NerdamerExpression objects
* nerdamer.add(equation, 'x') // NerdamerEquation objects
* ```;
*/
type ExpressionParam =
| string
| number
| NerdamerExpression
| NerdamerEquation
| nerdamerPrime.NerdamerCore.NerdamerSymbol
| nerdamerPrime.NerdamerCore.Vector
| nerdamerPrime.NerdamerCore.Matrix;
/**
* Represents the result of solving a system of equations.
*
* **CRITICAL BEHAVIOR NOTE**: The return format depends on the `SOLUTIONS_AS_OBJECT` setting:
*
* ```typescript
* // ✅ SOLUTIONS_AS_OBJECT = true (default):
* nerdamer.set('SOLUTIONS_AS_OBJECT', true);
* const result = nerdamer.solveEquations(['x + y - 1', '2*x - y'], ['x', 'y']);
* // Returns: { x: 0.3333333333333333, y: 0.6666666666666666 }
*
* // ✅ SOLUTIONS_AS_OBJECT = false:
* nerdamer.set('SOLUTIONS_AS_OBJECT', false);
* const result = nerdamer.solveEquations(['x + y - 1', '2*x - y'], ['x', 'y']);
* // Returns: [["x", 0.3333333333333333], ["y", 0.6666666666666666]]
*
* // ✅ SAFE ACCESS PATTERN for both formats:
* if (result && typeof result === 'object') {
* if (Array.isArray(result)) {
* // Array format: [["var", value], ...]
* const solutionMap = new Map(result);
* const xValue = solutionMap.get('x'); // number
* } else {
* // Object format: { var: value, ... }
* const solutionMap = new Map(Object.entries(result));
* const xValue = solutionMap.get('x'); // number
* }
* }
* ```
*
* **Important Notes:**
*
* - Values are always **numbers**, not NerdamerExpression objects
* - For systems with no solution: returns `null` or empty array `[]`
* - For systems with multiple solutions: behavior may vary
* - The setting `SOLUTIONS_AS_OBJECT` controls the output format
*/
type SolveResult =
| Record<string, number | NerdamerExpression | NerdamerExpression[]>
| [string, number | NerdamerExpression | NerdamerExpression[]][]
| null
| [];
// #endregion
// #region Core Expression Interfaces
/**
* The main expression object returned by nerdamer(), wrapping a symbolic NerdamerSymbol object. Provides a
* developer-friendly API for manipulating mathematical expressions.
*
* All mathematical objects in Nerdamer (including vectors and matrices) are ultimately NerdamerExpression instances,
* making the API consistent and predictable.
*
* @example
* ```typescript
* const expr = nerdamer('x^2 + 2*x + 1');
* const expanded = expr.expand(); // x^2 + 2*x + 1
* const factored = nerdamer.factor(expr); // (x + 1)^2
* const value = expr.evaluate({x: 3}); // 16
* ```;
*/
interface NerdamerExpression {
/** The underlying NerdamerSymbol object. */
symbol: nerdamerPrime.NerdamerCore.NerdamerSymbol;
// Basic output methods
toString: () => string;
/**
* Gets the string representation of the expression.
*
* **CRITICAL BEHAVIOR NOTE**: Small numbers become fractions instead of scientific notation:
*
* ```typescript
* nerdamer('1e-15').toString(); // becomes "1/999999999999999" instead of "1e-15"
* ```
*
* This breaks zero detection. Use tolerance-based comparison:
*
* ```typescript
* function isZero(expr: NerdamerExpression): boolean {
* // Method 1: String comparison (most reliable)
* if (expr.toString() === '0') return true;
*
* // Method 2: Decimal evaluation with tolerance
* try {
* const decimal = expr.text('decimals');
* const value = parseFloat(decimal);
* return Math.abs(value) < 1e-12;
* } catch {
* return false;
* }
* }
* ```
*
* @param option Pass in the string 'decimals' to always get back numbers as decimals. Pass in the string
* 'fractions' to always get back numbers as fractions. Defaults to decimals.
*/
text: (option?: OutputType) => string;
latex: (option?: OutputType) => string;
valueOf: () => number | string | Decimal;
// Basic methods
variables: () => string[];
/**
* Checks if the expression contains an integral. Added by the Calculus module - may not be available if Calculus
* module is not loaded.
*/
hasIntegral?: () => boolean;
/**
* Performs an arithmetic operation on this expression.
*
* This is an internal helper method used by add, subtract, multiply, divide, and pow.
*
* @param operationType The type of operation: 'add', 'subtract', 'multiply', 'divide', or 'pow'
* @param other The other operand
* @returns A new expression with the result of the operation
*/
operation: (
operationType: 'add' | 'subtract' | 'multiply' | 'divide' | 'pow',
other: ExpressionParam
) => NerdamerExpression;
/**
* Forces evaluation of the expression.
*
* @example
* const x = nerdamer('sin(9+5)');
* //the expression is simplified but the functions aren't called:
* x.toString(); // == sin(14)
* // force function calls with evaluate:
* x.evaluate().toString(); // == 127690464/128901187
*/
evaluate: (substitutions?: Record<string, ExpressionParam>) => NerdamerExpression;
/**
* Checks to see if the expression's value equals a number. Compares the direct value returned. The function will
* not check for all possible cases. To avoid this call evaluate.
*
* @example
* nerdamer('sqrt(5)').isNumber();
* // false
* nerdamer('sqrt(5)').evaluate().isNumber();
* // true
*/
isNumber: () => boolean;
/**
* Checks if a number evaluates to an imaginary number
*
* @example
* nerdamer('sqrt(-5)+8').isImaginary();
* // true
* nerdamer('sqrt(5)+8').isImaginary();
* // false
*/
isImaginary: () => boolean;
isInfinity: () => boolean;
isFraction: () => boolean;
isPolynomial: () => boolean;
// Expression operations
/**
* Expands a function or expression.
*
* @example
* nerdamer('x*(x+1)').expand();
* // x+x^2
* nerdamer('(x+y)*(x-5)*x').expand();
* // -5*x*y-5*x^2+x^3+x^2*y
*/
expand: () => NerdamerExpression;
/**
* Simplifies the expression. Added by the Algebra module - may not be available if Algebra module is not loaded.
*
* @throws {Error} An Error if the computation exceeds the configured TIMEOUT duration.
*/
simplify?: () => NerdamerExpression;
/**
* Sets this expression equal to another expression, creating an equation.
*
* This method is added by the Solve module - may not be available if Solve module is not loaded. Creates a
* NerdamerEquation object with this expression as the left-hand side (LHS) and the provided expression as the
* right-hand side (RHS).
*
* @example
* ```typescript
* const x = nerdamer('x^2');
* const equation = x.equals('4'); // Creates: x^2 = 4
* console.log(equation.LHS.toString()); // 'x^2'
* console.log(equation.RHS.toString()); // '4'
*
* // Can then be solved
* const solutions = equation.solveFor('x'); // [-2, 2]
* ```;
*
* @param other The expression to set equal to (becomes the RHS)
* @returns A NerdamerEquation with this expression as LHS and other as RHS
*/
equals?: (other: ExpressionParam) => NerdamerEquation;
/**
* Attempts to solve an equation. Added by the Solve module - may not be available if Solve module is not loaded.
*
* @example
* const eq = nerdamer('a*x^2+b*x-c=0');
* eq.solveFor('x'); // [(-b+sqrt(b^2+4*a*c))/(2*a), (-b-sqrt(b^2+4*a*c))/(2*a)]
*
* @param variable The variable to solve for.
* @throws {Error} An Error if the computation exceeds the configured TIMEOUT duration.
*/
solveFor?: (variable: string) => NerdamerExpression[];
/**
* Substitutes a given value for another given value
*
* @param variable The variable being substituted.
* @param value The value to substitute for.
*/
sub: (variable: string, value: ExpressionParam) => NerdamerExpression;
each: (callback: (symbol: nerdamerPrime.NerdamerCore.NerdamerSymbol, index?: number | string) => void) => void;
contains: (variable: string) => boolean;
hasFunction: (name: string) => boolean;
// Arithmetic operations
/**
* Adds a value to an expression
*
* @example
* nerdamer('x').add(3);
*/
add: (other: ExpressionParam) => NerdamerExpression;
/**
* Subtracts a value from an expression
*
* @example
* nerdamer('x').subtract(3);
*/
subtract: (other: ExpressionParam) => NerdamerExpression;
/**
* Multiplies an expression by a value
*
* @example
* nerdamer('x').multiply(3);
*/
multiply: (other: ExpressionParam) => NerdamerExpression;
/**
* Divides an expression by a value
*
* @example
* nerdamer('9*x').divide(3);
*/
divide: (other: ExpressionParam) => NerdamerExpression;
/**
* Raises an expression to a power
*
* @example
* nerdamer('x').pow(3);
*/
pow: (exponent: ExpressionParam) => NerdamerExpression;
// Comparison operations
/**
* Checks if two expressions are mathematically equal (returns boolean).
*
* **Note**: This differs from `equals()` which creates an equation. Use `eq()` for boolean comparison, `equals()`
* for creating equations.
*
* **Implementation Details**:
*
* - Internally calls `(this - other).equals(0)` on the underlying NerdamerSymbol
* - Returns `true` if expressions are mathematically equal
* - Returns `false` if expressions are not equal OR if comparison fails
* - Catches errors gracefully and returns `false` instead of throwing
*
* **Usage Examples**:
*
* ```typescript
* // Basic equality check (returns boolean)
* nerdamer('sqrt(9)').eq(3); // true
* nerdamer('x').eq('y'); // false
*
* // Zero detection (recommended approach)
* const expr = nerdamer('x - x');
* const isZero = expr.eq(nerdamer('0')); // true
*
* // Works with all expression types
* nerdamer('sqrt(7)').eq('0'); // false
* nerdamer('pi - pi').eq('0'); // true
* nerdamer('2*x').eq('2*x'); // true
*
* // Compare with equals() which creates an equation:
* nerdamer('x').equals('4'); // Creates equation: x = 4 (NerdamerEquation)
* nerdamer('x').eq('4'); // Returns false (boolean)
* ```
*
* @param other The expression to compare with
* @returns `true` if expressions are equal, `false` otherwise
*/
eq: (other: ExpressionParam) => boolean;
/**
* Checks if a value is less than another
*
* @example
* nerdamer('sqrt(9)').lt(3);
* // false
* nerdamer('8').lt(100);
* // true
*
* @param other The value being tested
*/
lt: (other: ExpressionParam) => boolean;
/**
* Checks if a value is greater than another
*
* @example
* nerdamer('sqrt(9)').gt(3);
* // false
* nerdamer('800').gt(100);
* // true
*
* @param other The value being tested
*/
gt: (other: ExpressionParam) => boolean;
/**
* Checks if a value is less than or equal to another
*
* @example
* nerdamer('sqrt(9)').lte(3);
* // true
* nerdamer('x').lte(100);
* // false
*
* @param other The value being tested
*/
lte: (other: ExpressionParam) => boolean;
/**
* Checks if a value is greater than or equal to another
*
* @example
* nerdamer('sqrt(9)').gte(3);
* // true
* nerdamer('x').gte(100);
* // false
*
* @param other The value being tested
*/
gte: (other: ExpressionParam) => boolean;
// Fraction operations
numerator: () => NerdamerExpression;
denominator: () => NerdamerExpression;
// Conversion
/** Gets expression as LaTeX */
toTeX: (format?: OutputType) => string;
/** Forces the expression to displayed with decimals */
toDecimal: (precision?: number) => string;
/**
* Generates a JavaScript function given the expression. This is perfect for plotting and filtering user input.
* Plotting for the demo is accomplished using this. The order of the parameters is in alphabetical order by default
* but an argument array can be provided with the desired order.
*
* @param variables The argument array with the order in which they are preferred.
*/
buildFunction: (variables?: string[]) => (...args: number[]) => number;
}
/**
* Represents a Nerdamer equation, with Left-Hand-Side (LHS) and Right-Hand-Side (RHS) properties. This is typically
* returned when using the '=' operator, e.g., `nerdamer('x^2=4')`.
*/
interface NerdamerEquation extends NerdamerExpression {
LHS: NerdamerExpression;
RHS: NerdamerExpression;
/** Moves the RHS to the LHS to form an expression that equals zero. */
toLHS: (expand?: boolean) => NerdamerExpression;
}
/**
* Configuration object for registering custom functions with Nerdamer.
*
* @example
* ```typescript
* // Register a simple custom function
* nerdamer.register({
* name: 'double',
* numargs: 1,
* visible: true,
* build: () => (x: number) => x * 2
* });
*
* // Use the custom function
* nerdamer('double(5)'); // 10
*
* // Register a function with variable arguments
* nerdamer.register({
* name: 'average',
* numargs: [-1], // Variable number of arguments
* build: () => (...args: number[]) => args.reduce((a, b) => a + b) / args.length
* });
* ```;
*/
interface NerdamerAddon {
/** Name of the function to register. */
name: string;
/**
* Number of function arguments:
*
* - Single number: exact number of arguments required
* - -1: variable number of arguments
* - [n]: array with single number for exact count
* - [min, max]: minimum and maximum number of arguments
*/
numargs: int | -1 | [int] | [int, int];
/** Whether this function is visible and can be called through nerdamer. Defaults to true. */
visible?: boolean;
/** Factory function that returns the actual implementation function. */
build: () => (...args: unknown[]) => unknown;
/**
* Parent module for the function. Used to register functions to specific namespaces. Examples: 'nerdamer', 'Solve',
* 'Algebra', etc.
*/
parent?: string;
}
// #endregion
// #region Main Function Interface
/**
* Defines a user function from a native JavaScript function. Allows for chaining.
*
* @example
* ```typescript
* // Register a custom function
* nerdamer(function myFunc(x, y) { return x + y; });
*
* // Use the custom function
* nerdamer('myFunc(3, 4)'); // 7
* ```;
*
* @param customJsFunction Native JavaScript function to register
* @returns The nerdamer function for chaining
*/
declare function nerdamer(customJsFunction: Function): typeof nerdamer;
/**
* Parses and evaluates mathematical expressions and equations.
*
* This is the main entry point for the Nerdamer library. It can parse mathematical expressions, equations, and perform
* symbolic computation.
*
* @example
* ```typescript
* // Basic expression parsing
* const expr = nerdamer('x^2 + 2*x + 1');
*
* // With substitutions
* const result = nerdamer('x^2 + y', {x: 3, y: 4}); // 13
*
* // With options
* const expanded = nerdamer('(x+1)^2', {}, 'expand'); // x^2 + 2*x + 1
*
* // Equations
* const equation = nerdamer('x^2 = 4');
* const solutions = equation.solveFor('x'); // [-2, 2]
*
* // Numerical evaluation
* const numerical = nerdamer('sin(pi/2)', {}, 'numer'); // 1
* ```;
*
* @param expression The mathematical expression or equation to parse
* @param substitutions Optional object containing variable substitutions
* @param options Optional parsing options ('numer' for numerical evaluation, 'expand' for expansion)
* @param index Optional index in the expression history to store the result
* @returns A NerdamerExpression for expressions, or NerdamerEquation for equations
*/
declare function nerdamer(
expression: ExpressionParam,
substitutions?: Record<string, ExpressionParam> | null,
options?: ParseOption | ParseOption[] | null,
index?: number
): NerdamerExpression | NerdamerEquation;
// Extend nerdamer function with all static methods from nerdamerPrime
declare namespace nerdamer {
// Import all types and functions from nerdamerPrime
export import version = nerdamerPrime.version;
// Core Functions
export import setConstant = nerdamerPrime.setConstant;
export import getConstant = nerdamerPrime.getConstant;
export import clearConstants = nerdamerPrime.clearConstants;
export import setFunction = nerdamerPrime.setFunction;
export import clearFunctions = nerdamerPrime.clearFunctions;
export import getCore = nerdamerPrime.getCore;
export import reserved = nerdamerPrime.reserved;
export import expressions = nerdamerPrime.expressions;
export import register = nerdamerPrime.register;
export import validVarName = nerdamerPrime.validVarName;
export import setVar = nerdamerPrime.setVar;
export import getVar = nerdamerPrime.getVar;
export import clearVars = nerdamerPrime.clearVars;
export import getVars = nerdamerPrime.getVars;
export import clear = nerdamerPrime.clear;
export import set = nerdamerPrime.set;
export import get = nerdamerPrime.get;
export import tree = nerdamerPrime.tree;
export import htmlTree = nerdamerPrime.htmlTree;
export import flush = nerdamerPrime.flush;
export import convertToLaTeX = nerdamerPrime.convertToLaTeX;
export import convertFromLaTeX = nerdamerPrime.convertFromLaTeX;
// Basic Operations
export import expand = nerdamerPrime.expand;
export import factor = nerdamerPrime.factor;
export import simplify = nerdamerPrime.simplify;
// Trigonometric Functions
export import cos = nerdamerPrime.cos;
export import sin = nerdamerPrime.sin;
export import tan = nerdamerPrime.tan;
export import sec = nerdamerPrime.sec;
export import csc = nerdamerPrime.csc;
export import cot = nerdamerPrime.cot;
export import acos = nerdamerPrime.acos;
export import asin = nerdamerPrime.asin;
export import atan = nerdamerPrime.atan;
export import atan2 = nerdamerPrime.atan2;
export import acsc = nerdamerPrime.acsc;
export import acot = nerdamerPrime.acot;
export import asec = nerdamerPrime.asec;
// Hyperbolic Functions
export import cosh = nerdamerPrime.cosh;
export import sinh = nerdamerPrime.sinh;
export import tanh = nerdamerPrime.tanh;
export import sech = nerdamerPrime.sech;
export import csch = nerdamerPrime.csch;
export import coth = nerdamerPrime.coth;
export import acosh = nerdamerPrime.acosh;
export import asinh = nerdamerPrime.asinh;
export import atanh = nerdamerPrime.atanh;
export import asech = nerdamerPrime.asech;
export import acsch = nerdamerPrime.acsch;
export import acoth = nerdamerPrime.acoth;
// Matrix and Vector Functions
export import matrix = nerdamerPrime.matrix;
export import imatrix = nerdamerPrime.imatrix;
export import determinant = nerdamerPrime.determinant;
export import matget = nerdamerPrime.matget;
export import matset = nerdamerPrime.matset;
export import invert = nerdamerPrime.invert;
export import transpose = nerdamerPrime.transpose;
export import matgetcol = nerdamerPrime.matgetcol;
export import matgetrow = nerdamerPrime.matgetrow;
export import vector = nerdamerPrime.vector;
export import vecget = nerdamerPrime.vecget;
export import vecset = nerdamerPrime.vecset;
export import cross = nerdamerPrime.cross;
export import dot = nerdamerPrime.dot;
export import matsetcol = nerdamerPrime.matsetcol;
export import matsetrow = nerdamerPrime.matsetrow;
export import size = nerdamerPrime.size;
// Complex Number Functions
export import polarform = nerdamerPrime.polarform;
export import rectform = nerdamerPrime.rectform;
export import arg = nerdamerPrime.arg;
export import imagpart = nerdamerPrime.imagpart;
export import realpart = nerdamerPrime.realpart;
// Math Functions
export import log = nerdamerPrime.log;
export import log10 = nerdamerPrime.log10;
export import log1p = nerdamerPrime.log1p;
export import log2 = nerdamerPrime.log2;
export import min = nerdamerPrime.min;
export import max = nerdamerPrime.max;
export import abs = nerdamerPrime.abs;
export import floor = nerdamerPrime.floor;
export import ceil = nerdamerPrime.ceil;
export import Si = nerdamerPrime.Si;
export import Ci = nerdamerPrime.Ci;
export import Ei = nerdamerPrime.Ei;
export import rect = nerdamerPrime.rect;
export import step = nerdamerPrime.step;
export import sinc = nerdamerPrime.sinc;
export import Shi = nerdamerPrime.Shi;
export import Chi = nerdamerPrime.Chi;
export import fact = nerdamerPrime.fact;
export import factorial = nerdamerPrime.factorial;
export import dfactorial = nerdamerPrime.dfactorial;
export import exp = nerdamerPrime.exp;
export import mod = nerdamerPrime.mod;
export import erf = nerdamerPrime.erf;
export import sign = nerdamerPrime.sign;
export import round = nerdamerPrime.round;
export import pfactor = nerdamerPrime.pfactor;
export import sqrt = nerdamerPrime.sqrt;
export import fib = nerdamerPrime.fib;
export import tri = nerdamerPrime.tri;
export import parens = nerdamerPrime.parens;
export import line = nerdamerPrime.line;
export import continuedFraction = nerdamerPrime.continuedFraction;
// Calculus Functions
export import sum = nerdamerPrime.sum;
export import product = nerdamerPrime.product;
export import diff = nerdamerPrime.diff;
export import integrate = nerdamerPrime.integrate;
export import defint = nerdamerPrime.defint;
// Algebra Functions
export import divide = nerdamerPrime.divide;
export import partfrac = nerdamerPrime.partfrac;
export import lcm = nerdamerPrime.lcm;
export import gcd = nerdamerPrime.gcd;
export import roots = nerdamerPrime.roots;
export import coeffs = nerdamerPrime.coeffs;
export import deg = nerdamerPrime.deg;
export import sqcomp = nerdamerPrime.sqcomp;
// Solve Functions
export import solve = nerdamerPrime.solve;
export import solveEquations = nerdamerPrime.solveEquations;
export import setEquation = nerdamerPrime.setEquation;
// Statistics Functions
export import mean = nerdamerPrime.mean;
export import mode = nerdamerPrime.mode;
export import median = nerdamerPrime.median;
export import zscore = nerdamerPrime.zscore;
export import limit = nerdamerPrime.limit;
export import smpvar = nerdamerPrime.smpvar;
export import variance = nerdamerPrime.variance;
export import smpstdev = nerdamerPrime.smpstdev;
export import stdev = nerdamerPrime.stdev;
// Transform Functions
export import laplace = nerdamerPrime.laplace;
export import ilt = nerdamerPrime.ilt;
// NerdamerSet Functions
export import NerdamerSet = nerdamerPrime.NerdamerSet;
export import C = nerdamerPrime.C;
export import S = nerdamerPrime.S;
export import union = nerdamerPrime.union;
export import intersection = nerdamerPrime.intersection;
export import difference = nerdamerPrime.difference;
export import isSubset = nerdamerPrime.isSubset;
export import isIn = nerdamerPrime.isIn;
export import intersects = nerdamerPrime.intersects;
export import contains = nerdamerPrime.contains;
// Additional Math Functions
export import cbrt = nerdamerPrime.cbrt;
export import nthroot = nerdamerPrime.nthroot;
export import trunc = nerdamerPrime.trunc;
export import integer_part = nerdamerPrime.integer_part;
export import conjugate = nerdamerPrime.conjugate;
export import gamma_incomplete = nerdamerPrime.gamma_incomplete;
export import radians = nerdamerPrime.radians;
export import degrees = nerdamerPrime.degrees;
export import rationalize = nerdamerPrime.rationalize;
export import Li = nerdamerPrime.Li;
// Alternative Trigonometric Names
export import arccos = nerdamerPrime.arccos;
export import arcsin = nerdamerPrime.arcsin;
export import arctan = nerdamerPrime.arctan;
// Utility Functions
export import IF = nerdamerPrime.IF;
export import supported = nerdamerPrime.supported;
export import sort = nerdamerPrime.sort;
export import print = nerdamerPrime.print;
export import scientific = nerdamerPrime.scientific;
export import primes = nerdamerPrime.primes;
export import vectrim = nerdamerPrime.vectrim;
export import updateAPI = nerdamerPrime.updateAPI;
export import validateName = nerdamerPrime.validateName;
export import load = nerdamerPrime.load;
// Parser Functions
export import parse = nerdamerPrime.parse;
export import rpn = nerdamerPrime.rpn;
export import functions = nerdamerPrime.functions;
export import addPeeker = nerdamerPrime.addPeeker;
export import removePeeker = nerdamerPrime.removePeeker;
export import aliasOperator = nerdamerPrime.aliasOperator;
export import setOperator = nerdamerPrime.setOperator;
export import getOperator = nerdamerPrime.getOperator;
export import getWarnings = nerdamerPrime.getWarnings;
export import replaceFunction = nerdamerPrime.replaceFunction;
// Expression/Equation Management
export import getExpression = nerdamerPrime.getExpression;
export import getEquation = nerdamerPrime.getEquation;
export import numExpressions = nerdamerPrime.numExpressions;
export import numEquations = nerdamerPrime.numEquations;
// Division Functions
export import div = nerdamerPrime.div;
export import useAlgebraDiv = nerdamerPrime.useAlgebraDiv;
export import useParserDiv = nerdamerPrime.useParserDiv;
// Import NerdamerCore namespace
export import NerdamerCore = nerdamerPrime.NerdamerCore;
// Type exports for modern ES module syntax (import type { X } from 'nerdamer-prime')
export type { NerdamerExpression, NerdamerEquation, SolveResult, ExpressionParam };
export type { OutputType, ParseOption, ExpandOptions, ArithmeticOperand };
export type { LaTeXToken, FilteredLaTeXToken, SortFn };
}
// #endregion
// #region Namespace for Static Methods and API
declare namespace nerdamerPrime {
/**
* Returns the version of nerdamer or a specific add-on module.
*
* @param add_on Optional module name to get the version of (e.g., 'Algebra', 'Calculus', 'Solve')
* @returns The version string, or an error message if the add_on module is not found
*/
function version(add_on?: string): string;
// #region Core Functions
/**
* Sets a constant value which nerdamer will automatically substitute when parsing expression/equation
*
* @param name The variable to be set as the constant.
* @param value The value for the expression to be set to.
*/
function setConstant(name: string, value: number | 'delete'): typeof nerdamer;
function getConstant(name: string): string;
function clearConstants(): typeof nerdamer;
/**
* Sets a function which can then be called using nerdamer.
*
* @example
* 1;
* nerdamer.setFunction('f', ['x', 'y'], 'x^2+y');
* var x = nerdamer('f(4, 7)').toString();
* console.log(x.toString());
* nerdamer.setFunction('g', ['z', 'x', 'y'], '2*x+3*y+4*z');
* x = nerdamer('g(3, 1, 2)');
* console.log(x.toString());
*
* @example
* 2;
* nerdamer.setFunction('f(x, y) = x^2+y'); //OR 'f(x, y) := x^2+y'
* var x = nerdamer('f(4, 7)').toString();
* console.log(x.toString());
* nerdamer.setFunction('g', ['z', 'x', 'y'], '2*x+3*y+4*z');
* x = nerdamer('g(3, 1, 2)');
* console.log(x.toString());
*
* @example
* 3
* function custom(x , y) {
* return x + y;
* }
* nerdamer.setFunction(custom);
* var x = nerdamer('custom(4, 7)').toString();
* console.log(x.toString())
* console.log(x.valueOf())
* OR just nerdamer.setFunction(function custom(x , y) { return x + y; });
*
* @param fnName The function name, definition string like 'f(x)=x^2', or a JavaScript function
* @param fnParams Optional array of parameter names (when fnName is a string name)
* @param fnBody Optional function body expression (when fnName is a string name)
*/
function setFunction(fnName: string | Function, fnParams?: string[], fnBody?: string): typeof nerdamer;
function clearFunctions(): typeof nerdamer;
/**
* Returns the nerdamer core object. This object contains all the core functions of nerdamer and houses the parser.
*
* @example
* Object.keys(nerdamer.getCore());
*/
function getCore(): NerdamerCore.Core;
/**
* Gets the list of reserved names. This is a list of names already in use by nerdamer excluding variable names.
* This is not a static list.
*
* @param asArray Pass in true to get the list back as an array instead of as an object.
*/
function reserved(asArray?: boolean): string | string[];
/**
* Each time an expression is parsed nerdamer stores the result. Use this method to get back stored expressions.
*
* @param asObject Pass in true to get expressions as numbered object with 1 as starting index
* @param asLaTeX Pass in the string "LaTeX" to get the expression to LaTeX, otherwise expressions come back as
* strings
*/
function expressions(
asObject?: boolean,
asLaTeX?: boolean,
options?: OutputType
): string[] | Record<number, string>;
/**
* Registers a module function with nerdamer. The object needs to contain at a minimum, a name property (text), a
* numargs property (int), this is -1 for variable arguments or an array containing the min and max arguments, the
* visible property (bool) which allows use of this function through nerdamer, defaults to true, and a build
* property containing a function which returns the function to be used. This function is also handy for creating
* aliases to functions. See below how the alias D was created for the diff function).
*
* @example
* var core = nerdamer.getCore();
* var _ = core.PARSER;
* function f(a, b) {
* //use clone for safety since a or b might be returned
* var sum = _.add(a.clone(), b.clone());
* var product = _.multiply(a.clone(), b.clone());
* return _.multiply(sum, product);
* }
* //register the function with nerdamer
* nerdamer.register({
* name: 'myFunction',
* numargs: 2,
* visible: true,
* build: function () {
* return f;
* },
* });
*
* //create an alias for the diff function
* var core = nerdamer.getCore();
* nerdamer.register({
* name: 'D',
* visible: true,
* numargs: [1, 3],
* build: function () {
* return core.Calculus.diff;
* },
* });
*
* @param addon
*/
function register(addon: NerdamerAddon | NerdamerAddon[]): void;
/**
* This method can be used to check that the variable meets variable name requirements for nerdamer. Variable names
* Must start with a letter or underscore and may contains any combination of numbers, letters, and underscores
* after that.
*
* @example
* nerdamer.validVarName('cos'); // false
* nerdamer.validVarName('chicken1'); // true
* nerdamer.validVarName('1chicken'); // false
* nerdamer.validVarName('_'); // true
*
* @param name The variable name being validated.
*/
function validVarName(name: string): boolean;
/**
* Sets a known value in nerdamer. This differs from setConstant as the value can be overridden trough the scope.
* See example.
*
* @example
* nerdamer.setVar('x', '11');
* nerdamer('x*x'); // == 121
* // nerdamer will use 13 instead of 11:
* nerdamer('x*x', { x: 13 }); // == 169
* // the value will be 121 again since the known value isn't being overridden:
* nerdamer('x*x'); // == 121
* nerdamer.setVar('x', 'delete');
* // since there no longer is a known value it will just be evaluated symbolically:
* nerdamer('x*x'); // == x^2
*
* @param name The known value to be set.
* @param value The value for the expression to be set to
*/
function setVar(name: string, value: ExpressionParam | 'delete'): typeof nerdamer;
function getVar(name: string): NerdamerCore.NerdamerSymbol | undefined;
/** Clears all previously set variables. */
function clearVars(): typeof nerdamer;
/**
* Gets all previously set variables.
*
* @param format Output format: 'text' (default), 'latex', or 'object' (returns raw expressions)
* @param option Additional formatting options passed to text() or latex() conversion
*/
function getVars(
format?: 'text' | 'latex' | 'object',
option?: OutputType
): Record<string, NerdamerExpression | string>;
/**
* Clears an item or all items from the expression history.
*
* @param item The expression to clear: 'all', 'last', 'first', or an index number
* @param keepFixed If true, replaces the expression with undefined instead of removing it (keeps EXPRESSIONS length
* fixed)
*/
function clear(item?: 'all' | 'last' | 'first' | ExpressionHistoryIndex, keepFixed?: boolean): typeof nerdamer;
/**
* Sets the value of a nerdamer setting. Currently PARSE2NUMBER and IMAGINARY. Setting PARSE2NUMBER to true will let
* nerdamer always try to return a number whenenver possible. IMAGINARY allows you to change the variable used for
* imaginary to j for instance.
*
* @example
* nerdamer.set('PARSE2NUMBER', true);
* nerdamer('cos(9)+1'); // == 14846499/167059106
* nerdamer.set('IMAGINARY', 'j');
* nerdamer('sqrt(-1)'); // == j
*
* @param option The setting to be changed
* @param value The value to set the setting to.
*/
function set(option: string, value: string | number | boolean): void;
/** Gets a nerdamer configuration option. */
function get(option: string): string | number | boolean | undefined;
/** Generates an abstract syntax tree of the expression. */
function tree(expression: ExpressionParam): unknown;
/**
* Generates an HTML representation of the expression tree.
*
* @param expression The expression to generate the tree for
* @param indent Optional indentation level for the HTML output
*/
function htmlTree(expression: ExpressionParam, indent?: number): string;
/**
* Clears all stored expressions.
*
* @example
* var x = nerdamer('x*x');
* console.log(nerdamer.expressions());
* nerdamer.flush(); //clear all expressions
* console.log(nerdamer.expressions());
*/
function flush(): typeof nerdamer;
/**
* Converts and expression to LaTeX without evaluating expression.
*
* @param expression The expression being converted.
*/
function convertToLaTeX(expression: ExpressionParam, options?: OutputType | { useGroup?: boolean }): string;
/**
* Attempts to import a LaTeX string.
*
* @param latex The expression being converted.
*/
function convertFromLaTeX(latex: string): NerdamerExpression;
// #endregion
// #region Basic Operations
/**
* Expands an algebraic expression by distributing products over sums.
*
* @example
* ```typescript
* nerdamer.expand('(x+1)*(x+2)'); // x^2 + 3*x + 2
* nerdamer.expand('(a+b)^2'); // a^2 + 2*a*b + b^2
* nerdamer.expand('x*(y+z)'); // x*y + x*z
* ```;
*
* @param expression The expression to expand
* @returns The expanded expression
*/
function expand(expression: ExpressionParam): NerdamerExpression;
/**
* Factors an algebraic expression into its constituent factors.
*
* @example
* ```typescript
* nerdamer.factor('x^2 + 3*x + 2'); // (x + 1)*(x + 2)
* nerdamer.factor('a^2 - b^2'); // (a - b)*(a + b)
* nerdamer.factor('x^3 - 8'); // (x - 2)*(x^2 + 2*x + 4)
* ```;
*
* @param expression The expression to factor
* @returns The factored expression
*/
function factor(expression: ExpressionParam): NerdamerExpression;
/**
* Simplifies an expression by combining like terms and applying algebraic rules.
*
* @example
* ```typescript
* nerdamer.simplify('2*x + 3*x'); // 5*x
* nerdamer.simplify('sin(x)^2 + cos(x)^2'); // 1
* nerdamer.simplify('(x^2 - 1)/(x - 1)'); // x + 1
* ```;
*
* @param expression The expression to simplify
* @returns The simplified expression
*/
function simplify(expression: ExpressionParam): NerdamerExpression;
// #endregion
// #region Trigonometric Functions
function cos(expression: ExpressionParam): NerdamerExpression;
function sin(expression: ExpressionParam): NerdamerExpression;
function tan(expression: ExpressionParam): NerdamerExpression;
function sec(expression: ExpressionParam): NerdamerExpression;
function csc(expression: ExpressionParam): NerdamerExpression;
function cot(expression: ExpressionParam): NerdamerExpression;
function acos(expression: ExpressionParam): NerdamerExpression;
function asin(expression: ExpressionParam): NerdamerExpression;
function atan(expression: ExpressionParam): NerdamerExpression;
function atan2(y: ExpressionParam, x: ExpressionParam): NerdamerExpression;
function acsc(expression: ExpressionParam): NerdamerExpression;
function acot(expression: ExpressionParam): NerdamerExpression;
function asec(expression: ExpressionParam): NerdamerExpression;
// #endregion
// #region Hyperbolic Functions
function cosh(expression: ExpressionParam): NerdamerExpression;
function sinh(expression: ExpressionParam): NerdamerExpression;
function tanh(expression: ExpressionParam): NerdamerExpression;
function sech(expression: ExpressionParam): NerdamerExpression;
function csch(expression: ExpressionParam): NerdamerExpression;
function coth(expression: ExpressionParam): NerdamerExpression;
function acosh(expression: ExpressionParam): NerdamerExpression;
function asinh(expression: ExpressionParam): NerdamerExpression;
function atanh(expression: ExpressionParam): NerdamerExpression;
function asech(expression: ExpressionParam): NerdamerExpression;
function acsch(expression: ExpressionParam): NerdamerExpression;
function acoth(expression: ExpressionParam): NerdamerExpression;
// #endregion
// #region Matrix and Vector Functions
/**
* Creates a matrix from 2D array data.
*
* **CRITICAL BEHAVIOR NOTE**: Different matrix creation methods produce different internal formats:
*
* ```typescript
* // Method 1: Function with 2D array - FLATTENS incorrectly for determinants:
* const m1 = nerdamer.matrix([
* [1, 2],
* [3, 4],
* ]); // → matrix([(1, 2, 3, 4)])
* nerdamer.determinant(m1); // → "" (empty, fails)
*
* // Method 2: String with double brackets - FAILS for determinants:
* const m2 = nerdamer('matrix([[1,2],[3,4]])'); // → matrix([[1,2],[3,4]])
* nerdamer.determinant(m2); // → "" (empty, fails)
*
* // Method 3: Variable-based - WORKS for determinants:
* nerdamer.setVar('M', 'matrix([1,2],[3,4])'); // → matrix([1,2],[3,4])
* const m3 = nerdamer('M');
* nerdamer.determinant(m3); // → "-2" ✅ WORKS!
* ```
*
* **For reliable determinant calculations**, use the variable-based approach:
*
* ```typescript
* function createMatrixForDeterminant(data: number[][]): NerdamerExpression {
* const flatData = data.flat().join(',');
* const rows = data.length;
* const cols = data[0]?.length || 0;
* const matrixStr = `matrix([${flatData}])`; // Single brackets format
*
* const tempVar = `temp_matrix_${Date.now()}`;
* nerdamer.setVar(tempVar, matrixStr);
* const matrix = nerdamer(tempVar);
* nerdamer.setVar(tempVar, 'delete'); // cleanup
* return matrix;
* }
* ```
*
* @param data 2D array of expressions or a single expression
* @returns Matrix object (format depends on creation method)
*/
function matrix(data: ExpressionParam[][] | ExpressionParam): NerdamerCore.Matrix;
function imatrix(size: number): NerdamerCore.Matrix;
/**
* Computes the determinant of a square matrix.
*
* **CRITICAL BEHAVIOR NOTE**: This function fails for 1x1 (single element) matrices:
*
* ```typescript
* // ❌ FAILS - Single element matrices throw error:
* nerdamer.setVar('M', 'matrix([42])');
* const matrix = nerdamer('M');
* nerdamer.determinant(matrix); // throws "Cannot read properties of undefined (reading '1')"
*
* // ✅ WORKAROUND - Extract the single element directly:
* function safeDeterminant(matrix: NerdamerExpression): NerdamerExpression {
* const size = nerdamer.size(matrix).toString();
* if (size === '[1,1]' || size === '1') {
*