nerdamer-prime
Version:
javascript light-weight symbolic math library
1,306 lines (1,199 loc) • 123 kB
TypeScript
/* eslint-disable no-unused-vars */
/**
* 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
// Main exports
export = nerdamer;
export as namespace nerdamer;
// Named exports for modern import syntax
export { NerdamerExpression, NerdamerEquation, SolveResult, ExpressionParam, OutputType, ParseOption };
// #endregion
// #region Core Type Definitions
/** A type alias for strings representing number output formats. */
type OutputType = 'decimals' | 'fractions' | 'scientific' | 'mixed' | 'recurring';
/** 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;
/** Type alias for integer numbers */
type int = number;
/**
* 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.Symbol;
/**
* 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
/**
* An internal base interface for core symbolic objects to share common methods.
*
* INCONSISTENCY NOTE: The `clone()` method was removed from this interface because it doesn't exist in the JavaScript
* runtime. While Symbol has a clone() method, Expression does not expose it, causing the Expression Method Coverage to
* be 97% instead of 100%.
*
* @internal
*/
interface CoreExpressionBase {
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;
}
/**
* The main expression object returned by nerdamer(), wrapping a symbolic Symbol 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 extends CoreExpressionBase {
/** The underlying Symbol object. */
symbol: nerdamerPrime.NerdamerCore.Symbol;
// Basic methods
variables(): string[];
/** Checks if the expression contains an integral */
hasIntegral(): boolean;
/** Gets the main operation of the expression */
operation(): string;
/**
* 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.
*
* @throws An Error if the computation exceeds the configured TIMEOUT duration.
*/
simplify(): NerdamerExpression;
/**
* Attempts to solve an equation.
*
* @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 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.Symbol, 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 equal.
*
* **IMPORTANT**: This is the ONLY public equality comparison method available on NerdamerExpression. The `equals()`
* method does NOT exist on wrapper objects - it's an internal method on Symbol objects.
*
* **Implementation Details**:
*
* - Internally calls `(this - other).equals(0)` on the underlying Symbol
* - 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
* 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
* ```
*
* @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 value 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 value 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 value 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 value The value being tested
*/
gte(other: ExpressionParam): boolean;
// Fraction operations
numerator(): NerdamerExpression;
denominator(): NerdamerExpression;
// Conversion
/** Gets expression as LaTeX */
toTeX(format?: OutputType): string;
/** Gets expression as LaTeX */
latex(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 args_array 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
* - [min, max]: minimum and maximum number of arguments
*/
numargs: int | -1 | [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: number[]) => number;
}
// #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 continued_fraction = nerdamerPrime.continued_fraction;
// 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;
// Set Functions
export import Set = nerdamerPrime.Set;
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 is_subset = nerdamerPrime.is_subset;
export import is_in = nerdamerPrime.is_in;
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;
}
// #endregion
// #region Namespace for Static Methods and API
declare namespace nerdamerPrime {
/** Returns the current version of nerdamer. */
function version(): 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
* @param fnParams The parameter array in the order in which the arguments are to be passed
* @param fnBody The body of the function
*/
function setFunction(functionDefinition: string): typeof nerdamer;
function setFunction(name: string, params: string[], body: string | NerdamerExpression): typeof nerdamer;
function setFunction(fn: Function): 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?: false): string;
function reserved(asArray: true): 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?: false, asLaTeX?: boolean, options?: any): string[];
function expressions(asObject: true, asLaTeX?: boolean, options?: any): Record<string, 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 variable_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): NerdamerExpression;
/** Clears all previously set variables. */
function clearVars(): typeof nerdamer;
/**
* Gets all previously set variables.
*
* @param format Use "LaTeX" to get as LaTeX. Defaults to text.
*/
function getVars(format?: 'text' | 'latex' | 'object'): Record<string, NerdamerExpression | string>;
/** Clears an item or all items from the expression history. */
function clear(item: 'all' | ExpressionHistoryIndex): 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 setting 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): any;
/** Generates an abstract syntax tree of the expression. */
function tree(expression: ExpressionParam): unknown;
/** Generates an HTML representation of the expression tree. */
function htmlTree(expression: ExpressionParam): 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?: any): string;
/**
* Attempts to import a LaTeX string.
*
* @param TeX 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') {
* return nerdamer.matget(matrix, 0, 0); // For 1x1, determinant = the element
* }
* return nerdamer.determinant(matrix);
* }
* ```
*
* Works correctly for 2x2, 3x3, and larger square matrices.
*
* @param matrix The square matrix to compute the determinant of
* @returns The determinant value (fails for 1x1 matrices)
* @throws Error for 1x1 matrices: "Cannot read properties of undefined (reading '1')"
*/
function determinant(matrix: ExpressionParam): NerdamerExpression;
function matget(matrix: ExpressionParam, row: number, col: number): NerdamerExpression;
function matset(matrix: ExpressionParam, row: number, col: number, value: ExpressionParam): NerdamerExpression;
function invert(matrix: ExpressionParam): NerdamerCore.Matrix;
function transpose(matrix: ExpressionParam): NerdamerCore.Matrix;
function matgetcol(matrix: ExpressionParam, col: number): NerdamerCore.Vector;
function matgetrow(matrix: ExpressionParam, row: number): NerdamerCore.Vector;
function vector(components: ExpressionParam[] | ExpressionParam): NerdamerCore.Vector;
/**
* Gets an element from a vector at the specified index.
*
* **CRITICAL BEHAVIOR NOTE**: This function returns a NerdamerExpression wrapper, but for missing/invalid indices it
* returns an object with `symbol: undefined`:
*
* ```typescript
* // For valid coefficients:
* const result = nerdamer.vecget(coeffs, 0);
* result.toString(); // "5" (valid value)
* result.symbol; // { group: 1, value: '#', ... } (valid symbol)
*
* // For invalid/missing coefficients:
* const invalid = nerdamer.vecget(coeffs, 999);
* invalid.toString(); // "" (empty string!)
* invalid.symbol; // undefined (no symbol property!)
* ```
*
* **SAFE USAGE PATTERN**: Always check if symbol is undefined before using the result:
*
* ```typescript
* function safeVecget(coeffs: any, index: number): NerdamerExpression {
* const result = nerdamer.vecget(coeffs, index);
* // Check if symbol is undefined - this indicates missing coefficient
* if (!result || result.symbol === undefined) {
* return nerdamer('0'); // Return zero for missing coefficients
* }
* return result;
* }
* ```
*
* @param vector The vector to access
* @param index The index to retrieve
* @returns NerdamerExpression for valid indices, or object with `symbol: undefined` for invalid indices
*/
function vecget(vector: ExpressionParam, index: number): NerdamerExpression;
function vecset(vector: ExpressionParam, index: number, value: ExpressionParam): NerdamerExpression;
function cross(vector1: ExpressionParam, vector2: ExpressionParam): NerdamerCore.Vector;
function dot(vector1: ExpressionParam, vector2: ExpressionParam): NerdamerExpression;
function matsetcol(matrix: ExpressionParam, col: number, vector: ExpressionParam): NerdamerCore.Matrix;
function matsetrow(matrix: ExpressionParam, row: number, vector: ExpressionParam): NerdamerCore.Matrix;
/**
* Gets the size of a matrix or vector.
*
* **CRITICAL BEHAVIOR NOTE**: This function returns dimensions in [columns, rows] order, NOT [rows, columns]:
*
* ```typescript
* // For a 2x3 matrix (2 rows, 3 columns):
* nerdamer.setVar('M', 'matrix([1,2,3],[4,5,6])');
* const matrix = nerdamer('M');
* const size = nerdamer.size(matrix);
* console.log(size.toString()); // "[3,2]" - returns [cols, rows]!
*
* // To get [rows, cols], you need to swap:
* const [cols, rows] = size
* .toString()
* .replace(/[\[\]]/g, '')
* .split(',')
* .map(Number);
* const actualSize = [rows, cols]; // [2, 3] - correct [rows, cols]
* ```
*
* This contradicts the official documentation which claims it returns [row length, column length]. Always swap the
* values when you need [rows, cols] format.
*
* @param matrix The matrix or vector to get the size of
* @returns Size expression in [columns, rows] format (contrary to documentation)
*/
function size(matrix: ExpressionParam): NerdamerExpression;
// #endregion
// #region Complex Number Functions
function polarform(expression: ExpressionParam): NerdamerExpression;
function rectform(expression: ExpressionParam): NerdamerExpression;
function arg(expression: ExpressionParam): NerdamerExpression;
function imagpart(expression: ExpressionParam): NerdamerExpression;
function realpart(expression: ExpressionParam): NerdamerExpression;
// #endregion
// #region Math Functions
function log(expression: ExpressionParam, base?: ExpressionParam): NerdamerExpression;
function log10(expression: ExpressionParam): NerdamerExpression;
function log1p(expression: ExpressionParam): NerdamerExpression;
function log2(expression: ExpressionParam): NerdamerExpression;
function min(...expressions: ExpressionParam[]): NerdamerExpression;
function max(...expressions: ExpressionParam[]): NerdamerExpression;
function abs(expression: ExpressionParam): NerdamerExpression;
function floor(expression: ExpressionParam): NerdamerExpression;
function ceil(expression: ExpressionParam): NerdamerExpression;
function Si(expression: ExpressionParam): NerdamerExpression;
function Ci(expression: ExpressionParam): NerdamerExpression;
function Ei(expression: ExpressionParam): NerdamerExpression;
function rect(expression: ExpressionParam): NerdamerExpression;
function step(expression: ExpressionParam): NerdamerExpression;
function sinc(expression: ExpressionParam): NerdamerExpression;
function Shi(expression: ExpressionParam): NerdamerExpression;
function Chi(expression: ExpressionParam): NerdamerExpression;
function fact(expression: ExpressionParam): NerdamerExpression;
function factorial(expression: ExpressionParam): NerdamerExpression;