Optional
canonical?: ((ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression | null)Optional
compile?: ((expr: BoxedExpression) => CompiledExpression)Return a compiled (optimized) expression.
Optional
domain?: DomainExpressionThe domain of this signature, a domain compatible with the Functions
domain).
Optional
evalDimensional analysis
Optional
evaluate?: SemiBoxedExpression | ((ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression | undefined)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, if all the arguments are exact,
return an exact expression. If any of the arguments is not exact, that is
if it is a literal decimal (non-integer) number, return an approximation.
In this case, the value may be the same as expr.N()
.
When doing an exact calculation:
holdUntil
attribute of "N"
If the expression cannot be evaluated, due to the values, domains, or
assumptions about its arguments, for example, return undefined
or
an ["Error"]
expression.
Optional
N?: ((ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression | undefined)Evaluate numerically a function expression.
The arguments args
have been simplified and evaluated, numerically
if possible, except the arguments to which a hold
apply.
The arguments may be a combination of numbers, symbolic expressions and other expressions.
Perform as many calculations as possible, and return the result.
Return undefined
if there isn't enough information to perform
the evaluation, for example one of the arguments is a symbol with
no value. If the handler returns undefined
, symbolic evaluation of
the expression will be returned instead to the caller.
Return NaN
if there is enough information to perform the
evaluation, but a literal argument is out of range or
not of the expected type.
Use the value of ce.numericMode
to determine how to perform
the numeric evaluation.
Note that regardless of the current value of ce.numericMode
, the
arguments may be boxed numbers representing machine numbers, bignum
numbers, complex numbers, rationals or big rationals.
If the numeric mode does not allow complex numbers (the
engine.numericMode
is not "complex"
or "auto"
) and the result of
the evaluation would be a complex number, return NaN
instead.
If ce.numericMode
is "bignum"
or "auto"
the evaluation should
be done using bignums.
Otherwise, ce.numericMode
is `"machine", the evaluation should be
performed using machine numbers.
You may perform any necessary computations, including approximate calculations on floating point numbers.
Optional
optOptional
params?: DomainExpression[]Optional
restOptional
result?: DomainExpression | ((ce: IComputeEngine, args: BoxedDomain[]) => BoxedDomain | null | undefined)The domain of the result of the function. Either a domain expression, or a function that returns a boxed domain.
Optional
sgn?: ((ce: IComputeEngine, args: BoxedExpression[]) => Return the sign of the function expression.
Optional
simplify?: ((ce: IComputeEngine, args: BoxedExpression[]) => BoxedExpression | undefined)Rewrite an expression into a simpler form.
The arguments are in canonical form and have been simplified.
The handler can use the values assigned to symbols and the assumptions
about symbols, for example with arg.numericValue
, arg.isInteger
or
arg.isPositive
.
Even though a symbol may not have a value, there may be some information
about it reflected for example in this.isZero
or this.isPrime
.
The handler should not perform approximate numeric calculations, such as calculations involving decimal numbers (non-integers). Making exact calculations on integers or rationals is OK.
Do not reduce constants with a holdUntil
attribute of "N"
or "evaluate"
.
This handler should not have any side-effects: do not modify
the environment of the ComputeEngine
instance, do not perform I/O,
do not do calculations that depend on random values.
If no simplification can be performed due to the values, domains or
assumptions about its arguments, for example, return undefined
.
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 domain 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 expressionIf the domain of an argument is not compatible, it should be indicated with an
incompatible-domain
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.
The handler can make transformations based on the value of the arguments that are exact and literal (i.e.
arg.numericValue !== null && arg.isExact
).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 returnnull
.