UNPKG

nerdamer-prime

Version:
1,306 lines (1,199 loc) 123 kB
/* 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;