math-expression-evaluator

repository·master·Indexed 42 days ago

https://github.com/bugwheels94/math-expression-evaluator

A high-performance JavaScript library for evaluating complex mathematical expressions. It supports trigonometry, sequence operations like Sigma (summation) and Pi (product), and custom tokens. The library provides the Mexp class for high-level evaluation via .eval(), as well as granular methods for lexing, converting to postfix notation, and stack-based evaluation.

Tokens
4.2K
Snippets
14
Records
17
Agent score
53%

What's inside math-expression-evaluator

  1. How Sigma and Pi work

    master

    The evaluator has built-in support for sequence operations.

    • Sigma (Summation): Sigma(start, end, n) calculates the sum of a sequence from start to end using n as the iterator. For example, Sigma(1,100,n) evaluates to 5050.
    • Pi (Product): Pi(start, end, n) calculates the product of a sequence from start to end using n as the iterator. For example, Pi(1,15,n) evaluates to 1307674368000 (which is 15!).
  2. Use granular evaluation methods in Mexp

    master

    For more control over the evaluation lifecycle, you can use the constituent methods of the Mexp object to manually lex, convert to postfix, and evaluate the expression. This is useful if you need to inspect tokens or the postfix notation before calculating the final result.

    // 1. Create mexp object
    const mexp = new Mexp();
    
    // 2. Parse expression into tokens
    var lexed = mexp.lex("expression");
    
    // 3. Convert tokens to postfix notation
    var postfixed = mexp.toPostfix(lexed);
    
    // 4. Evaluate the postfix expression
    var result = mexp.postfixEval(postfixed);
  3. Extend Mexp with custom tokens

    master

    You can add custom tokens to the evaluator to support new operators or functions. Tokens added via these methods are preserved for subsequent evaluations on that instance.

    const mexp = new Mexp();
    
    // Option 1: Using addToken method
    mexp.addToken([token1, token2]);
    
    // Option 2: Passing tokens directly to eval
    mexp.eval("expression", [token1, token2]);
    
    // Option 3: Passing tokens through the granular pipeline
    const answer = mexp.postfixEval(
      mexp.toPostfix(
        mexp.lex("expression", [token1, token2])
      )
    );
  4. Reference of supported mathematical symbols

    master

    The evaluator supports a wide range of operators, constants, and functions, including advanced sequence operations like Sigma (summation) and Pi (product).

    |Symbol|Explanation|Example/Note|
    |:---:|:---|---|
    |**+**|Addition Operator|2+3 results 5|
    |**-**|Subtraction Operator|2-3 results -1|
    |**/**|Division operator|3/2 results 1.5|
    |**\***|Multiplication operator|2\*3 results 6|
    |**Mod**|Modulus Operator|3 Mod 2 results 1|
    |**(**|Opening Parenthesis||
    |**)**|Closing Parenthesis||
    |**&**|Bitwise AND|3&1 results 1|
    |**Sigma**|Summation|Sigma(1,100,n) results 5050|
    |**Pi**|Product|Pi(1,10,n) results 3628800|
    |**n**|Variable for Summation or Product||
    |**pi**|Math constant pi|3.14...|
    |**e**|Math constant e|2.71...|
    |**C**|Combination operator|4C2 returns 6|
    |**P**|Permutation operator|4P2 returns 12|
    |**!**|Factorial operator|4! returns 24|
    |**log**|Logarithmic function (base 10)|log 1000 returns 3|
    |**ln**|Natural log function (base e)|ln 1000 returns .3010|
    |**pow**|Power function|pow(2,3) returns 8|
    |**^**|Power operator|2^3 returns 8|
    |**root**|Underroot function|root 4 returns 2|
    |**sin**|Sine function||
    |**cos**|Cosine function||
    |**tan**|Tangent function||
    |**asin**|Inverse Sine function||
    |**acos**|Inverse Cosine function||
    |**atan**|Inverse Tangent function||
    |**sinh**|Hyperbolic Sine function||
    |**cosh**|Hyperbolic Cosine function||
    |**tanh**|Hyperbolic Tangent function||
    |**asinh**|Inverse Hyperbolic Sine function||
    |**acosh**|Inverse Hyperbolic Cosine function||
    |**atanh**|Inverse Hyperbolic Tangent function||
  5. Extend math functions using createMathFunctions

    master

    The createMathFunctions utility allows you to define or extend the set of mathematical operations available to the Mexp evaluator. It accepts an instance of Mexp and returns an object containing mathematical functions. These functions can be used to implement custom logic or override default behaviors.

    Note that some functions (like sin, cos, tan) respect the mexp.math.isDegree setting, while others (like sigma or Pi) utilize mexp.postfixEval to evaluate sub-expressions within a range.

    import Mexp from './index';
    import { createMathFunctions } from './functions';
    
    const mexp = new Mexp();
    const customFunctions = createMathFunctions(mexp);
    
    // customFunctions now contains the standard math library including:
    // sin, cos, tan, log, fact, sigma, Pi, etc.
  6. Perform lexical analysis with lex()

    master

    The lex method performs lexical analysis on an input string, converting it into an array of ParsedToken objects. This process validates the syntax and ensures that tokens appear in a mathematically valid order (e.g., preventing two decimals in one number or invalid operator sequences).

    • Input: A string representing the mathematical expression.
    • Optional Input: An array of Token[] to be added to the evaluator's vocabulary before lexing.
    • Returns: An array of ParsedToken objects representing the structured expression.
    • Errors: Throws an error if the expression is syntactically invalid (e.g., "complete the expression", "Unexpected Space", or "is not allowed after [token]").
    // Basic usage
    const tokens = mexp.lex("sin(pi) + 2");
    
    // Usage with custom tokens
    const tokensWithCustom = mexp.lex("myFunc(5)", customTokens);
  7. Extend supported tokens with addToken()

    master

    You can extend the evaluator's vocabulary by adding custom tokens to the Mexp instance using the addToken method. This allows you to define new mathematical constants, functions, or operators that the lexer will recognize.

    When adding tokens, ensure they follow the Token interface structure. If you add a token of type FUNCTION_WITH_N_ARGS without specifying numberOfArguments, it defaults to 2.

    // Assuming 'mexp' is an instance of Mexp
    const customTokens: Token[] = [
      {
        token: 'myFunc',
        type: tokenTypes.FUNCTION_WITH_ONE_ARG,
        value: (x: number) => x * 2,
        show: 'myFunc',
        precedence: 4
      }
    ];
    
    mexp.addToken(customTokens);
  8. Evaluate postfix expressions with postfixEval()

    master

    The postfixEval function evaluates an array of tokens in postfix notation (Reverse Polish Notation). It uses a stack-based approach to process operators and operands.

    By default, the function automatically includes Math.PI and Math.E in its constant lookup. You can provide a custom Constants object to define additional named values (e.g., variables or specific mathematical constants) that the evaluator can resolve when it encounters a constant token (type 3).

    Parameters:

    • arr: An array of tokens (the return type of toPostfix).
    • Constants (optional): A Record<string, number> containing key-value pairs for constant resolution.

    Returns:

    • A number representing the evaluated result, rounded to 15 decimal places using parseFloat(value.toFixed(15)) to mitigate floating-point precision issues.
    import { postfixEval, type Constants } from './postfix_evaluator';
    
    // Example usage with custom constants
    const myConstants: Constants = { x: 10, y: 5 };
    const result = postfixEval(postfixTokens, myConstants);
    console.log(result);
  9. Use the Mexp class to evaluate math expressions

    master

    The Mexp class is the primary entrypoint for evaluating mathematical expressions. You can use the eval method to pass a string expression, which the class internally lexes, converts to postfix notation, and evaluates.

    eval(string, tokens?, Constants?) accepts:

    • string: The mathematical expression to evaluate.
    • tokens (optional): An array of pre-existing Token objects.
    • Constants (optional): A configuration object for constants used during evaluation.

    Upon instantiation, Mexp automatically initializes its math functions and tokens registry.

    import Mexp from 'math-expression-evaluator';
    
    const evaluator = new Mexp();
    const result = evaluator.eval('2 + 3 * 4');
    console.log(result); // 14
  10. Convert tokens to postfix notation with toPostfix()

    master

    The toPostfix function converts an array of tokens (typically produced by the lex function) into postfix notation (Reverse Polish Notation). This is a necessary intermediate step for evaluating mathematical expressions. The function handles operator precedence and grouping symbols to ensure the resulting array is in the correct order for stack-based evaluation.

    import { lex } from './lexer';
    import { toPostfix } from './postfix';
    
    const tokens = lex('3 + 4 * 2');
    const postfix = toPostfix(tokens);
    // postfix will contain the tokens rearranged for evaluation