You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

@cortex-js/compute-engine

Package Overview
Dependencies
Maintainers
1
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cortex-js/compute-engine - npm Package Versions

23456

0.30.2

Diff
a
arnog
published 0.30.2 •

Changelog

Source

0.30.2 2025-07-15

Breaking Changes

  • The expr.value property reflects the value of the expression if it is a number literal or a symbol with a literal value. If you previously used the expr.value property to get the value of an expression, you should now use the expr.N().valueOf() method instead. The valueOf() method is suitable for interoperability with JavaScript, but it may result in a loss of precision for numbers with more than 15 digits.

  • BoxedExpr.sgn now returns undefined for complex numbers, or symbols with a complex-number value.

  • The ce.assign() method previously accepted ce.assign("f(x, y)", ce.parse("x+y")). This is now deprecated. Use ce.assign("f", ce.parse("(x, y) \\mapsto x+y") instead.

  • It was previously possible to invoke expr.evaluate() or expr.N() on a non-canonical expression. This will now return the expression itself.

    To evaluate a non-canonical expression, use expr.canonical.evaluate() or expr.canonical.N().

    That's also the case for the methods numeratorDenominator(), numerator(), and denominator().

    In addition, invoking the methods inv(), abs(), add(), mul(), div(), pow(), root(), ln() will throw an error if the expression is not canonical.

New Features and Improvements

  • Collections now support lazy materialization. This means that the elements of some collection are not computed until they are needed. This can significantly improve performance when working with large collections, and allow working with infinite collections. For example:

    ce.box(['Map', 'Integers', 'Square']).evaluate().print();
    // -> [0, 1, 4, 9, 16, ...]
    

    Materialization can be controlled with the materialization option of the evaluate() method. Lazy collections are materialized by default when converted to a string or LaTeX, or when assigned to a variable.

  • The bindings of symbols and function expressions is now consistently done during canonicalization.

  • It was previously not possible to change the type of an identifier from a function to a value or vice versa. This is now possible.

  • Antiderivatives are now computed symbolically:

ce.parse(`\\int_0^1 \\sin(\\pi x) dx`).evaluate().print();
// -> 2 / pi
ce.parse(`\\int \\sin(\\pi x) dx`).evaluate().print();
// -> -cos(pi * x) / pi

Requesting a numeric approximation of the integral will use a Monte Carlo method:

ce.parse(`\\int_0^1 \\sin(\\pi x) dx`).N().print();
// -> 0.6366
  • Numeric approximations of integrals is several order of magnitude faster.

  • Added Number Theory functions: Totient, Sigma0, Sigma1, SigmaMinus1, IsPerfect, Eulerian, Stirling, NPartition, IsTriangular, IsSquare, IsOctahedral, IsCenteredSquare, IsHappy, IsAbundant.

  • Added Combinatorics functions: Choose, Fibonacci, Binomial, CartesianProduct, PowerSet, Permutations, Combinations, Multinomial, Subfactorial and BellNumber.

  • The symbol type can be refined to match a specific symbol. For example symbol<True>. The type expression can be refined to match expressions with a specific operator, for example expression<Add> is a type that matches expressions with the Add operator. The numeric types can be refined with a lower and upper bound. For example integer<0..10> is a type that matches integers between 0 and 10. The type real<1..> matches real numbers greater than 1 and rational<..0> matches non-positive rational numbers.

  • Numeric types can now be constrained with a lower and upper bound. For example, real<0..10> is a type that matches real numbers between 0 and 10. The type integer<1..> matches integers greater than or equal to 1.

  • Collections that can be indexed (list, tuple) are now a subtype of indexed_collection.

  • The map type has been replaced with dictionary for collections of arbitrary key-value pairs and record for collections of structured key-value pairs.

  • Support for structural typing has been added. To define a structural type, use ce.declareType() with the alias flag, for example:

    ce.declareType(
      "point", "tuple<x: integer, y: integer>",
      { alias: true }
    );
    
  • Recursive types are now supported by using the type keyword to forward reference types. For example, to define a type for a binary tree:

    ce.declareType(
      "binary_tree",
      "tuple<value: integer, left: type binary_tree?, right: type binary_tree?>",
    );
    
  • The syntax for variadic arguments has changeed. To indicate a variadic argument, use a + or * after the type, for example:

    ce.declare('f', '(number+) -> number');
    

    Use + for a non-empty list of arguments and * for a possibly empty list.

  • Added a rule to solve the equation a^x + b = 0

  • The LaTeX parser now supports the \placeholder[]{}, \phantom{}, \hphantom{}, \vphantom{}, \mathstrut, \strut and \smash{} commands.

  • The range of recognized sign values, i.e. as returned from BoxedExpression.sgn has been simplified (e.g. '...-infinity' and 'nan' have been removed)

  • The Power canonical-form is less aggressive - only carrying-out ops. as listed in doc. - is much more careful in its consideration of operand types & values... (for example, typically, exponents are required to be numbers: e.g. x^1 will simplify, but x^y (where y===0), or x^{1+0}, will not)

Issues Resolved

  • Ensure expression LaTeX serialization is based on MathJSON generated with matching "pretty" formatting (or not), therefore resulting in LaTeX with less prettification, where prettify === false (#daef87f)

  • Symbols declare with a constant flag are now not marked as "inferred"

  • Some BoxedSymbols properties now more consistently return undefined, instead of a boolean (i.e. because the symbol is non-bound)

  • Some expr.root() computations

  • Canonical-forms

    • Fixes the Number form
    • Forms (at least, Number, Power) do not mistakenly fully canonicalize operands
    • This (partial canonicalization) now substitutes symbols (constants) with a holdUntil value of "never" during/prior-to canonicalization (i.e. just like for full canonicalization)
a
arnog
published 0.30.1 •
a
arnog
published 0.30.0 •
a
arnog
published 0.29.1 •

Changelog

Source

0.29.1 2025-03-31

  • #231 During evaluation, some numbers, for example 10e-15 were incorrectly rounded to 0.
a
arnog
published 0.29.0 •
a
arnog
published 0.28.0 •

Changelog

Source

0.28.0 2025-02-06

Issues Resolved

  • #211 More consistent canonicalization and serialization of exact numeric values of the form (a√b)/c.

  • #219 The invisibleOperator canonicalization previously also canonicalized some multiplication.

  • #218 Improved performance of parsing invisible operators, including fixing some cases where the parsing was incorrect.

  • #216 Correctly parse subscripts with a single character, for example x_1.

  • #216 Parse some non-standard integral signs, for example \int x \cdot \differentialD x (both the \cdot and the \differentialD are non-standard).

  • #210 Numeric approximation of odd nth roots of negative numbers evaluate correctly.

  • #153 Correctly parse integrals with \limits, e.g. \int\limits_0^1 x^2 \mathrm{d} x.

  • Correctly serialize to ASCIIMath Delimiter expressions.

  • When inferring the type of numeric values do not constrain them to be real. As a result:

    ce.assign('a', ce.parse('i'));
    ce.parse('a+1').evaluate().print();
    

    now returns 1 + i instead of throwing a type error.

  • Correctly parse and evaluate unary and binary \pm and \mp operators.

New Features and Improvements

  • expr.isEqual() will now return true/false if the expressions include the same unknowns and are structurally equal after expansion and simplifications. For example:

    console.info(ce.parse('(x+1)^2').isEqual(ce.parse('x^2+2x+1')));
    // -> true
    

Asynchronous Operations

Some computations can be time-consuming, for example, computing a very large factorial. To prevent the browser from freezing, the Compute Engine can now perform some operations asynchronously.

To perform an asynchronous operation, use the expr.evaluateAsync method. For example:

try {
  const fact = ce.parse('(70!)!');
  const factResult = await fact.evaluateAsync();
  factResult.print();
} catch (e) {
  console.error(e);
}

It is also possible to interrupt an operation, for example by providing a pause/cancel button that the user can press. To do so, use an AbortController object and a signal. For example:

const abort = new AbortController();
const signal = abort.signal;
setTimeout(() => abort.abort(), 500);
try {
  const fact = ce.parse('(70!)!');
  const factResult = await fact.evaluateAsync({ signal });
  factResult.print();
} catch (e) {
  console.error(e);
}

In the example above, we trigger an abort after 500ms.

It is also possible to control how long an operation can run by setting the ce.timeLimit property with a value in milliseconds. For example:

ce.timeLimit = 1000;
try {
  const fact = ce.parse('(70!)!');
  fact.evaluate().print();
} catch (e) {
  console.error(e);
}

The time limit applies to either the synchronous or asynchronous evaluation.

The default time limit is 2,000ms (2 seconds).

When an operation is canceled either because of a timeout or an abort, a CancellationError is thrown.

a
arnog
published 0.27.0 •

Changelog

Source

0.27.0 2024-12-02

  • #217 Correctly parse LaTeX expressions that include a command followed by a * such as \\pi*2.

  • #217 Correctly calculate the angle of trigonometric expressions with an expression containing a reference to Pi, for example \\sin(\\pi^2).

  • The Factorial function will now time out if the argument is too large. The timeout is signaled by throwing a CancellationError.

  • When specifying exp.toMathJSON({shorthands:[]}), i.e., not to use shorthands in the MathJSON, actually avoid using shorthands.

  • Correctly use custom multiply, plus, etc. for LaTeX serialization.

  • When comparing two numeric values, the tolerance is now used to determine if the values are equal. The tolerance can be set with the ce.tolerance property.

  • When comparing two expressions with isEqual() the values are compared structurally when necessary, or with a stochastic test when the expressions are too complex to compare structurally.

  • Correctly serialize nested superscripts, e.g. x^{y^z}.

  • The result of evaluating a Hold expression is now the expression itself.

  • To prevent evaluation of an expression temporarily, use the Unevaluated function. The result of evaluating an Unevaluated expression is its argument.

  • The type of a Hold expression was incorrectly returned as string. It now returns the type of its argument.

  • The statistics function (Mean, Median, Variance, StandardDeviation, Kurtosis, Skewness, Mode, Quartiles and InterQuartileRange) now accept as argument either a collection or a sequence of values.

    ce.parse("\\mathrm{Mean}([7, 2, 11])").evaluate().print();
    // -> 20/3
    ce.parse("\\mathrm{Mean}(7, 2, 11)").evaluate().print();
    // -> 20/3
    
  • The Variance and StandardDeviation functions now have variants for population statistics, PopulationVariance and PopulationStandardDeviation. The default is to use sample statistics.

    ce.parse("\\mathrm{PopulationVariance}([7, 2, 11])").evaluate().print();
    // -> 13.555
    ce.parse("\\mathrm{Variance}([7, 2, 11])").evaluate().print();
    // -> 20.333
    
  • The statistics function can now be compiled to JavaScript:

    const code = ce.parse("\\mathrm{Mean}(7, 2, 11)").compile();
    console.log(code());
    // -> 13.555
    
  • The statistics function calculate either using machine numbers or bignums depending on the precision. The precision can be set with the precision property of the Compute Engine.

  • The argument of compiled function is now optional.

  • Compiled expressions can now reference external JavaScript functions. For example:

    ce.defineFunction('Foo', {
      signature: 'number -> number',
      evaluate: ([x]) => ce.box(['Add', x, 1]),
    });
    
    const fn = ce.box(['Foo', 3]).compile({
      functions: { Foo: (x) => x + 1 },
    })!;
    
    console.info(fn());
    // -> 4
    
    ce.defineFunction('Foo', {
      signature: 'number -> number',
      evaluate: ([x]) => ce.box(['Add', x, 1]),
    });
    
    function foo(x) {
      return x + 1;
    }
    
    const fn = ce.box(['Foo', 3]).compile({
      functions: { Foo: foo },
    })!;
    
    console.info(fn());
    // -> 4
    

    Additionally, functions can be implicitly imported (in case they are needed by other JavaScript functions):

    ce.defineFunction('Foo', {
      signature: 'number -> number',
      evaluate: ([x]) => ce.box(['Add', x, 1]),
    });
    
    function bar(x, y) {
      return x + y;
    }
    
    function foo(x) {
      return bar(x, 1);
    }
    
    
    const fn = ce.box(['Foo', 3]).compile({
      functions: { Foo: 'foo' },
      imports: [foo, bar],
    })!;
    
    console.info(fn());
    // -> 4
    
  • Compiled expression can now include an arbitrary preamble (JavaScript source) that is executed before the compiled function is executed. This can be used to define additional functions or constants.

    ce.defineFunction('Foo', {
      signature: 'number -> number',
      evaluate: ([x]) => ce.box(['Add', x, 1]),
    });
    
    const code = ce.box(['Foo', 3]).compile({
      preamble: "function Foo(x) { return x + 1};",
    });
    
  • The hold function definition flag has been renamed to lazy

a
arnog
published 0.26.4 •

Changelog

Source

0.26.4 2024-10-17

  • #201 Identifiers of the form A_\text{1} were not parsed correctly.
  • #202 Fixed serialization of integrals and bigops.
a
arnog
published 0.26.3 •

Changelog

Source

0.26.3 2024-10-17

  • Correctly account for fractionalDigits when formatting numbers.
  • #191 Correctly handle \\lnot\\forall and \\lnot\\exists.
  • #206 The square root of 1000000 was canonicalized to 0.
  • #207 When a square root with a literal base greater than 1e6 was preceded by a non-integer literal number, the literal number was ignored during canonicalization.
  • #208 #204 Correctly evaluate numeric approximation of roots, e.g. \\sqrt[3]{125}.
  • #205 1/ln(0) was incorrectly evaluated to 1. It now returns 0.
a
arnog
published 0.26.2 •