Compute Engine API Reference
Modules
Common
Type
PrimitiveType
type PrimitiveType =
| NumericType
| "collection"
| "list"
| "set"
| "map"
| "tuple"
| "value"
| "scalar"
| "function"
| "symbol"
| "boolean"
| "string"
| "expression"
| "unknown"
| "error"
| "nothing"
| "never"
| "any";
A primitive type is a simple type that represents a concrete value.
-
any
: the top typeexpression
error
: an invalid value, such as["Error", "missing"]
nothing
: the type of theNothing
symbol, the unit typenever
: the bottom typeunknown
: a value whose type is not known
-
expression
:- a symbolic expression, such as
["Add", "x", 1]
<value>
symbol
: a symbol, such asx
.function
: a function expression such as["Function", ["Add", "x", 1], "x"]
.
- a symbolic expression, such as
-
value
scalar
<number>
boolean
: a boolean value:True
orFalse
.string
: a string of characters.
collection
list
: a collection of expressions, possibly recursive, with optional dimensions, e.g.[number]
,[boolean^32]
,[number^(2x3)]
. Used to represent a vector, a matrix or a tensor when the type of its elements is a numberset
: a collection of unique expressions, e.g.set<string>
.tuple
: a fixed-size collection of named or unnamed elements, e.g.tuple<number, boolean>
,tuple<x: number, y: boolean>
.map
: a set key-value pairs, e.g.map<x: number, y: boolean>
.
NumericType
type NumericType =
| "number"
| "finite_number"
| "complex"
| "finite_complex"
| "imaginary"
| "real"
| "finite_real"
| "rational"
| "finite_rational"
| "integer"
| "finite_integer"
| "non_finite_number";
number
: any numeric value =complex
+real
plusNaN
complex
: a number with non-zero real and imaginary parts =finite_complex
plusComplexInfinity
finite_complex
: a finite complex number =imaginary
+finite_real
imaginary
: a complex number with a real part of 0 (pure imaginary)finite_number
: a finite numeric value =finite_complex
finite_real
: a finite real number =finite_rational
+finite_integer
finite_rational
: a pure rational numberfinite_integer
: a whole numberreal
: a complex number with an imaginary part of 0 =finite_real
+non_finite_number
non_finite_number
:PositiveInfinity
,NegativeInfinity
integer
: a whole number =finite_integer
+non_finite_number
rational
: a pure rational number (not an integer) =finite_rational
+non_finite_number
NamedElement
type NamedElement = object;
Type declaration
name?
NamedElement.name?
optional name: string;
type
NamedElement.type
type: Type;
FunctionSignature
type FunctionSignature = object;
Type declaration
kind
FunctionSignature.kind
kind: "signature";
args?
FunctionSignature.args?
optional args: NamedElement[];
optArgs?
FunctionSignature.optArgs?
optional optArgs: NamedElement[];
restArg?
FunctionSignature.restArg?
optional restArg: NamedElement;
result
FunctionSignature.result
result: Type;
AlgebraicType
type AlgebraicType = object;
Type declaration
kind
AlgebraicType.kind
kind: "union" | "intersection";
types
AlgebraicType.types
types: Type[];
NegationType
type NegationType = object;
Type declaration
kind
NegationType.kind
kind: "negation";
type
NegationType.type
type: Type;
ValueType
type ValueType = object;
Type declaration
kind
ValueType.kind
kind: "value";
value
ValueType.value
value: any;
MapType
type MapType = object;
Map is a non-indexable collection of key/value pairs.
An element of a map whose type is a subtype of nothing
is optional.
For example, in {x: number, y: boolean | nothing}
the element y
is optional.
Type declaration
kind
MapType.kind
kind: "map";
elements
MapType.elements
elements: Record<string, Type>;
CollectionType
type CollectionType = object;
Collection, List, Set, Tuple and Map are collections.
CollectionType
is a generic collection of elements of a certain type.
Type declaration
kind
CollectionType.kind
kind: "collection";
elements
CollectionType.elements
elements: Type;
ListType
type ListType = object;
The elements of a list are ordered.
All elements of a list have the same type, but it can be a broad type,
up to any
.
The same element can be present in the list more than once.
A list can be multi-dimensional. For example, a list of integers with dimensions 2x3x4 is a 3D tensor with 2 layers, 3 rows and 4 columns.
Type declaration
kind
ListType.kind
kind: "list";
elements
ListType.elements
elements: Type;
dimensions?
ListType.dimensions?
optional dimensions: number[];
SetType
type SetType = object;
Each element of a set is unique (is not present in the set more than once). The elements of a set are not ordered.
Type declaration
kind
SetType.kind
kind: "set";
elements
SetType.elements
elements: Type;
TupleType
type TupleType = object;
Type declaration
kind
TupleType.kind
kind: "tuple";
elements
TupleType.elements
elements: NamedElement[];
TypeReference
type TypeReference = object;
Nominal typing
Type declaration
kind
TypeReference.kind
kind: "reference";
ref
TypeReference.ref
ref: string;
Type
type Type =
| PrimitiveType
| AlgebraicType
| NegationType
| CollectionType
| ListType
| SetType
| MapType
| TupleType
| FunctionSignature
| ValueType
| TypeReference;
TypeString
type TypeString = string;
The type of a boxed expression indicates the kind of expression it is and the value it represents.
The type is represented either by a primitive type (e.g. number, complex, collection, etc.), or a compound type (e.g. tuple, function signature, etc.).
Types are described using the following BNF grammar:
<type> ::= <union_type> | "(" <type> ")"
<union_type> ::= <intersection_type> (" | " <intersection_type>)*
<intersection_type> ::= <primary_type> (" & " <primary_type>)*
<primary_type> ::= <primitive>
| <tuple_type>
| <signature>
| <list_type>
<primitive> ::= "any" | "unknown" | <value-type> | <symbolic-type> | <numeric-type>
<numeric-type> ::= "number" | "complex" | "imaginary" | "real" | "rational" | "integer"
<value-type> ::= "value" | <numeric-type> | "collection" | "boolean" | "string"
<symbolic-type> ::= "expression" | "function" | "symbol"
<tuple_type> ::= "tuple<" (<name> <type> "," <named_tuple_elements>*) ">"
| "tuple<" (<type> "," <unnamed_tuple_elements>*) ">" |
| "tuple<" <tuple_elements> ">"
<tuple_elements> ::= <unnamed_tuple_elements> | <named_tuple_elements>
<unnamed_tuple_elements> ::= <type> ("," <type>)*
<named_tuple_elements> ::= <name> <type> ("," <name> <type>)*
<signature> ::= <arguments> " -> " <type>
<arguments> ::= "()"
| <argument>
| "(" <argument-list> ")"
<argument> ::= <type>
| <name> <type>
<rest_argument> ::= "..." <type>
| <name> "..." <type>
<optional_argument> ::= <argument> "?"
<optional_arguments> ::= <optional_argument> ("," <optional_argument>)*
<required_arguments> ::= <argument> ("," <argument>)*
<argument-list> ::= <required_arguments> ("," <rest_argument>)?
| <required_arguments> <optional_arguments>?
| <optional_arguments>?
| <rest_argument>
<list_type> ::= "list<" <type> <dimensions>? ">"
<dimensions> ::= "^" <fixed_size>
| "^(" <multi_dimensional_size> ")"
<fixed_size> ::= <positive-integer_literal>
<multi_dimensional_size> ::= <positive-integer_literal> "x" <positive-integer_literal> ("x" <positive-integer_literal>)*
<map> ::= "map" | "map<" <map_elements> ">"
<map_elements> ::= <name> <type> ("," <name> <type>)*
<set> ::= "set<" <type> ">"
<collection ::= "collection<" <type> ">"
<name> ::= <identifier> ":"
<identifier> ::= [a-zA-Z_][a-zA-Z0-9_]*
<positive-integer_literal> ::= [1-9][0-9]*
Examples of types strings:
"number"
-- a simple type primitive"(number, boolean)"
-- a tuple type"(x: number, y:boolean)"
-- a named tuple/record type. Either all arguments are named, or none are"collection<any>"
-- an arbitrary collection type, with no length or element type restrictions"collection<integer>"
-- a collection type where all the elements are integers"collection<(number, boolean)>"
-- a collection of tuples"collection<(value:number, seen:boolean)>"
-- a collection of named tuples"[boolean]^32"
-- a collection type with a fixed size of 32 elements"[integer]^(2x3)"
-- an integer matrix of 2 columns and 3 rows"[integer]^(2x3x4)"
-- a tensor of dimensions 2x3x4"number -> number"
-- a signature with a single argument"(x: number, number) -> number"
-- a signature with a named argument"(number, y:number?) -> number"
-- a signature with an optional named argument (can have several optional arguments, at the end)"(number, ...number) -> number"
-- a signature with a rest argument (can have only one, and no optional arguments if there is a rest argument)."() -> number"
-- a signature with an empty argument list"number | boolean"
-- a union type"(x: number) & (y: number)"
-- an intersection type"number | ((x: number) & (y: number))"
-- a union type with an intersection type"(number -> number) | number"
-- a union type with a signature and a primitive type
TypeCompatibility
type TypeCompatibility = "covariant" | "contravariant" | "bivariant" | "invariant";
TypeResolver()
type TypeResolver = (name) => Type | undefined;
name
string
Type
| undefined
The Compute Engine is a symbolic computation engine that can be used to manipulate and evaluate mathematical expressions.
Use an instance of ComputeEngine to create boxed expressions with ComputeEngine.parse and ComputeEngine.box.
Use a BoxedExpression
object to manipulate and evaluate
mathematical expressions.
Compute Engine
SimplifyOptions
type SimplifyOptions = object;
Options for BoxedExpression.simplify()
Type declaration
rules?
SimplifyOptions.rules?
optional rules:
| null
| Rule
| ReadonlyArray<
| BoxedRule
| Rule>
| BoxedRuleSet;
The set of rules to apply. If null
, use no rules. If not provided,
use the default simplification rules.
costFunction()?
SimplifyOptions.costFunction()?
optional costFunction: (expr) => number;
Use this cost function to determine if a simplification is worth it.
If not provided, ce.costFunction
, the cost function of the engine is
used.
expr
number
ArrayValue
type ArrayValue =
| boolean
| number
| string
| BigNum
| BoxedExpression
| undefined;
JsonSerializationOptions
type JsonSerializationOptions = object;
Options to control the serialization to MathJSON when using BoxedExpression.toMathJson()
.
Type declaration
prettify
JsonSerializationOptions.prettify
prettify: boolean;
If true, the serialization applies some transformations to make
the JSON more readable. For example, ["Power", "x", 2]
is serialized
as ["Square", "x"]
.
exclude
JsonSerializationOptions.exclude
exclude: string[];
A list of space separated function names that should be excluded from the JSON output.
Those functions are replaced with an equivalent, for example, Square
with
Power
, etc...
Possible values include Sqrt
, Root
, Square
, Exp
, Subtract
,
Rational
, Complex
Default: []
(none)
shorthands
JsonSerializationOptions.shorthands
shorthands: ("all" | "number" | "symbol" | "function" | "string")[];
A list of space separated keywords indicating which MathJSON expressions can use a shorthand.
Default: ["all"]
metadata
JsonSerializationOptions.metadata
metadata: ("all" | "wikidata" | "latex")[];
A list of space separated keywords indicating which metadata should be included in the MathJSON. If metadata is included, shorthand notation is not used.
Default: []
(none)
repeatingDecimal
JsonSerializationOptions.repeatingDecimal
repeatingDecimal: boolean;
If true, repeating decimals are detected and serialized accordingly For example:
1.3333333333333333
( \to )1.(3)
0.142857142857142857142857142857142857142857142857142
( \to )0.(1428571)
Default: true
fractionalDigits
JsonSerializationOptions.fractionalDigits
fractionalDigits: "auto" | "max" | number;
The maximum number of significant digits in serialized numbers.
"max"
: all availabe digits are serialized."auto"
: use the same precision as the compute engine.
Default: "auto"
Scope
type Scope = object;
A scope is a set of names in a dictionary that are bound (defined) in a MathJSON expression.
Scopes are arranged in a stack structure. When an expression that defined a new scope is evaluated, the new scope is added to the scope stack. Outside of the expression, the scope is removed from the scope stack.
The scope stack is used to resolve symbols, and it is possible for a scope to 'mask' definitions from previous scopes.
Scopes are lexical (also called a static scope): they are defined based on where they are in an expression, they are not determined at runtime.
AngularUnit
type AngularUnit = "rad" | "deg" | "grad" | "turn";
When a unitless value is passed to or returned from a trigonometric function, the angular unit of the value.
rad
: radians, 2π radians is a full circledeg
: degrees, 360 degrees is a full circlegrad
: gradians, 400 gradians is a full circleturn
: turns, 1 turn is a full circle
RuntimeScope
type RuntimeScope = Scope & object;
Type declaration
parentScope?
RuntimeScope.parentScope?
optional parentScope: RuntimeScope;
ids?
RuntimeScope.ids?
optional ids: RuntimeIdentifierDefinitions;
assumptions
RuntimeScope.assumptions
assumptions:
| undefined
| ExpressionMapInterface<boolean>;
AssignValue
type AssignValue =
| boolean
| number
| SemiBoxedExpression
| (args, options) => BoxedExpression
| undefined;
Boxed Expression
BoxedExpression
The BoxedExpression
interface includes the methods and properties
applicable to any kind of expression, for example expr.symbol
or
expr.ops
.
When a member function is not applicable to this BoxedExpression
,
for example get symbol()
on a BoxedNumber
, it returns null
.
This convention makes it convenient to manipulate expressions without having to check what kind of instance they are before manipulating them.
To get a boxed expression from a LaTeX string use ce.parse()
, and to
get a boxed expression from a MathJSON expression use ce.box()
.
Function Expression
BoxedExpression.ops
readonly ops: readonly BoxedExpression[];
The list of operands of the function.
If the expression is not a function, return null
.
Applicable to canonical and non-canonical expressions.
BoxedExpression.nops
readonly nops: number;
If this expression is a function, the number of operands, otherwise 0.
Note that a function can have 0 operands, so to check if this expression
is a function, check if this.ops !== null
instead.
Applicable to canonical and non-canonical expressions.
BoxedExpression.op1
readonly op1: BoxedExpression;
First operand, i.e.this.ops[0]
.
If there is no first operand, return the symbol Nothing
.
Applicable to canonical and non-canonical expressions.
BoxedExpression.op2
readonly op2: BoxedExpression;
Second operand, i.e.this.ops[1]
If there is no second operand, return the symbol Nothing
.
Applicable to canonical and non-canonical expressions.
BoxedExpression.op3
readonly op3: BoxedExpression;
Third operand, i.e. this.ops[2]
If there is no third operand, return the symbol Nothing
.
Applicable to canonical and non-canonical expressions.
Numeric Expression
BoxedExpression.isNaN
readonly isNaN: boolean;
"Not a Number".
A value representing undefined result of computations, such as 0/0
,
as per the floating point format standard IEEE-754.
Note that if isNaN
is true, isNumber
is also true (yes, NaN
is a
number).
BoxedExpression.isInfinity
readonly isInfinity: boolean;
The numeric value of this expression is ±Infinity
or Complex Infinity
BoxedExpression.isFinite
readonly isFinite: boolean;
This expression is a number, but not ±Infinity
, 'ComplexInfinityor
NaN`
BoxedExpression.isEven
readonly isEven: boolean;
BoxedExpression.isOdd
readonly isOdd: boolean;
BoxedExpression.numericValue
readonly numericValue: number | NumericValue;
Return the value of this expression, if a number literal.
Note it is possible for this.numericValue
to be null
, and for
this.isNotZero
to be true. For example, when a symbol has been
defined with an assumption.
Conversely, this.isNumber
may be true even if numericValue
is null
,
example the symbol Pi
return true
for isNumber
but numericValue
is
null
. Its value can be accessed with .N().numericValue
.
To check if an expression is a number literal, use this.isNumberLiteral
.
If this.isNumberLiteral
is true
, this.numericValue
is not null
BoxedExpression.isNumberLiteral
readonly isNumberLiteral: boolean;
Return true
if this expression is a number literal, for example
2
, 3.14
, 1/2
, √2
etc.
This is equivalent to checking if this.numericValue
is not null
.
BoxedExpression.re
readonly re: number;
If this expression is a number literal or a symbol with a value that is a number literal, return the real part of the value.
If the expression is not a number literal, or a symbol with a value
that is a number literal, return NaN
(not a number).
BoxedExpression.im
readonly im: number;
If this expression is a number literal or a symbol with a value that is a number literal, return the imaginary part of the value. If the value is a real number, the imaginary part is 0.
If the expression is not a number literal, or a symbol with a value
that is a number literal, return NaN
(not a number).
BoxedExpression.bignumRe
readonly bignumRe: Decimal;
If this expression is a number literal or a symbol with a value that
is a number literal, return the real part of the value as a BigNum
.
If the value is not available as a bignum return undefined
. That is,
the value is not upconverted to a bignum.
To get the real value either as a bignum or a number, use
this.bignumRe ?? this.re
. When using this pattern, the value is
returned as a bignum if available, otherwise as a number or NaN if
the value is not a number literal or a symbol with a value that is a
number literal.
BoxedExpression.bignumIm
readonly bignumIm: Decimal;
If this expression is a number literal, return the imaginary part as a
BigNum
.
It may be 0 if the number is real.
If the expression is not a number literal or the value is not available
as a bignum return undefined
. That is, the value is not upconverted
to a bignum.
To get the imaginary value either as a bignum or a number, use
this.bignumIm ?? this.im
. When using this pattern, the value is
returned as a bignum if available, otherwise as a number or NaN if
the value is not a number literal or a symbol with a value that is a
number literal.
BoxedExpression.sgn
readonly sgn: Sign;
Return the sign of the expression.
Note that complex numbers have no natural ordering,
so if the value is an imaginary number (a complex number with a non-zero
imaginary part), this.sgn
will return unsigned
.
If a symbol, this does take assumptions into account, that is this.sgn
will return positive
if the symbol is assumed to be positive
(using ce.assume()
).
BoxedExpression.isPositive
readonly isPositive: boolean;
The numeric value of this expression is > 0, same as isGreater(0)
BoxedExpression.isNonNegative
readonly isNonNegative: boolean;
The numeric value of this expression is >= 0, same as isGreaterEqual(0)
BoxedExpression.isNegative
readonly isNegative: boolean;
The numeric value of this expression is < 0, same as isLess(0)
BoxedExpression.isNonPositive
readonly isNonPositive: boolean;
The numeric value of this expression is <= 0, same as isLessEqual(0)
Other
BoxedExpression.engine
readonly engine: IComputeEngine;
The Compute Engine associated with this expression provides a context in which to interpret it, such as definition of symbols and functions.
BoxedExpression.toMathJson()
toMathJson(options?): Expression
Serialize to a MathJSON expression with specified options
options?
Readonly
<Partial
<JsonSerializationOptions
>>
BoxedExpression.toLatex()
toLatex(options?): string
Serialize to a LaTeX string.
Will ignore any LaTeX metadata.
options?
Partial
<SerializeLatexOptions
>
string
BoxedExpression.verbatimLatex?
optional verbatimLatex: string;
BoxedExpression.isCanonical
Get Signature
get isCanonical(): boolean
If true
, this expression is in a canonical form.
boolean
BoxedExpression.isStructural
Get Signature
get isStructural(): boolean
If true
, this expression is in a structural form.
boolean
BoxedExpression.json
readonly json: Expression;
MathJSON representation of this expression.
This representation always use shorthands when possible. Metadata is not included.
Numbers are converted to JavaScript numbers and may lose precision.
The expression is represented exactly and no sugaring is applied. For
example, ["Power", "x", 2]
is not represented as ["Square", "x"]
.
For more control over the serialization, use expr.toMathJson()
.
Applicable to canonical and non-canonical expressions.
BoxedExpression.scope
readonly scope: object;
The scope in which this expression has been defined.
Is null
when the expression is not canonical.
parentScope?
scope.parentScope?
optional parentScope: { parentScope?: ...; ids?: RuntimeIdentifierDefinitions; assumptions: ExpressionMapInterface<boolean>; };
ids?
scope.ids?
optional ids: RuntimeIdentifierDefinitions;
assumptions
scope.assumptions
assumptions: ExpressionMapInterface<boolean>;
BoxedExpression.latex
Get Signature
get latex(): string
LaTeX representation of this expression.
If the expression was parsed from LaTeX, the LaTeX representation is the same as the input LaTeX.
To customize the serialization, use expr.toLatex()
.
Applicable to canonical and non-canonical expressions.
string
BoxedExpression.getSubexpressions()
getSubexpressions(name): readonly BoxedExpression[]
All the subexpressions matching the named operator, recursively.
Applicable to canonical and non-canonical expressions.
name
string
readonly BoxedExpression
[]
BoxedExpression.subexpressions
readonly subexpressions: readonly BoxedExpression[];
All the subexpressions in this expression, recursively
Applicable to canonical and non-canonical expressions.
BoxedExpression.symbols
readonly symbols: readonly string[];
All the symbols in the expression, recursively
Applicable to canonical and non-canonical expressions.
BoxedExpression.unknowns
readonly unknowns: readonly string[];
All the identifiers used in the expression that do not have a value associated with them, i.e. they are declared but not defined.
BoxedExpression.freeVariables
readonly freeVariables: readonly string[];
All the identifiers (symbols and functions) in the expression that are not a local variable or a parameter of that function.
BoxedExpression.errors
readonly errors: readonly BoxedExpression[];
All the ["Error"]
subexpressions.
If an expression includes an error, the expression is also an error.
In that case, the this.isValid
property is false
.
Applicable to canonical and non-canonical expressions.
BoxedExpression.operator
readonly operator: string;
The name of the operator of the expression.
For example, the name of the operator of ["Add", 2, 3]
is "Add"
.
A string literal has a "String"
operator.
A symbol has a "Symbol"
operator.
A number has a "Number"
, "Real"
, "Rational"
or "Integer"
operator.
BoxedExpression.isPure
readonly isPure: boolean;
If true, the value of the expression never changes and evaluating it has no side-effects.
If false, the value of the expression may change, if the value of other expression changes or for other reasons.
If this.isPure
is false
, this.value
is undefined. Call
this.evaluate()
to determine the value of the expression instead.
As an example, the Random
function is not pure.
Applicable to canonical and non-canonical expressions.
BoxedExpression.isConstant
readonly isConstant: boolean;
True if the the value of the expression does not depend on the value of any other expression.
For example, a number literal, a symbol with a constant value.
2
is constantPi
is constant["Add", "Pi", 2]
is constantx
is not constant["Add", "x", 2]
is not constant
BoxedExpression.canonical
Get Signature
get canonical(): BoxedExpression
Return the canonical form of this expression.
If this is a function expression, a definition is associated with the canonical expression.
When determining the canonical form the following function definition flags are applied:
associative
: \( f(a, f(b), c) \longrightarrow f(a, b, c) \)idempotent
: \( f(f(a)) \longrightarrow f(a) \)involution
: \( f(f(a)) \longrightarrow a \)commutative
: sort the arguments.
If this expression is already canonical, the value of canonical is
this
.
BoxedExpression.structural
Get Signature
get structural(): BoxedExpression
Return the structural form of this expression.
Some expressions, such as rational numbers, are represented with
a BoxedExpression
object. In some cases, for example when doing a
structural comparison of two expressions, it is useful to have a
structural representation of the expression where the rational numbers
is represented by a function expression instead.
If there is a structural representation of the expression, return it,
otherwise return this
.
BoxedExpression.subs()
subs(sub, options?): BoxedExpression
Replace all the symbols in the expression as indicated.
Note the same effect can be achieved with this.replace()
, but
using this.subs()
is more efficient, and simpler, but limited
to replacing symbols.
The result is bound to the current scope, not to this.scope
.
If options.canonical
is not set, the result is canonical if this
is canonical.
Applicable to canonical and non-canonical expressions.
sub
options?
canonical
BoxedExpression.map()
map(fn, options?): BoxedExpression
Recursively replace all the subexpressions in the expression as indicated.
To remove a subexpression, return an empty ["Sequence"]
expression.
The canonical option is applied to each function subexpression after the substitution is applied.
If no options.canonical
is set, the result is canonical if this
is canonical.
Default: { canonical: this.isCanonical, recursive: true }
fn
(expr
) => BoxedExpression
options?
canonical
recursive
boolean
BoxedExpression.replace()
replace(rules, options?): BoxedExpression
Transform the expression by applying one or more replacement rules:
-
If the expression matches the
match
pattern and thecondition
predicate is true, replace it with thereplace
pattern. -
If no rules apply, return
null
.
See also expr.subs()
for a simple substitution of symbols.
If options.canonical
is not set, the result is canonical if this
is canonical.
Applicable to canonical and non-canonical expressions.
rules
Rule
| BoxedRuleSet
| Rule
[]
options?
Partial
<ReplaceOptions
>
BoxedExpression.has()
has(v): boolean
True if the expression includes a symbol v
or a function operator v
.
Applicable to canonical and non-canonical expressions.
v
string
| string
[]
boolean
BoxedExpression.numerator
Get Signature
get numerator(): BoxedExpression
Return this expression expressed as a numerator and denominator.
BoxedExpression.numeratorDenominator
Get Signature
get numeratorDenominator(): [BoxedExpression, BoxedExpression]
BoxedExpression.match()
match(pattern, options?): BoxedSubstitution
If this expression matches pattern
, return a substitution that makes
pattern
equal to this
. Otherwise return null
.
If pattern
includes wildcards (identifiers that start
with _
), the substitution will include a prop for each matching named
wildcard.
If this expression matches pattern
but there are no named wildcards,
return the empty substitution, {}
.
Read more about patterns and rules.
Applicable to canonical and non-canonical expressions.
pattern
options?
BoxedExpression.isFunctionExpression
readonly isFunctionExpression: boolean;
Return true
if this expression is a function expression.
If true
, this.ops
is not null
, and this.operator
is the name
of the function.
BoxedExpression.toNumericValue()
toNumericValue(): [NumericValue, BoxedExpression]
Attempt to factor a numeric coefficient c
and a rest
out of a
canonical expression such that rest.mul(c)
is equal to this
.
Attempts to make rest
a positive value (i.e. pulls out negative sign).
['Multiply', 2, 'x', 3, 'a']
-> [NumericValue(6), ['Multiply', 'x', 'a']]
['Divide', ['Multiply', 2, 'x'], ['Multiply', 3, 'y', 'a']]
-> [NumericValue({rational: [2, 3]}), ['Divide', 'x', ['Multiply, 'y', 'a']]]
BoxedExpression.shape
readonly shape: number[];
The shape describes the axis of the expression.
When the expression is a scalar (number), the shape is []
.
When the expression is a vector of length n
, the shape is [n]
.
When the expression is a n
by m
matrix, the shape is [n, m]
.
BoxedExpression.rank
readonly rank: number;
Return 0 for a scalar, 1 for a vector, 2 for a matrix, > 2 for a multidimensional matrix.
The rank is equivalent to the length of expr.shape
BoxedExpression.wikidata
readonly wikidata: string;
Wikidata identifier.
undefined
if not a canonical expression.
BoxedExpression.description
readonly description: string[];
An optional short description if a symbol or function expression.
May include markdown. Each string is a paragraph.
undefined
if not a canonical expression.
BoxedExpression.url
readonly url: string;
An optional URL pointing to more information about the symbol or function operator.
undefined
if not a canonical expression.
BoxedExpression.complexity
readonly complexity: number;
Expressions with a higher complexity score are sorted first in commutative functions
undefined
if not a canonical expression.
BoxedExpression.baseDefinition
readonly baseDefinition: BoxedBaseDefinition;
For symbols and functions, a definition associated with the
expression. this.baseDefinition
is the base class of symbol and function
definition.
undefined
if not a canonical expression.
BoxedExpression.functionDefinition
readonly functionDefinition: BoxedFunctionDefinition;
For functions, a definition associated with the expression.
undefined
if not a canonical expression or not a function.
BoxedExpression.symbolDefinition
readonly symbolDefinition: BoxedSymbolDefinition;
For symbols, a definition associated with the expression.
Return undefined
if not a symbol
BoxedExpression.simplify()
simplify(options?): BoxedExpression
Return a simpler form of this expression.
A series of rewriting rules are applied repeatedly, until no more rules apply.
The values assigned to symbols and the assumptions about symbols may be
used, for example expr.isInteger
or expr.isPositive
.
No calculations involving decimal numbers (numbers that are not integers) are performed but exact calculations may be performed, for example:
\sin(\frac{\pi}{4}) \longrightarrow \frac{\sqrt{2}}{2}
.
The result is canonical.
To manipulate symbolically non-canonical expressions, use expr.replace()
.
options?
Partial
<SimplifyOptions
>
BoxedExpression.expand()
expand(): BoxedExpression
Expand the expression: distribute multiplications over additions, and expand powers.
BoxedExpression.evaluate()
evaluate(options?): BoxedExpression
Return the value of the canonical form of this expression.
A pure expression always return the same value and has no side effects.
If expr.isPure
is true
, expr.value
and expr.evaluate()
are
synonyms.
For an impure expression, expr.value
is undefined.
Evaluating an impure expression may have some side effects, for
example modifying the ComputeEngine
environment, such as its set of
assumptions.
The result may be a rational number or the product of a rational number and the square root of an integer.
To perform approximate calculations, use expr.N()
instead,
or set options.numericApproximation
to true
.
The result of expr.evaluate()
may be the same as expr.simplify()
.
The result is in canonical form.
options?
Partial
<EvaluateOptions
>
BoxedExpression.evaluateAsync()
evaluateAsync(options?): Promise<BoxedExpression>
Asynchronous version of evaluate()
.
The options
argument can include a signal
property, which is an
AbortSignal
object. If the signal is aborted, a CancellationError
is thrown.
options?
Partial
<EvaluateOptions
>
Promise
<BoxedExpression
>
BoxedExpression.N()
N(): BoxedExpression
Return a numeric approximation of the canonical form of this expression.
Any necessary calculations, including on decimal numbers (non-integers), are performed.
The calculations are performed according to the
precision
property of the ComputeEngine
.
To only perform exact calculations, use this.evaluate()
instead.
If the function is not numeric, the result of this.N()
is the same as
this.evaluate()
.
The result is in canonical form.
BoxedExpression.compile()
compile(options?): (args?) => CompiledType
Compile the expression to a JavaScript function.
The function takes an object as argument, with the keys being the symbols in the expression, and returns the value of the expression.
const expr = ce.parse('x^2 + y^2');
const f = expr.compile();
console.log(f({x: 2, y: 3}));
options?
to
"javascript"
optimize
("evaluate"
| "simplify"
)[]
functions
Record
<string
, string
| (...any
) => any
>
vars
Record
<string
, CompiledType
>
imports
unknown
[]
preamble
string
Function
args?
Record
<string
, CompiledType
>
BoxedExpression.solve()
solve(vars?): readonly BoxedExpression[]
If this is an equation, solve the equation for the variables in vars.
Otherwise, solve the equation this = 0
for the variables in vars.
const expr = ce.parse('x^2 + 2*x + 1 = 0');
console.log(expr.solve('x'));
vars?
string
| Iterable
<string
> | BoxedExpression
| Iterable
<BoxedExpression
>
readonly BoxedExpression
[]
BoxedExpression.value
Get Signature
get value(): string | number | boolean | object
Return a JavaScript primitive representing the value of this expression.
Equivalent to expr.N().valueOf()
.
string
| number
| boolean
| object
set value(value): void
Only the value of variables can be changed (symbols that are not constants).
Throws a runtime error if a constant.
If non-canonical, does nothing
Parameters
value
string
| number
| boolean
| number
[] | Decimal
| BoxedExpression
| {
re
: number
;
im
: number
;
} | {
num
: number
;
denom
: number
;
}
void
BoxedExpression.type
Get Signature
get type(): BoxedType
The type of the value of this expression.
If a function expression, the type of the value of the function (the result type).
If a symbol the type of the value of the symbol.
If not valid, return "error"
.
If non-canonical, return undefined
.
If the type is not known, return "unknown"
.
set type(type): void
Parameters
type
string
| AlgebraicType
| NegationType
| CollectionType
| ListType
| SetType
| MapType
| TupleType
| FunctionSignature
| ValueType
| TypeReference
| BoxedType
void
BoxedExpression.isCollection
isCollection: boolean;
Return true if the expression is a collection: a list, a vector, a matrix, a map, a tuple, etc...
BoxedExpression.contains()
contains(rhs): boolean
If this is a collection, return true if the rhs
expression is in the
collection.
Return undefined
if the membership cannot be determined.
rhs
boolean
BoxedExpression.size
Get Signature
get size(): number
If this is a collection, return the number of elements in the collection.
If the collection is infinite, return Infinity
.
number
BoxedExpression.each()
each: (start?, count?) => Iterator<BoxedExpression, undefined>;
If this is a collection, return an iterator over the elements of the collection.
If start
is not specified, start from the first element.
If count
is not specified or negative, return all the elements from start
to the end.
const expr = ce.parse('[1, 2, 3, 4]');
for (const e of expr.each()) {
console.log(e);
}
start?
number
count?
number
Iterator
<BoxedExpression
, undefined
>
BoxedExpression.at()
at(index): BoxedExpression
If this is an indexable collection, return the element at the specified index.
If the index is negative, return the element at index size() + index + 1
.
index
number
BoxedExpression.get()
get(key): BoxedExpression
If this is a map or a tuple, return the value of the corresponding key.
If key
is a BoxedExpression
, it should be a string.
key
string
| BoxedExpression
BoxedExpression.indexOf()
indexOf(expr): number
If this is an indexable collection, return the index of the first element that matches the target expression.
expr
number
Primitive Methods
BoxedExpression.valueOf()
valueOf(): any
From Object.valueOf()
, return a primitive value for the expression.
If the expression is a machine number, or bignum or rational that can be
converted to a machine number, return a JavaScript number
.
If the expression is a symbol, return the name of the symbol as a string
.
Otherwise return a JavaScript primitive representation of the expression.
any
BoxedExpression.toString()
toString(): string
From Object.toString()
, return a string representation of the
expression. This string is suitable to be output to the console
for debugging, for example. It is formatted as a ASCIIMath expression.
To get a LaTeX representation of the expression, use expr.latex
.
Used when coercing a BoxedExpression
to a String
.
string
BoxedExpression.print()
print(): void
Output to the console a string representation of the expression.
void
BoxedExpression.[toPrimitive]()
toPrimitive: string | number
Similar toexpr.valueOf()
but includes a hint.
hint
"string"
| "number"
| "default"
string
| number
BoxedExpression.toJSON()
toJSON(): Expression
Used by JSON.stringify()
to serialize this object to JSON.
Method version of expr.json
.
BoxedExpression.is()
is(rhs): boolean
Equivalent to BoxedExpression.isSame()
but the argument can be
a JavaScript primitive. For example, expr.is(2)
is equivalent to
expr.isSame(ce.number(2))
.
rhs
any
boolean
Relational Operator
BoxedExpression.isSame()
isSame(rhs): boolean
Structural/symbolic equality (weak equality).
ce.parse('1+x').isSame(ce.parse('x+1'))
is false
.
See expr.isEqual()
for mathematical equality.
Applicable to canonical and non-canonical expressions.
rhs
boolean
BoxedExpression.isLess()
isLess(other): boolean
If the expressions cannot be compared, return undefined
The numeric value of both expressions are compared.
The expressions are evaluated before being compared, which may be expensive.
other
number
| BoxedExpression
boolean
BoxedExpression.isLessEqual()
isLessEqual(other): boolean
The numeric value of both expressions are compared.
other
number
| BoxedExpression
boolean
BoxedExpression.isGreater()
isGreater(other): boolean
The numeric value of both expressions are compared.
other
number
| BoxedExpression
boolean
BoxedExpression.isGreaterEqual()
isGreaterEqual(other): boolean
The numeric value of both expressions are compared.
other
number
| BoxedExpression
boolean
BoxedExpression.isEqual()
isEqual(other): boolean
Mathematical equality (strong equality), that is the value
of this expression and the value of other
are numerically equal.
Both expressions are evaluated and the result is compared numerically.
Numbers whose difference is less than engine.tolerance
are
considered equal. This tolerance is set when the engine.precision
is
changed to be such that the last two digits are ignored.
The evaluations may be expensive operations. Other options to consider to compare two expressions include:
expr.isSame(other)
for a structural comparisonexpr.is(other)
for a comparison of a number literal
Examples
let expr = ce.parse('2 + 2');
console.log(expr.isEqual(4)); // true
console.log(expr.isSame(ce.parse(4))); // false
console.log(expr.is(4)); // false
expr = ce.parse('4');
console.log(expr.isEqual(4)); // true
console.log(expr.isSame(ce.parse(4))); // true
console.log(expr.is(4)); // true (fastest)
other
number
| BoxedExpression
boolean
String Expression
BoxedExpression.string
readonly string: string;
If this expression is a string, return the value of the string.
Otherwise, return null
.
Applicable to canonical and non-canonical expressions.
Symbol Expression
BoxedExpression.symbol
readonly symbol: string;
If this expression is a symbol, return the name of the symbol as a string.
Otherwise, return null
.
Applicable to canonical and non-canonical expressions.
BoxedExpression.tensor
readonly tensor: AbstractTensor<"expression">;
BoxedExpression.isValid
readonly isValid: boolean;
true
if this expression or any of its subexpressions is an ["Error"]
expression.
Applicable to canonical and non-canonical expressions. For non-canonical expression, this may indicate a syntax error while parsing LaTeX. For canonical expression, this may indicate argument type mismatch, or missing or unexpected arguments.
Type Properties
BoxedExpression.isNumber
readonly isNumber: boolean;
true
if the value of this expression is a number.
Note that in a fateful twist of cosmic irony, NaN
("Not a Number")
is a number.
If isNumber
is true
, this indicates that evaluating the expression
will return a number.
This does not indicate that the expression is a number literal. To check
if the expression is a number literal, use expr.isNumberLiteral
.
For example, the expression ["Add", 1, "x"]
is a number if "x" is a
number and expr.isNumber
is true
, but isNumberLiteral
is false
.
BoxedExpression.isInteger
readonly isInteger: boolean;
The value of this expression is an element of the set ℤ: ...,-2, -1, 0, 1, 2...
Note that ±∞ and NaN are not integers.
BoxedExpression.isRational
readonly isRational: boolean;
The value of this expression is an element of the set ℚ, p/q with p ∈ ℕ, q ∈ ℤ ⃰ q >= 1
Note that every integer is also a rational.
This is equivalent to this.type === "rational" || this.type === "integer"
Note that ±∞ and NaN are not rationals.
BoxedExpression.isReal
readonly isReal: boolean;
The value of this expression is a real number.
This is equivalent to this.type === "rational" || this.type === "integer" || this.type === "real"
Note that ±∞ and NaN are not real numbers.
SemiBoxedExpression
type SemiBoxedExpression =
| number
| bigint
| string
| BigNum
| MathJsonNumber
| MathJsonString
| MathJsonSymbol
| MathJsonFunction
| readonly [MathJsonIdentifier, ...SemiBoxedExpression[]]
| BoxedExpression;
A semi boxed expression is a MathJSON expression which can include some boxed terms.
This is convenient when creating new expressions from portions
of an existing BoxedExpression
while avoiding unboxing and reboxing.
ReplaceOptions
type ReplaceOptions = object;
Type declaration
recursive
ReplaceOptions.recursive
recursive: boolean;
If true
, apply replacement rules to all sub-expressions.
If false
, only consider the top-level expression.
Default: false
once
ReplaceOptions.once
once: boolean;
If true
, stop after the first rule that matches.
If false
, apply all the remaining rules even after the first match.
Default: false
useVariations
ReplaceOptions.useVariations
useVariations: boolean;
If true
the rule will use some equivalent variations to match.
For example when useVariations
is true:
x
matchesa + x
with a = 0x
matchesax
with a = 1- etc...
Setting this to true
can save time by condensing multiple rules
into one. This can be particularly useful when describing equations
solutions. However, it can lead to infinite recursion and should be
used with caution.
iterationLimit
ReplaceOptions.iterationLimit
iterationLimit: number;
If iterationLimit
> 1, the rules will be repeatedly applied
until no rules apply, up to maxIterations
times.
Note that if once
is true, iterationLimit
has no effect.
Default: 1
canonical
ReplaceOptions.canonical
canonical: CanonicalOptions;
Indicate if the expression should be canonicalized after the replacement. If not provided, the expression is canonicalized if the expression that matched the pattern is canonical.
Rational
type Rational =
| [SmallInteger, SmallInteger]
| [bigint, bigint];
A rational number is a number that can be expressed as the quotient or fraction p/q of two integers, a numerator p and a non-zero denominator q.
A rational can either be represented as a pair of small integers or a pair of big integers.
EvaluateOptions
type EvaluateOptions = object;
Options for BoxedExpression.evaluate()
Type declaration
numericApproximation
EvaluateOptions.numericApproximation
numericApproximation: boolean;
signal
EvaluateOptions.signal
signal: AbortSignal;
CanonicalForm
type CanonicalForm =
| "InvisibleOperator"
| "Number"
| "Multiply"
| "Add"
| "Power"
| "Divide"
| "Flatten"
| "Order";
When provided, canonical forms are used to put an expression in a "standard" form.
Each canonical form applies some transformation to an expression. When specified as an array, each transformation is done in the order in which it was provided.
InvisibleOperator
: replace use of theInvisibleOperator
with another operation, such as multiplication (i.e.2x
or function application (f(x)
).Number
: replace all numeric values with their canonical representation, for example, reduce rationals and replace complex numbers with no imaginary part with a real number.Multiply
: replace negation with multiplication by -1, remove 1 from multiplications, simplify signs (-y \times -x
->x \times y
), complex numbers are promoted (['Multiply', 2, 'ImaginaryUnit'] ->["Complex", 0, 2]
)Add
: replaceSubtract
withAdd
, removes 0 in addition, promote complex numbers (["Add", "a", ["Complex", 0, "b"] ->["Complex", "a", "b"]
)Power
: simplifyPower
expression, for example,x^{-1}
->\frac{1}{x}
,x^0
->1
,x^1
->x
,1^x
->1
,x^{\frac{1}{2}}
->\sqrt{x}
,a^b^c
->a^{bc}
...Divide
: replace with aRational
number if numerator and denominator are integers, simplify, e.g.\frac{x}{1}
->x
...Flatten
: remove any unnecessaryDelimiter
expression, and flatten any associative functions, for example["Add", ["Add", "a", "b"], "c"]
->["Add", "a", "b", "c"]
Order
: when applicable, sort the arguments in a specific order, for example for addition and multiplication.
Metadata
type Metadata = object;
Metadata that can be associated with a BoxedExpression
Type declaration
latex?
Metadata.latex?
optional latex: string;
wikidata?
Metadata.wikidata?
optional wikidata: string;
Substitution<T>
type Substitution<T> = object;
A substitution describes the values of the wildcards in a pattern so that the pattern is equal to a target expression.
A substitution can also be considered a more constrained version of a
rule whose match
is always a symbol.
Type Parameters
• T = SemiBoxedExpression
Index Signature
[symbol: string]: T
BoxedSubstitution
type BoxedSubstitution = Substitution<BoxedExpression>;
Pattern Matching
PatternMatchOptions
type PatternMatchOptions = object;
Control how a pattern is matched to an expression.
-
substitution
: if present, assumes these values for the named wildcards, and ensure that subsequent occurrence of the same wildcard have the same value. -
recursive
: if true, match recursively, otherwise match only the top level. -
useVariations
: if false, only match expressions that are structurally identical. If true, match expressions that are structurally identical or equivalent.For example, when true,
["Add", '_a', 2]
matches2
, with a value of_a
of0
. If false, the expression does not match. Default:false
Type declaration
substitution?
PatternMatchOptions.substitution?
optional substitution: BoxedSubstitution;
recursive?
PatternMatchOptions.recursive?
optional recursive: boolean;
useVariations?
PatternMatchOptions.useVariations?
optional useVariations: boolean;
Rules
RuleReplaceFunction()
type RuleReplaceFunction = (expr, wildcards) => BoxedExpression | undefined;
Given an expression and set of wildcards, return a new expression.
For example:
{
match: '_x',
replace: (expr, {_x}) => { return ['Add', 1, _x] }
}
expr
wildcards
BoxedExpression
| undefined
RuleConditionFunction()
type RuleConditionFunction = (wildcards, ce) => boolean;
wildcards
ce
IComputeEngine
boolean
RuleFunction()
type RuleFunction = (expr) =>
| undefined
| BoxedExpression
| RuleStep;
expr
| undefined
| BoxedExpression
| RuleStep
RuleStep
type RuleStep = object;
Type declaration
value
RuleStep.value
value: BoxedExpression;
because
RuleStep.because
because: string;
RuleSteps
type RuleSteps = RuleStep[];
Rule
type Rule =
| string
| RuleFunction
| {
match: | LatexString
| SemiBoxedExpression
| BoxedExpression;
replace: | LatexString
| SemiBoxedExpression
| RuleReplaceFunction
| RuleFunction;
condition: | LatexString
| RuleConditionFunction;
useVariations: boolean;
id: string;
};
A rule describes how to modify an expressions that matches a pattern match
into a new expression replace
.
x-1
( \to )1-x
(x+1)(x-1)
( \to ) `x^2-1
The patterns can be expressed as LaTeX strings or a MathJSON expressions.
As a shortcut, a rule can be defined as a LaTeX string: x-1 -> 1-x
.
The expression to the left of ->
is the match
and the expression to the
right is the replace
. When using LaTeX strings, single character variables
are assumed to be wildcards.
When using MathJSON expressions, anonymous wildcards (_
) will match any
expression. Named wildcards (_x
, _a
, etc...) will match any expression
and bind the expression to the wildcard name.
In addition the sequence wildcard (__1
, __a
, etc...) will match
a sequence of one or more expressions, and bind the sequence to the
wildcard name.
Sequence wildcards are useful when the number of elements in the sequence
is not known in advance. For example, in a sum, the number of terms is
not known in advance. ["Add", 0, __a
] will match two or more terms and
the __a
wildcard will be a sequence of the matchign terms.
If exact
is false, the rule will match variants.
For example 'x' will match 'a + x', 'x' will match 'ax', etc...
For simplification rules, you generally want exact
to be true, but
to solve equations, you want it to be false. Default to true.
When set to false, infinite recursion is possible.
BoxedRule
type BoxedRule = object;
If the match
property is undefined
, all expressions match this rule
and condition
should also be undefined
. The replace
property should
be a BoxedExpression
or a RuleFunction
, and further filtering can be
done in the replace
function.
Type declaration
match
BoxedRule.match
match: undefined | BoxedExpression;
replace
BoxedRule.replace
replace:
| BoxedExpression
| RuleReplaceFunction
| RuleFunction;
condition
BoxedRule.condition
condition:
| undefined
| RuleConditionFunction;
useVariations?
BoxedRule.useVariations?
optional useVariations: boolean;
id?
BoxedRule.id?
optional id: string;
BoxedRuleSet
type BoxedRuleSet = object;
To create a BoxedRuleSet use the ce.rules()
method.
Do not create a BoxedRuleSet
directly.
Type declaration
rules
BoxedRuleSet.rules
rules: ReadonlyArray<BoxedRule>;
Assumptions
ExpressionMapInterface<U>
Type Parameters
• U
ExpressionMapInterface.[iterator]()
iterator: IterableIterator<[BoxedExpression, U]>
IterableIterator
<[BoxedExpression
, U
]>
ExpressionMapInterface.entries()
entries(): IterableIterator<[BoxedExpression, U]>
IterableIterator
<[BoxedExpression
, U
]>
AssumeResult
type AssumeResult =
| "internal-error"
| "not-a-predicate"
| "contradiction"
| "tautology"
| "ok";
Compiling
CompiledType
type CompiledType = boolean | number | string | object;
CompiledExpression
type CompiledExpression = object;
Type declaration
evaluate()?
CompiledExpression.evaluate()?
optional evaluate: (scope) => number | BoxedExpression;
scope
number
| BoxedExpression
Definitions
EqHandlers
type EqHandlers = object;
These handlers compare two expressions.
If only one of the handlers is provided, the other is derived from it.
Having both may be useful if comparing non-equality is faster than equality.
Type declaration
eq()
neq()
Hold
type Hold = "none" | "all" | "first" | "rest" | "last" | "most";
SymbolDefinition
type SymbolDefinition = BaseDefinition & Partial<SymbolAttributes> & object;
A bound symbol (i.e. one with an associated definition) has either a type (e.g. ∀ x ∈ ℝ), a value (x = 5) or both (π: value = 3.14... type = 'real')
Type declaration
type?
SymbolDefinition.type?
optional type:
| Type
| TypeString;
inferred?
SymbolDefinition.inferred?
optional inferred: boolean;
If true, the type is inferred, and could be adjusted later as more information becomes available or if the symbol is explicitly declared.
value?
SymbolDefinition.value?
optional value:
| LatexString
| SemiBoxedExpression
| (ce) => BoxedExpression | null;
value
can be a JS function since for some constants, such as
Pi
, the actual value depends on the precision
setting of the
ComputeEngine
and possible other environment settings
flags?
SymbolDefinition.flags?
optional flags: Partial<NumericFlags>;
eq()?
neq()?
cmp()?
SymbolDefinition.cmp()?
optional cmp: (a) => "=" | ">" | "<" | undefined;
a
"="
| ">"
| "<"
| undefined
collection?
SymbolDefinition.collection?
optional collection: Partial<CollectionHandlers>;
FunctionDefinition
type FunctionDefinition = BaseDefinition & Partial<FunctionDefinitionFlags> & object;
Definition record for a function.
Type declaration
signature?
FunctionDefinition.signature?
optional signature:
| Type
| TypeString;
The function signature.
If a type
handler is provided, the return type of the function should
be a subtype of the return type in the signature.
type()?
FunctionDefinition.type()?
optional type: (ops, options) =>
| Type
| TypeString
| BoxedType
| undefined;
The actual type of the result based on the arguments.
Should be a subtype of the type indicated in the signature.
Do not evaluate the arguments.
The type of the arguments can be used to determine the type of the result.
ops
ReadonlyArray
<BoxedExpression
>
options
engine
IComputeEngine
| Type
| TypeString
| BoxedType
| undefined
sgn()?
FunctionDefinition.sgn()?
optional sgn: (ops, options) => Sign | undefined;
Return the sign of the function expression.
If the sign cannot be determined, return undefined
.
When determining the sign, only literal values and the values of symbols, if they are literals, should be considered.
Do not evaluate the arguments.
The type and sign of the arguments can be used to determine the sign.
ops
ReadonlyArray
<BoxedExpression
>
options
engine
IComputeEngine
Sign
| undefined
even()?
FunctionDefinition.even()?
optional even: (ops, options) => boolean | undefined;
Return true of the function expression is even, false if it is odd and undefined if it is neither.
ops
ReadonlyArray
<BoxedExpression
>
options
engine
IComputeEngine
boolean
| undefined
complexity?
FunctionDefinition.complexity?
optional complexity: number;
A number used to order arguments.
Argument with higher complexity are placed after arguments with lower complexity when ordered canonically in commutative functions.
- Additive functions: 1000-1999
- Multiplicative functions: 2000-2999
- Root and power functions: 3000-3999
- Log functions: 4000-4999
- Trigonometric functions: 5000-5999
- Hypertrigonometric functions: 6000-6999
- Special functions (factorial, Gamma, ...): 7000-7999
- Collections: 8000-8999
- Inert and styling: 9000-9999
- Logic: 10000-10999
- Relational: 11000-11999
Default: 100,000
canonical()?
FunctionDefinition.canonical()?
optional canonical: (ops, options) => BoxedExpression | null;
Return the canonical form of the expression with the arguments args
.
The arguments (args
) may not be in canonical form. If necessary, they
can be put in canonical form.
This handler should validate the type and number of the arguments.
If a required argument is missing, it should be indicated with a
["Error", "'missing"]
expression. If more arguments than expected
are present, this should be indicated with an
["Error", "'unexpected-argument'"]` error expression
If the type of an argument is not compatible, it should be indicated
with an incompatible-type
error.
["Sequence"]
expressions are not folded and need to be handled
explicitly.
If the function is associative, idempotent or an involution, this handler should account for it. Notably, if it is commutative, the arguments should be sorted in canonical order.
Values of symbols should not be substituted, unless they have
a holdUntil
attribute of "never"
.
The handler should not consider the value or any assumptions about any
of the arguments that are symbols or functions (i.e. arg.isZero
,
arg.isInteger
, etc...) since those may change over time.
The result of the handler should be a canonical expression.
If the arguments do not match, they should be replaced with an appropriate
["Error"]
expression. If the expression cannot be put in canonical form,
the handler should return null
.
ops
ReadonlyArray
<BoxedExpression
>
options
engine
IComputeEngine
BoxedExpression
| null
evaluate?
FunctionDefinition.evaluate?
optional evaluate:
| (ops, options) => BoxedExpression | undefined
| BoxedExpression;
Evaluate a function expression.
The arguments have been evaluated, except the arguments to which a
hold
applied.
It is not necessary to further simplify or evaluate the arguments.
If performing numerical calculations and options.numericalApproximation
is false
return an exact numeric value, for example return a rational
number or a square root, rather than a floating point approximation.
Use ce.number()
to create the numeric value.
When numericalApproximation
is false
, return a floating point number:
- do not reduce rational numbers to decimal (floating point approximation)
- do not reduce square roots of rational numbers
If the expression cannot be evaluated, due to the values, types, or
assumptions about its arguments, for example, return undefined
or
an ["Error"]
expression.
evaluateAsync()?
FunctionDefinition.evaluateAsync()?
optional evaluateAsync: (ops, options) => Promise<BoxedExpression | undefined>;
An option asynchronous version of evaluate
.
ops
ReadonlyArray
<BoxedExpression
>
options
EvaluateOptions
& object
Promise
<BoxedExpression
| undefined
>
evalDimension()?
FunctionDefinition.evalDimension()?
optional evalDimension: (args, options) => BoxedExpression;
Experimental
Dimensional analysis
args
ReadonlyArray
<BoxedExpression
>
options
EvaluateOptions
& object
compile()?
FunctionDefinition.compile()?
optional compile: (expr) => CompiledExpression;
Return a compiled (optimized) expression.
expr
eq()?
neq()?
collection?
FunctionDefinition.collection?
optional collection: Partial<CollectionHandlers>;
BaseDefinition
type BaseDefinition = object;
Type declaration
description?
BaseDefinition.description?
optional description: string | string[];
A short (about 1 line) description. May contain Markdown.
url?
BaseDefinition.url?
optional url: string;
A URL pointing to more information about this symbol or operator.
wikidata?
BaseDefinition.wikidata?
optional wikidata: string;
A short string representing an entry in a wikibase.
For example Q167
is the wikidata entry
for the Pi
constant.
IdentifierDefinition
type IdentifierDefinition = OneOf<[SymbolDefinition, FunctionDefinition, SemiBoxedExpression]>;
A table mapping identifiers to their definition.
Identifiers should be valid MathJSON identifiers. In addition, the following rules are recommended:
- Use only latin letters, digits and
-
:/[a-zA-Z0-9-]+/
- The first character should be a letter:
/^[a-zA-Z]/
- Functions and symbols exported from a library should start with an uppercase letter
/^[A-Z]/
IdentifierDefinitions
type IdentifierDefinitions = Readonly<{}>;
NumericFlags
type NumericFlags = object;
When used in a SymbolDefinition
or Functiondefinition
these flags
provide additional information about the value of the symbol or function.
If provided, they will override the value derived from the symbol's value.
Type declaration
sgn
NumericFlags.sgn
sgn: Sign | undefined;
even
NumericFlags.even
even: boolean | undefined;
odd
NumericFlags.odd
odd: boolean | undefined;
CollectionHandlers
type CollectionHandlers = object;
These handlers are the primitive operations that can be performed on collections.
There are two types of collections:
-
finite collections, such as lists, tuples, sets, matrices, etc... The
size()
handler of finite collections returns the number of elements -
infinite collections, such as sequences, ranges, etc... The
size()
handler of infinite collections returnsInfinity
Infinite collections are not indexable: they have noat()
handler.
Type declaration
Definitions
iterator()
CollectionHandlers.iterator()
iterator: (collection, start?, count?) => Iterator<BoxedExpression, undefined>;
Return an iterator
- start is optional and is a 1-based index.
- if start is not specified, start from index 1
- count is optional and is the number of elements to return
- if count is not specified or negative, return all the elements from start to the end
If there is a keys()
handler, there is no iterator()
handler.
collection
start?
number
count?
number
Iterator
<BoxedExpression
, undefined
>
Other
size()
CollectionHandlers.size()
size: (collection) => number;
Return the number of elements in the collection.
An empty collection has a size of 0.
collection
number
contains()
CollectionHandlers.contains()
contains: (collection, target) => boolean;
Return true
if the target
expression is in the collection, false
otherwise.
collection
target
boolean
at()
CollectionHandlers.at()
at: (collection, index) => undefined | BoxedExpression;
Return the element at the specified index.
The first element is at(1)
, the last element is at(-1)
.
If the index is <0, return the element at index size() + index + 1
.
The index can also be a string for example for maps. The set of valid keys
is returned by the keys()
handler.
If the index is invalid, return undefined
.
collection
index
number
| string
undefined
| BoxedExpression
keys()
CollectionHandlers.keys()
keys: (collection) => undefined | Iterable<string>;
If the collection can be indexed by strings, return the valid values for the index.
collection
undefined
| Iterable
<string
>
indexOf()
CollectionHandlers.indexOf()
indexOf: (collection, target, from?) => number | undefined;
Return the index of the first element that matches the target expression.
The comparison is done using the target.isEqual()
method.
If the expression is not found, return undefined
.
If the expression is found, return the index, 1-based.
Return the index of the first match.
from
is the starting index for the search. If negative, start from
the end and search backwards.
collection
target
from?
number
number
| undefined
subsetOf()
CollectionHandlers.subsetOf()
subsetOf: (collection, target, strict) => boolean;
Return true
if all the elements of target
are in expr
.
Both expr
and target
are collections.
If strict is true
, the subset must be strict, that is, expr
must
have more elements than target
.
collection
target
strict
boolean
boolean
eltsgn()
CollectionHandlers.eltsgn()
eltsgn: (collection) => Sign | undefined;
Return the sign of all the elements of the collection.
collection
Sign
| undefined
elttype()
CollectionHandlers.elttype()
elttype: (collection) => Type | undefined;
Return the widest type of all the elements in the collection
collection
Type
| undefined
BoxedBaseDefinition
Extended by
BoxedBaseDefinition.name
name: string;
BoxedBaseDefinition.wikidata?
optional wikidata: string;
BoxedBaseDefinition.description?
optional description: string | string[];
BoxedBaseDefinition.url?
optional url: string;
BoxedBaseDefinition.scope
scope: object;
The scope this definition belongs to.
This field is usually undefined, but its value is set by getDefinition()
parentScope?
scope.parentScope?
optional parentScope: { parentScope?: ...; ids?: RuntimeIdentifierDefinitions; assumptions: ExpressionMapInterface<boolean>; };
ids?
scope.ids?
optional ids: RuntimeIdentifierDefinitions;
assumptions
scope.assumptions
assumptions: ExpressionMapInterface<boolean>;
BoxedBaseDefinition.collection?
optional collection: Partial<CollectionHandlers>;
If this is the definition of a collection, the set of primitive operations that can be performed on this collection (counting the number of elements, enumerating it, etc...).
BoxedBaseDefinition.reset()
reset(): void
When the environment changes, for example the numerical precision,
call reset()
so that any cached values can be recalculated.
void
SymbolAttributes
type SymbolAttributes = object;
Type declaration
constant
SymbolAttributes.constant
constant: boolean;
If true
the value of the symbol is constant. The value or type of
symbols with this attribute set to true
cannot be changed.
If false
, the symbol is a variable.
Default: false
holdUntil
SymbolAttributes.holdUntil
holdUntil: "never" | "evaluate" | "N";
If the symbol has a value, it is held as indicated in the table below. A green checkmark indicate that the symbol is substituted.
Operation | "never" | "evaluate" | "N" |
---|---|---|---|
canonical() | (X) | ||
evaluate() | (X) | (X) | |
"N()" | (X) | (X) | (X) |
Some examples:
ImaginaryUnit
hasholdUntil: 'never'
: it is substituted during canonicalizationx
hasholdUntil: 'evaluate'
(variables)Pi
hasholdUntil: 'N'
(special numeric constant)
Default: evaluate
BoxedSymbolDefinition
Extends
BoxedSymbolDefinition.sgn?
optional sgn: Sign;
BoxedSymbolDefinition.even?
optional even: boolean;
BoxedSymbolDefinition.odd?
optional odd: boolean;
BoxedSymbolDefinition.name
name: string;
BoxedSymbolDefinition.wikidata?
optional wikidata: string;
BoxedSymbolDefinition.description?
optional description: string | string[];
BoxedSymbolDefinition.url?
optional url: string;
BoxedSymbolDefinition.scope
scope: object;
The scope this definition belongs to.
This field is usually undefined, but its value is set by getDefinition()
parentScope?
scope.parentScope?
optional parentScope: { parentScope?: ...; ids?: RuntimeIdentifierDefinitions; assumptions: ExpressionMapInterface<boolean>; };
ids?
scope.ids?
optional ids: RuntimeIdentifierDefinitions;
assumptions
scope.assumptions
assumptions: ExpressionMapInterface<boolean>;
BoxedSymbolDefinition.collection?
optional collection: Partial<CollectionHandlers>;
If this is the definition of a collection, the set of primitive operations that can be performed on this collection (counting the number of elements, enumerating it, etc...).
BoxedSymbolDefinition.constant
constant: boolean;
If true
the value of the symbol is constant. The value or type of
symbols with this attribute set to true
cannot be changed.
If false
, the symbol is a variable.
Default: false
BoxedSymbolDefinition.holdUntil
holdUntil: "never" | "N" | "evaluate";
If the symbol has a value, it is held as indicated in the table below. A green checkmark indicate that the symbol is substituted.
Operation | "never" | "evaluate" | "N" |
---|---|---|---|
canonical() | (X) | ||
evaluate() | (X) | (X) | |
"N()" | (X) | (X) | (X) |
Some examples:
ImaginaryUnit
hasholdUntil: 'never'
: it is substituted during canonicalizationx
hasholdUntil: 'evaluate'
(variables)Pi
hasholdUntil: 'N'
(special numeric constant)
Default: evaluate
BoxedSymbolDefinition.isFunction
readonly isFunction: boolean;
BoxedSymbolDefinition.isConstant
readonly isConstant: boolean;
BoxedSymbolDefinition.inferredType
inferredType: boolean;
BoxedSymbolDefinition.type
type: BoxedType;
BoxedSymbolDefinition.value
Get Signature
get value(): BoxedExpression
set value(val): void
Parameters
val
number
| BoxedExpression
void
BoxedSymbolDefinition.reset()
reset(): void
When the environment changes, for example the numerical precision,
call reset()
so that any cached values can be recalculated.
void
FunctionDefinitionFlags
type FunctionDefinitionFlags = object;
A function definition can have some flags to indicate specific properties of the function.
Type declaration
lazy
FunctionDefinitionFlags.lazy
lazy: boolean;
If true
, the arguments to this function are not automatically
evaluated. The default is false
(the arguments are evaluated).
This can be useful for example for functions that take symbolic
expressions as arguments, such as D
or Integrate
.
This is also useful for functions that take an argument that is potentially an infinite collection.
It will be up to the evaluate()
handler to evaluate the arguments as
needed. This is conveninent to pass symbolic expressions as arguments
to functions without having to explicitly use a Hold
expression.
This also applies to the canonical()
handler.
threadable
FunctionDefinitionFlags.threadable
threadable: boolean;
If true
, the function is applied element by element to lists, matrices
(["List"]
or ["Tuple"]
expressions) and equations (relational
operators).
Default: false
associative
FunctionDefinitionFlags.associative
associative: boolean;
If true
, ["f", ["f", a], b]
simplifies to ["f", a, b]
Default: false
commutative
FunctionDefinitionFlags.commutative
commutative: boolean;
If true
, ["f", a, b]
equals ["f", b, a]
. The canonical
version of the function will order the arguments.
Default: false
commutativeOrder
FunctionDefinitionFlags.commutativeOrder
commutativeOrder: (a, b) => number | undefined;
If commutative
is true
, the order of the arguments is determined by
this function.
If the function is not provided, the arguments are ordered by the default order of the arguments.
idempotent
FunctionDefinitionFlags.idempotent
idempotent: boolean;
If true
, ["f", ["f", x]]
simplifies to ["f", x]
.
Default: false
involution
FunctionDefinitionFlags.involution
involution: boolean;
If true
, ["f", ["f", x]]
simplifies to x
.
Default: false
pure
FunctionDefinitionFlags.pure
pure: boolean;
If true
, the value of this function is always the same for a given
set of arguments and it has no side effects.
An expression using this function is pure if the function and all its arguments are pure.
For example Sin
is pure, Random
isn't.
This information may be used to cache the value of expressions.
Default: true
BoxedFunctionDefinition
type BoxedFunctionDefinition = BoxedBaseDefinition & FunctionDefinitionFlags & object;
Type declaration
complexity
BoxedFunctionDefinition.complexity
complexity: number;
inferredSignature
BoxedFunctionDefinition.inferredSignature
inferredSignature: boolean;
If true, the signature was inferred from usage and may be modified as more information becomes available.
signature
BoxedFunctionDefinition.signature
signature: BoxedType;
The type of the arguments and return value of this function
type()?
BoxedFunctionDefinition.type()?
optional type: (ops, options) =>
| Type
| TypeString
| BoxedType
| undefined;
If present, this handler can be used to more precisely determine the return type based on the type of the arguments. The arguments themselves should not be evaluated, only their types should be used.
ops
ReadonlyArray
<BoxedExpression
>
options
engine
IComputeEngine
| Type
| TypeString
| BoxedType
| undefined
sgn()?
BoxedFunctionDefinition.sgn()?
optional sgn: (ops, options) => Sign | undefined;
If present, this handler can be used to determine the sign of the return value of the function, based on the sign and type of its arguments.
The arguments themselves should not be evaluated, only their types and sign should be used.
This can be used in some case for example to determine when certain simplifications are valid.
ops
ReadonlyArray
<BoxedExpression
>
options
engine
IComputeEngine
Sign
| undefined
eq()?
neq()?
canonical()?
BoxedFunctionDefinition.canonical()?
optional canonical: (ops, options) => BoxedExpression | null;
ops
ReadonlyArray
<BoxedExpression
>
options
engine
IComputeEngine
BoxedExpression
| null
evaluate()?
BoxedFunctionDefinition.evaluate()?
optional evaluate: (ops, options) => BoxedExpression | undefined;
ops
ReadonlyArray
<BoxedExpression
>
options
Partial
<EvaluateOptions
> & object
BoxedExpression
| undefined
evaluateAsync()?
BoxedFunctionDefinition.evaluateAsync()?
optional evaluateAsync: (ops, options?) => Promise<BoxedExpression | undefined>;
ops
ReadonlyArray
<BoxedExpression
>
options?
Partial
<EvaluateOptions
> & object
Promise
<BoxedExpression
| undefined
>
evalDimension()?
BoxedFunctionDefinition.evalDimension()?
optional evalDimension: (ops, options) => BoxedExpression;
ops
ReadonlyArray
<BoxedExpression
>
options
engine
IComputeEngine
compile()?
RuntimeIdentifierDefinitions
type RuntimeIdentifierDefinitions = Map<string, OneOf<[BoxedSymbolDefinition, BoxedFunctionDefinition]>>;
The entries have been validated and optimized for faster evaluation.
When a new scope is created with pushScope()
or when creating a new
engine instance, new instances of this type are created as needed.
Latex Parsing and Serialization
LatexString
type LatexString = string;
A LatexString is a regular string of LaTeX, for example:
\frac{\pi}{2}
DelimiterScale
type DelimiterScale = "normal" | "scaled" | "big" | "none";
SerializeLatexOptions
type SerializeLatexOptions = NumberSerializationFormat & object;
The LaTeX serialization options can used with the expr.toLatex()
method.
Type declaration
prettify
SerializeLatexOptions.prettify
prettify: boolean;
If true, prettify the LaTeX output.
For example, render \frac{a}{b}\frac{c}{d}
as \frac{ac}{bd}
invisibleMultiply
SerializeLatexOptions.invisibleMultiply
invisibleMultiply: LatexString;
LaTeX string used to render an invisible multiply, e.g. in '2x'.
If empty, both operands are concatenated, i.e. 2x
.
Use \cdot
to insert a \cdot
operator between them, i.e. 2 \cdot x
.
Empty by default.
invisiblePlus
SerializeLatexOptions.invisiblePlus
invisiblePlus: LatexString;
LaTeX string used to render mixed numbers e.g. '1 3/4'.
Leave it empty to join the main number and the fraction, i.e. render it
as 1\frac{3}{4}
.
Use +
to insert an explicit +
operator between them,
i.e. 1+\frac{3}{4}
Empty by default.
multiply
SerializeLatexOptions.multiply
multiply: LatexString;
LaTeX string used to render an explicit multiply operator.
For example, \times
, \cdot
, etc...
Default: \times
missingSymbol
SerializeLatexOptions.missingSymbol
missingSymbol: LatexString;
Serialize the expression ["Error", "'missing'"]
, with this LaTeX string
applyFunctionStyle()
SerializeLatexOptions.applyFunctionStyle()
applyFunctionStyle: (expr, level) => DelimiterScale;
expr
level
number
groupStyle()
rootStyle()
SerializeLatexOptions.rootStyle()
rootStyle: (expr, level) => "radical" | "quotient" | "solidus";
expr
level
number
"radical"
| "quotient"
| "solidus"
fractionStyle()
SerializeLatexOptions.fractionStyle()
fractionStyle: (expr, level) =>
| "quotient"
| "block-quotient"
| "inline-quotient"
| "inline-solidus"
| "nice-solidus"
| "reciprocal"
| "factor";
expr
level
number
| "quotient"
| "block-quotient"
| "inline-quotient"
| "inline-solidus"
| "nice-solidus"
| "reciprocal"
| "factor"
logicStyle()
SerializeLatexOptions.logicStyle()
logicStyle: (expr, level) => "word" | "boolean" | "uppercase-word" | "punctuation";
expr
level
number
"word"
| "boolean"
| "uppercase-word"
| "punctuation"
powerStyle()
SerializeLatexOptions.powerStyle()
powerStyle: (expr, level) => "root" | "solidus" | "quotient";
expr
level
number
"root"
| "solidus"
| "quotient"
numericSetStyle()
SerializeLatexOptions.numericSetStyle()
numericSetStyle: (expr, level) => "compact" | "regular" | "interval" | "set-builder";
expr
level
number
"compact"
| "regular"
| "interval"
| "set-builder"
Other
OneOf<TypesArray, Res, AllProperties>
type OneOf<TypesArray, Res, AllProperties> = TypesArray extends [infer Head, ...(infer Rem)] ? OneOf<Rem, Res | OnlyFirst<Head, AllProperties>, AllProperties> : Res;
Type Parameters
• TypesArray extends any
[]
• Res = never
• AllProperties = MergeTypes
<TypesArray
>
BoxedType
new BoxedType()
new BoxedType()
new BoxedType(type): BoxedType
type
string
| AlgebraicType
| NegationType
| CollectionType
| ListType
| SetType
| MapType
| TupleType
| FunctionSignature
| ValueType
| TypeReference
BoxedType.unknown
static unknown: BoxedType;
BoxedType.type
type: Type;
BoxedType.matches()
matches(other): boolean
other
string
| AlgebraicType
| NegationType
| CollectionType
| ListType
| SetType
| MapType
| TupleType
| FunctionSignature
| ValueType
| TypeReference
| BoxedType
boolean
BoxedType.is()
is(other): boolean
other
string
| AlgebraicType
| NegationType
| CollectionType
| ListType
| SetType
| MapType
| TupleType
| FunctionSignature
| ValueType
| TypeReference
boolean
DataTypeMap
type DataTypeMap = object;
Type declaration
float64
DataTypeMap.float64
float64: number;
float32
DataTypeMap.float32
float32: number;
int32
DataTypeMap.int32
int32: number;
uint8
DataTypeMap.uint8
uint8: number;
complex128
DataTypeMap.complex128
complex128: Complex;
complex64
DataTypeMap.complex64
complex64: Complex;
bool
DataTypeMap.bool
bool: boolean;
string
DataTypeMap.string
string: string;
expression
DataTypeMap.expression
expression: BoxedExpression;
TensorDataType
type TensorDataType = keyof DataTypeMap;
makeTensorField()
function makeTensorField<DT>(ce, dtype): TensorField<DataTypeMap[DT]>
• DT extends keyof DataTypeMap
ce
IComputeEngine
dtype
DT
TensorField
<DataTypeMap
[DT
]>
TensorField<T>
Type Parameters
• T extends
| number
| Complex
| BoxedExpression
| boolean
| string
= number
TensorField.one
readonly one: T;
TensorField.zero
readonly zero: T;
TensorField.nan
readonly nan: T;
TensorField.cast()
cast(x, dtype)
cast(x, dtype): number
x
T
dtype
"float64"
number
cast(x, dtype)
cast(x, dtype): number
x
T
dtype
"float32"
number
cast(x, dtype)
cast(x, dtype): number
x
T
dtype
"int32"
number
cast(x, dtype)
cast(x, dtype): number
x
T
dtype
"uint8"
number
cast(x, dtype)
cast(x, dtype): any
x
T
dtype
"complex128"
any
cast(x, dtype)
cast(x, dtype): any
x
T
dtype
"complex64"
any
cast(x, dtype)
cast(x, dtype): boolean
x
T
dtype
"bool"
boolean
cast(x, dtype)
cast(x, dtype): string
x
T
dtype
"string"
string
cast(x, dtype)
cast(x, dtype): BoxedExpression
x
T
dtype
"expression"
cast(x, dtype)
cast(x, dtype): number[]
x
T
[]
dtype
"float64"
number
[]
cast(x, dtype)
cast(x, dtype): number[]
x
T
[]
dtype
"float32"
number
[]
cast(x, dtype)
cast(x, dtype): number[]
x
T
[]
dtype
"int32"
number
[]
cast(x, dtype)
cast(x, dtype): number[]
x
T
[]
dtype
"uint8"
number
[]
cast(x, dtype)
cast(x, dtype): Complex[]
x
T
[]
dtype
"complex128"
Complex
[]
cast(x, dtype)
cast(x, dtype): Complex[]
x
T
[]
dtype
"complex64"
Complex
[]
cast(x, dtype)
cast(x, dtype): boolean[]
x
T
[]
dtype
"bool"
boolean
[]
cast(x, dtype)
cast(x, dtype): string[]
x
T
[]
dtype
"string"
string
[]
cast(x, dtype)
cast(x, dtype): BoxedExpression[]
x
T
[]
dtype
"expression"
cast(x, dtype)
cast(x, dtype): any
x
T
| T
[]
dtype
keyof DataTypeMap
any
TensorFieldNumber
Implements
TensorField
<number
>
new TensorFieldNumber()
new TensorFieldNumber()
new TensorFieldNumber(ce): TensorFieldNumber
ce
IComputeEngine
TensorFieldNumber.one
one: number = 1;
TensorFieldNumber.zero
zero: number = 0;
TensorFieldNumber.nan
nan: number = NaN;
TensorFieldNumber.cast()
cast(x, dtype)
cast(x, dtype): number
x
number
dtype
"float64"
number
cast(x, dtype)
cast(x, dtype): number
x
number
dtype
"float32"
number
cast(x, dtype)
cast(x, dtype): number
x
number
dtype
"int32"
number
cast(x, dtype)
cast(x, dtype): number
x
number
dtype
"uint8"
number
cast(x, dtype)
cast(x, dtype): any
x
number
dtype
"complex128"
any
cast(x, dtype)
cast(x, dtype): any
x
number
dtype
"complex64"
any
cast(x, dtype)
cast(x, dtype): boolean
x
number
dtype
"bool"
boolean
cast(x, dtype)
cast(x, dtype): string
x
number
dtype
"string"
string
cast(x, dtype)
cast(x, dtype): BoxedExpression
x
number
dtype
"expression"
cast(x, dtype)
cast(x, dtype): number[]
x
number
[]
dtype
"float64"
number
[]
cast(x, dtype)
cast(x, dtype): number[]
x
number
[]
dtype
"float32"
number
[]
cast(x, dtype)
cast(x, dtype): number[]
x
number
[]
dtype
"int32"
number
[]
cast(x, dtype)
cast(x, dtype): number[]
x
number
[]
dtype
"uint8"
number
[]
cast(x, dtype)
cast(x, dtype): Complex[]
x
number
[]
dtype
"complex128"
Complex
[]
cast(x, dtype)
cast(x, dtype): Complex[]
x
number
[]
dtype
"complex64"
Complex
[]
cast(x, dtype)
cast(x, dtype): boolean[]
x
number
[]
dtype
"bool"
boolean
[]
cast(x, dtype)
cast(x, dtype): string[]
x
number
[]
dtype
"string"
string
[]
cast(x, dtype)
cast(x, dtype): BoxedExpression[]
x
number
[]
dtype
"expression"
TensorFieldExpression
Implements
new TensorFieldExpression()
new TensorFieldExpression()
new TensorFieldExpression(ce): TensorFieldExpression
ce
IComputeEngine
TensorFieldExpression.one
one: BoxedExpression;
TensorFieldExpression.zero
zero: BoxedExpression;
TensorFieldExpression.nan
nan: BoxedExpression;
TensorFieldExpression.cast()
cast(x, dtype)
cast(x, dtype): number
x
dtype
"float64"
number
cast(x, dtype)
cast(x, dtype): number
x
dtype
"float32"
number
cast(x, dtype)
cast(x, dtype): number
x
dtype
"int32"
number
cast(x, dtype)
cast(x, dtype): number
x
dtype
"uint8"
number
cast(x, dtype)
cast(x, dtype): any
x
dtype
"complex128"
any
cast(x, dtype)
cast(x, dtype): any
x
dtype
"complex64"
any
cast(x, dtype)
cast(x, dtype): boolean
x
dtype
"bool"
boolean
cast(x, dtype)
cast(x, dtype): string
x
dtype
"string"
string
cast(x, dtype)
cast(x, dtype): BoxedExpression
x
dtype
"expression"
cast(x, dtype)
cast(x, dtype): number[]
x
dtype
"float64"
number
[]
cast(x, dtype)
cast(x, dtype): number[]
x
dtype
"float32"
number
[]
cast(x, dtype)
cast(x, dtype): number[]
x
dtype
"int32"
number
[]
cast(x, dtype)
cast(x, dtype): number[]
x
dtype
"uint8"
number
[]
cast(x, dtype)
cast(x, dtype): Complex[]
x
dtype
"complex128"
Complex
[]
cast(x, dtype)
cast(x, dtype): Complex[]
x
dtype
"complex64"
Complex
[]
cast(x, dtype)
cast(x, dtype): boolean[]
x
dtype
"bool"
boolean
[]
cast(x, dtype)
cast(x, dtype): string[]
x
dtype
"string"
string
[]
cast(x, dtype)
cast(x, dtype): BoxedExpression[]
x
dtype
"expression"
TensorFieldComplex
Implements
TensorField
<Complex
>
new TensorFieldComplex()
new TensorFieldComplex()
new TensorFieldComplex(ce): TensorFieldComplex
ce
IComputeEngine
TensorFieldComplex.one
one: Complex;
TensorFieldComplex.zero
zero: Complex;
TensorFieldComplex.nan
nan: Complex;
TensorFieldComplex.cast()
cast(x, dtype)
cast(x, dtype): number
x
Complex
dtype
"float64"
number
cast(x, dtype)
cast(x, dtype): number
x
Complex
dtype
"float32"
number
cast(x, dtype)
cast(x, dtype): number
x
Complex
dtype
"int32"
number
cast(x, dtype)
cast(x, dtype): number
x
Complex
dtype
"uint8"
number
cast(x, dtype)
cast(x, dtype): any
x
Complex
dtype
"complex128"
any
cast(x, dtype)
cast(x, dtype): any
x
Complex
dtype
"complex64"
any
cast(x, dtype)
cast(x, dtype): boolean
x
Complex
dtype
"bool"
boolean
cast(x, dtype)
cast(x, dtype): string
x
Complex
dtype
"string"
string
cast(x, dtype)
cast(x, dtype): BoxedExpression
x
Complex
dtype
"expression"
cast(x, dtype)
cast(x, dtype): number[]
x
Complex
[]
dtype
"float64"
number
[]
cast(x, dtype)
cast(x, dtype): number[]
x
Complex
[]
dtype
"float32"
number
[]
cast(x, dtype)
cast(x, dtype): number[]
x
Complex
[]
dtype
"int32"
number
[]
cast(x, dtype)
cast(x, dtype): number[]
x
Complex
[]
dtype
"uint8"
number
[]
cast(x, dtype)
cast(x, dtype): Complex[]
x
Complex
[]
dtype
"complex128"
Complex
[]
cast(x, dtype)
cast(x, dtype): Complex[]
x
Complex
[]
dtype
"complex64"
Complex
[]
cast(x, dtype)
cast(x, dtype): boolean[]
x
Complex
[]
dtype
"bool"
boolean
[]
cast(x, dtype)
cast(x, dtype): string[]
x
Complex
[]
dtype
"string"
string
[]
cast(x, dtype)
cast(x, dtype): BoxedExpression[]
x
Complex
[]
dtype
"expression"
getSupertype()
function getSupertype(t1, t2): TensorDataType
t1
keyof DataTypeMap
t2
keyof DataTypeMap
NumberFormat
type NumberFormat = object;
These options control how numbers are parsed and serialized.
Type declaration
positiveInfinity
NumberFormat.positiveInfinity
positiveInfinity: LatexString;
negativeInfinity
NumberFormat.negativeInfinity
negativeInfinity: LatexString;
notANumber
NumberFormat.notANumber
notANumber: LatexString;
imaginaryUnit
NumberFormat.imaginaryUnit
imaginaryUnit: LatexString;
decimalSeparator
NumberFormat.decimalSeparator
decimalSeparator: LatexString;
A string representing the decimal separator, the string separating the whole portion of a number from the fractional portion, i.e. the "." in "3.1415".
Some countries use a comma rather than a dot. In this case it is
recommended to use "{,}"
as the separator: the surrounding brackets
ensure there is no additional gap after the comma.
Default: "."
digitGroupSeparator
NumberFormat.digitGroupSeparator
digitGroupSeparator:
| LatexString
| [LatexString, LatexString];
A string representing the separator between groups of digits, to make numbers with many digits easier to read.
If a single string is provided, it is used to group digits in the whole and the fractional part of the number. If two strings are provided, the first is used for the whole part and the second for the fractional part.
Caution: some values may lead to unexpected results.
For example, if the digitGroupSeparator
is ,
(comma) the expression
\operatorname{Hypot}(1,2)
will parse as ["Hypot", 1.2]
rather than
["Hypot", 1, 2]
. You can however use {,}
which will avoid this issue
and display with correct spacing.
Default: "\\,"
(thin space, 3/18mu) (Resolution 7 of the 1948 CGPM)
digitGroup
NumberFormat.digitGroup
digitGroup: "lakh" | number | [number | "lakh", number];
Maximum length of digits between digit group separators.
If a single number is provided, it is used for the whole and the fractional part of the number. If two numbers are provided, the first is used for the whole part and the second for the fractional part.
If '"lakh"
' is provided, the number is grouped in groups of 2 digits,
except for the last group which has 3 digits. For example: 1,00,00,000
.
Default: 3
exponentProduct
NumberFormat.exponentProduct
exponentProduct: LatexString;
beginExponentMarker
NumberFormat.beginExponentMarker
beginExponentMarker: LatexString;
endExponentMarker
NumberFormat.endExponentMarker
endExponentMarker: LatexString;
truncationMarker
NumberFormat.truncationMarker
truncationMarker: LatexString;
repeatingDecimal
NumberFormat.repeatingDecimal
repeatingDecimal: "auto" | "vinculum" | "dots" | "parentheses" | "arc" | "none";
NumberSerializationFormat
type NumberSerializationFormat = NumberFormat & object;
Type declaration
fractionalDigits
NumberSerializationFormat.fractionalDigits
fractionalDigits: "auto" | "max" | number;
The maximum number of significant digits in serialized numbers.
"max"
: all availabe digits are serialized."auto"
: use the same precision as the compute engine.
Default: "auto"
notation
NumberSerializationFormat.notation
notation: "auto" | "engineering" | "scientific";
avoidExponentsInRange
NumberSerializationFormat.avoidExponentsInRange
avoidExponentsInRange: undefined | null | [number, number];
ExactNumericValueData
type ExactNumericValueData = object;
The value is equal to (decimal * rational * sqrt(radical)) + im * i
Type declaration
rational?
ExactNumericValueData.rational?
optional rational: Rational;
radical?
ExactNumericValueData.radical?
optional radical: number;
NumericValueData
type NumericValueData = object;
Type declaration
re?
NumericValueData.re?
optional re: Decimal | number;
im?
NumericValueData.im?
optional im: number;
NumericValueFactory()
type NumericValueFactory = (data) => NumericValue;
data
number
| Decimal
| NumericValueData
abstract
NumericValue
NumericValue.im
readonly im: number;
The imaginary part of this numeric value.
Can be negative, zero or positive.
NumericValue.isExact
Get Signature
get abstract isExact(): boolean
True if numeric value is the product of a rational and the square root of an integer.
This includes: 3/4√5, -2, √2, etc...
But it doesn't include 0.5, 3.141592, etc...
boolean
NumericValue.asExact
Get Signature
get abstract asExact(): NumericValue
If isExact()
, returns an ExactNumericValue, otherwise returns undefined.
NumericValue.re
Get Signature
get abstract re(): number
The real part of this numeric value.
Can be negative, 0 or positive.
number
NumericValue.bignumRe
Get Signature
get bignumRe(): Decimal
bignum version of .re, if available
Decimal
NumericValue.isZeroWithTolerance()
isZeroWithTolerance(_tolerance): boolean
_tolerance
number
| Decimal
boolean
NumericValue.pow()
abstract pow(n): NumericValue
n
number
| NumericValue
| {
re
: number
;
im
: number
;
}
NumericValue.valueOf()
valueOf(): string | number
Object.valueOf(): returns a primitive value
string
| number
NumericValue.[toPrimitive]()
toPrimitive: string | number
Object.toPrimitive()
hint
"string"
| "number"
| "default"
string
| number
SmallInteger
type SmallInteger = IsInteger<number>;
A SmallInteger
is an integer < 1e6
BigNum
type BigNum = Decimal;
IBigNum
IBigNum._BIGNUM_NAN
readonly _BIGNUM_NAN: Decimal;
IBigNum._BIGNUM_ZERO
readonly _BIGNUM_ZERO: Decimal;
IBigNum._BIGNUM_ONE
readonly _BIGNUM_ONE: Decimal;
IBigNum._BIGNUM_TWO
readonly _BIGNUM_TWO: Decimal;
IBigNum._BIGNUM_HALF
readonly _BIGNUM_HALF: Decimal;
IBigNum._BIGNUM_PI
readonly _BIGNUM_PI: Decimal;
IBigNum._BIGNUM_NEGATIVE_ONE
readonly _BIGNUM_NEGATIVE_ONE: Decimal;
TensorData<DT>
Type Parameters
• DT extends keyof DataTypeMap
= "float64"
TensorData.dtype
dtype: DT;
TensorData.shape
shape: number[];
TensorData.data
data: DataTypeMap[DT][];
NestedArray<T>
type NestedArray<T> = NestedArray_<T>[];
Type Parameters
• T
NestedArray_<T>
type NestedArray_<T> = T | NestedArray_<T>[];
Type Parameters
• T
abstract
AbstractTensor<DT>
Type Parameters
• DT extends keyof DataTypeMap
Implements
TensorData
<DT
>
new AbstractTensor()
new AbstractTensor()
new AbstractTensor<DT>(ce, tensorData): AbstractTensor<DT>
ce
IComputeEngine
tensorData
TensorData
<DT
>
AbstractTensor
<DT
>
AbstractTensor.field
readonly field: TensorField<DataTypeMap[DT]>;
AbstractTensor.shape
readonly shape: number[];
AbstractTensor.rank
readonly rank: number;
AbstractTensor.array
Get Signature
get array(): NestedArray<DataTypeMap[DT]>
Like expression(), but return a nested JS array instead of a BoxedExpression
NestedArray
<DataTypeMap
[DT
]>
AbstractTensor.align()
align(lhs, rhs)
static align<T1, T2>(lhs, rhs): [AbstractTensor<T1>, AbstractTensor<T1>]
Return a tuple of tensors that have the same dtype. If necessary, one of the two input tensors is upcast.
The shape of the tensors is reshaped to a compatible
shape. If the shape is not compatible, undefined
is returned.
• T1 extends keyof DataTypeMap
• T2 extends keyof DataTypeMap
lhs
AbstractTensor
<T1
>
rhs
AbstractTensor
<T2
>
[AbstractTensor
<T1
>, AbstractTensor
<T1
>]
align(lhs, rhs)
static align<T1, T2>(lhs, rhs): [AbstractTensor<T2>, AbstractTensor<T2>]
Return a tuple of tensors that have the same dtype. If necessary, one of the two input tensors is upcast.
The shape of the tensors is reshaped to a compatible
shape. If the shape is not compatible, undefined
is returned.
• T1 extends keyof DataTypeMap
• T2 extends keyof DataTypeMap
lhs
AbstractTensor
<T1
>
rhs
AbstractTensor
<T2
>
[AbstractTensor
<T2
>, AbstractTensor
<T2
>]
AbstractTensor.broadcast()
static broadcast<T>(
fn,
lhs,
rhs): AbstractTensor<T>
Apply a function to the elements of two tensors, or to a tensor and a scalar.
The tensors are aligned and broadcasted if necessary.
• T extends keyof DataTypeMap
fn
(lhs
, rhs
) => DataTypeMap
[T
]
lhs
rhs
DataTypeMap
[T
] | AbstractTensor
<T
>
AbstractTensor.at()
at(...indices): DataTypeMap[DT]
The number of indices should match the rank of the tensor.
Note: the indices are 1-based Note: the data is broadcast (wraps around) if the indices are out of bounds
LaTeX notation A\lbracki, j\rbrack
or A_{i, j}
indices
...number
[]
DataTypeMap
[DT
]
AbstractTensor.diagonal()
diagonal(axis1?, axis2?): DataTypeMap[DT][]
axis1?
number
axis2?
number
DataTypeMap
[DT
][]
AbstractTensor.trace()
trace(axis1?, axis2?): DataTypeMap[DT]
axis1?
number
axis2?
number
DataTypeMap
[DT
]
AbstractTensor.reshape()
reshape(...shape): AbstractTensor<DT>
Change the shape of the tensor
The data is reused (and shared) between the two tensors.
shape
...number
[]
AbstractTensor
<DT
>
AbstractTensor.upcast()
upcast<DT>(dtype): AbstractTensor<DT>
• DT extends keyof DataTypeMap
dtype
DT
AbstractTensor
<DT
>
AbstractTensor.transpose()
transpose()
transpose(): AbstractTensor<DT>
Transpose the first and second axis
AbstractTensor
<DT
>
transpose(axis1, axis2, fn)
transpose(
axis1,
axis2,
fn?): AbstractTensor<DT>
Transpose two axes.
axis1
number
axis2
number
fn?
(v
) => DataTypeMap
[DT
]
AbstractTensor
<DT
>
AbstractTensor.conjugateTranspose()
conjugateTranspose(axis1, axis2): AbstractTensor<DT>
axis1
number
axis2
number
AbstractTensor
<DT
>
AbstractTensor.map1()
map1(fn, scalar): AbstractTensor<DT>
fn
(lhs
, rhs
) => DataTypeMap
[DT
]
scalar
DataTypeMap
[DT
]
AbstractTensor
<DT
>
AbstractTensor.map2()
map2(fn, rhs): AbstractTensor<DT>
fn
(lhs
, rhs
) => DataTypeMap
[DT
]
rhs
AbstractTensor
<DT
>
AbstractTensor
<DT
>
AbstractTensor.add()
add(rhs): AbstractTensor<DT>
rhs
AbstractTensor
<DT
> | DataTypeMap
[DT
]
AbstractTensor
<DT
>
AbstractTensor.subtract()
subtract(rhs): AbstractTensor<DT>
rhs
AbstractTensor
<DT
> | DataTypeMap
[DT
]
AbstractTensor
<DT
>
AbstractTensor.multiply()
multiply(rhs): AbstractTensor<DT>
rhs
AbstractTensor
<DT
> | DataTypeMap
[DT
]
AbstractTensor
<DT
>
AbstractTensor.divide()
divide(rhs): AbstractTensor<DT>
rhs
AbstractTensor
<DT
> | DataTypeMap
[DT
]
AbstractTensor
<DT
>
AbstractTensor.power()
power(rhs): AbstractTensor<DT>
rhs
AbstractTensor
<DT
> | DataTypeMap
[DT
]
AbstractTensor
<DT
>
makeTensor()
function makeTensor<T>(ce, data): AbstractTensor<T>
• T extends keyof DataTypeMap
ce
IComputeEngine
data
TensorData
<T
> | {
operator
: string
;
ops
: BoxedExpression
[];
dtype
: T
;
shape
: number
[];
}
Sign
type Sign =
| "zero"
| "positive"
| "negative"
| "non-negative"
| "non-positive"
| "not-zero"
| "real-not-zero"
| "real"
| "nan"
| "positive-infinity"
| "negative-infinity"
| "complex-infinity"
| "unsigned";
CanonicalOptions
type CanonicalOptions =
| boolean
| CanonicalForm
| CanonicalForm[];
MathJSON
MathJsonAttributes
type MathJsonAttributes = object;
Type declaration
comment?
MathJsonAttributes.comment?
optional comment: string;
A human readable string to annotate this expression, since JSON does not allow comments in its encoding
documentation?
MathJsonAttributes.documentation?
optional documentation: string;
A Markdown-encoded string providing documentation about this expression.
latex?
MathJsonAttributes.latex?
optional latex: string;
A visual representation of this expression as a LaTeX string.
This can be useful to preserve non-semantic details, for example parentheses in an expression or styling attributes.
wikidata?
MathJsonAttributes.wikidata?
optional wikidata: string;
A short string referencing an entry in a wikibase.
For example:
"Q167"
is the wikidata entry
for the Pi
constant.
wikibase?
MathJsonAttributes.wikibase?
optional wikibase: string;
A base URL for the wikidata
key.
A full URL can be produced by concatenating this key with the wikidata
key. This key applies to this node and all its children.
The default value is "https://www.wikidata.org/wiki/"
openmathSymbol?
MathJsonAttributes.openmathSymbol?
optional openmathSymbol: string;
A short string indicating an entry in an OpenMath Content Dictionary.
For example: arith1/#abs
.
openmathCd?
MathJsonAttributes.openmathCd?
optional openmathCd: string;
A base URL for an OpenMath content dictionary. This key applies to this node and all its children.
The default value is "http://www.openmath.org/cd".
sourceUrl?
MathJsonAttributes.sourceUrl?
optional sourceUrl: string;
A URL to the source code from which this expression was generated.
sourceContent?
MathJsonAttributes.sourceContent?
optional sourceContent: string;
The source code from which this expression was generated.
It could be a LaTeX expression, or some other source language.
sourceOffsets?
MathJsonAttributes.sourceOffsets?
optional sourceOffsets: [number, number];
A character offset in sourceContent
or sourceUrl
from which this
expression was generated.
MathJsonIdentifier
type MathJsonIdentifier = string;
MathJsonNumber
type MathJsonNumber = object & MathJsonAttributes;
A MathJSON numeric quantity.
The num
string is made of:
- an optional
-
minus sign - a string of decimal digits
- an optional fraction part (a
.
decimal marker followed by decimal digits) - an optional repeating decimal pattern: a string of digits enclosed in parentheses
- an optional exponent part (a
e
orE
exponent marker followed by an optional-
minus sign, followed by a string of digits)
It can also consist of the value NaN
, -Infinity
and +Infinity
to
represent these respective values.
A MathJSON number may contain more digits or an exponent with a greater range than can be represented in an IEEE 64-bit floating-point.
For example:
-12.34
0.234e-56
1.(3)
123456789123456789.123(4567)e999
Type declaration
num
MathJsonNumber.num
num: "NaN" | "-Infinity" | "+Infinity" | string;
MathJsonSymbol
type MathJsonSymbol = object & MathJsonAttributes;
Type declaration
sym
MathJsonSymbol.sym
sym: MathJsonIdentifier;
MathJsonString
type MathJsonString = object & MathJsonAttributes;
Type declaration
str
MathJsonString.str
str: string;
MathJsonFunction
type MathJsonFunction = object & MathJsonAttributes;
Type declaration
fn
MathJsonFunction.fn
fn: [MathJsonIdentifier, ...Expression[]];
Expression
type Expression =
| ExpressionObject
| number
| MathJsonIdentifier
| string
| readonly [MathJsonIdentifier, ...Expression[]];
A MathJSON expression is a recursive data structure.
The leaf nodes of an expression are numbers, strings and symbols. The dictionary and function nodes can contain expressions themselves.
Other
ExpressionObject
type ExpressionObject =
| MathJsonNumber
| MathJsonString
| MathJsonSymbol
| MathJsonFunction;