UNPKG

nerdamer-prime

Version:
1,340 lines (1,228 loc) 233 kB
/** * 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') { *