diff --git a/docs/core/configuration.md b/docs/core/configuration.md
index 95f93329c1..6d7e1a4a3f 100644
--- a/docs/core/configuration.md
+++ b/docs/core/configuration.md
@@ -1,22 +1,33 @@
# Configuration
-Math.js contains a number of configuration options.
-These options can be applied on a created mathjs instance and changed afterwards.
+Math.js contains a number of configuration options. These options can be
+applied on a created mathjs instance and changed afterwards.
```js
import { create, all } from 'mathjs'
// create a mathjs instance with configuration
const config = {
- relTol: 1e-12,
- absTol: 1e-15,
- matrix: 'Matrix',
number: 'number',
- numberFallback: 'number',
- precision: 64,
- predictable: false,
- randomSeed: null,
- legacySubset: false
+ compute: {
+ defaultRelTol: 1e-12,
+ defaultAbsTol: 1e-15,
+ numberApproximate: 'number',
+ randomSeed: null,
+ uniformType: false,
+ Matrix: {
+ defaultType: 'Matrix'
+ },
+ BigNumber: {
+ precision: 64,
+ },
+ },
+ parse: {
+ numberFallback: 'number',
+ },
+ compatibility: {
+ subset: false
+ }
}
const math = create(all, config)
@@ -24,69 +35,90 @@ const math = create(all, config)
console.log(math.config())
// change the configuration
-math.config({
- number: 'BigNumber'
-})
+math.config({ number: 'BigNumber' })
```
-The following configuration options are available:
-
-- `relTol`. The minimum relative difference used to test equality between two
- compared values. This value is used by all relational functions.
- Default value is `1e-12`.
-
-- `absTol`. The minimum absolute difference used to test equality between two
- compared values. This value is used by all relational functions.
- Default value is `1e-15`.
-
-- `matrix`. The default type of matrix output for functions.
- Available values are: `'Matrix'` (default) or `'Array'`.
- Where possible, the type of matrix output from functions is determined from
- the function input: An array as input will return an Array, a Matrix as input
- will return a Matrix. In case of no matrix as input, the type of output is
- determined by the option `matrix`. In case of mixed matrix
- inputs, a matrix will be returned always.
-
-- `number`. The type used to parse strings into a numeric value or create a new
- numeric value internally.
-
- For most functions, the type of output is determined from the input:
- a number as input will return a number as output, a BigNumber as input
- returns a BigNumber as output. But for example the functions
- `math.evaluate('2+3')`, `math.parse('2+3')`, `math.range('1:10')`,
- and `math.unit('5cm')` use the `number` configuration setting.
-
- Note that `math.sqrt(4)` will always return the number `2` regardless of
- the `number` configuration, because the numeric type can be determined from
- the input value.
-
- Available values are: `'number'` (default), `'BigNumber'`, `'bigint'`, or `'Fraction'`.
- [BigNumbers](../datatypes/bignumbers.md) have higher precision than the default numbers of JavaScript,
- [bigint](../datatypes/bigints.md) can represent large integer numbers,
- and [`Fractions`](../datatypes/fractions.md) store values in terms of a numerator and
- denominator.
-
-- `numberFallback`. When `number` is configured for example with value `'bigint'`,
- and a value cannot be represented as `bigint` like in `math.evaluate('2.3')`,
- the value will be parsed in the type configured with `numberFallback`.
- Available values: `'number'` (default) or `'BigNumber'`.
-
-- `precision`. The maximum number of significant digits for BigNumbers.
- This setting only applies to BigNumbers, not to numbers.
- Default value is `64`.
-
-- `predictable`. Predictable output type of functions. When true, output type
- depends only on the input types. When false (default), output type can vary
- depending on input values. For example `math.sqrt(-4)` returns `complex('2i')` when
- predictable is false, and returns `NaN` when true.
- Predictable output can be needed when programmatically handling the result of
- a calculation, but can be inconvenient for users when evaluating dynamic
- equations.
-
-- `randomSeed`. Set this option to seed pseudo random number generation, making it deterministic. The pseudo random number generator is reset with the seed provided each time this option is set. For example, setting it to `'a'` will cause `math.random()` to return `0.43449421599986604` upon the first call after setting the option every time. Set to `null` to seed the pseudo random number generator with a random seed. Default value is `null`.
-
-- `legacySubset`. When set to `true`, the `subset` function behaves as in earlier versions of math.js: retrieving a subset where the index size contains only one element, returns the value itself. When set to `false` (default), `subset` eliminates dimensions from the result only if the index dimension is a scalar; if the index dimension is a range, matrix, or array, the dimensions are preserved. This option is helpful for maintaining compatibility with legacy code that depends on the previous behavior.
-
+The following configuration options and sub-options are available.
+
+- {string} `number`. When the type of a numeric value is not otherwise
+ specifically determined, either in parsing or in computation, the type
+ given by this option is tried first. For example, when set to `Fraction`,
+ `math.evaluate('0.15 + 02')` will return the exact rational number
+ `math.fraction(7, 20)` and `math.sum([])` will return `math.fraction(0)`.
+ Note there are separate backup options for parsing (`parse.numberFallback`)
+ and computation (`compute.numberApproximate`) when this `number` type is
+ not appropriate, see below. The currently supported values for this
+ option are `number` (the default), `BigNumber` (which can support higher
+ precision than the built-in JavaScript number type), `Fraction`, `bigint`
+ (which can represent arbitrarily large integer numbers, but not
+ fractions or decimals).
+
+- compute:
+ - {number} `defaultAbsTol`. The minimum absolute difference used to test
+ equality between two compared values of floating-point (inexact) types.
+ This value is used by all relational functions. Default value is `1e-15`.
+
+ - {number} `defaultRelTol`. The minimum relative difference used to test
+ equality between two compared values of floating-point (inexact) types.
+ This value is used by all relational functions. Default value is `1e-12`.
+
+ - {string} `numberApproximate`. The type to use for floating-point
+ (approximate real) values as output when the type is not uniquely
+ determined by the input types (e.g., the square root of a bigint or the
+ value of a mathematical constant). Default value is `number`.
+
+ - {string|null} `randomSeed`. Set this option to seed pseudo-random number
+ generation, making it deterministic. The pseudo-random number generator is
+ reset with the seed provided each time this option is set to a new value.
+ For example, setting it to `'a'` will always cause `math.random()` to
+ return `0.43449421599986604` on its next call. Set to `null` to seed the
+ pseudo random number generator with a random seed. Default value is `null`.
+
+ - {boolean} `uniformType`. When this option is true, the output type of any
+ function depends only on the input types. When false, the output type can
+ vary depending on input values within the same type. For example,
+ `math.sqrt(-4)` returns `math.complex('2i')` when this option is false,
+ and returns `NaN` when true. Predictable output can be needed when
+ programmatically handling the result of a calculation, but can be
+ inconvenient for users when evaluating dynamic equations. Default
+ value is `false`.
+
+ - BigNumber:
+ - {number} `precision`. The maximum number of significant digits kept
+ for values of BigNumber type. Note that increasing it will not affect
+ previously computed BigNumbers, but will retain the larger number
+ of digits for future computations. Default value is `64`.
+
+ - Matrix:
+ - {string} `defaultType`. The data type used to represent a matrix output
+ by any function, when that type is not uniquely determined by the input
+ types. Whenever possible, the type of matrix output from functions is
+ determined from the function input: An array as input will return an
+ Array and a Matrix as input will return a Matrix (which is also returned
+ in case of mixed-type matrix inputs). However, some functions, such as
+ `math.identity(n)`, have no matrix parameter. In such cases, the type
+ of the output is determined by this option, including in the case of
+ the `[...]` matrix-creating operator in mathjs expressions. Currently
+ supported types are `Array` and `Matrix`, the default.
+
+- parse:
+ - {string} `numberFallback`. When the top-level `number` option is
+ configured, for example, with value `'bigint'`, and a literal value in
+ an expression, such as `'2.3'`, cannot be represented as that type,
+ the value will instead be parsed into the type specified by
+ `numberFallback`. The currently supported values are `BigNumber`,
+ `Fraction`, and `number`, the default.
+
+- compatibility:
+ - {boolean} `subset`. When set to `true`, the `subset` function behaves
+ as in earlier versions of math.js: retrieving a subset where the index
+ size contains only one element, returns the value itself. When set to
+ `false`, `subset` eliminates dimensions from the result only if the
+ index dimension is a scalar; if the index dimension is a range, matrix,
+ or array, the dimensions are preserved. This option is helpful for
+ maintaining compatibility with legacy code that depends on the
+ previous behavior. It is, however, deprecated and will be removed in some
+ future version of mathjs.
## Examples
@@ -98,7 +130,9 @@ This section shows a number of configuration examples.
import { create, all } from 'mathjs'
const config = {
- matrix: 'Array' // Choose 'Matrix' (default) or 'Array'
+ compute: {
+ Matrix: { defaultType: 'Array' } // Choose 'Matrix' (default) or 'Array'
+ }
}
const math = create(all, config)
@@ -106,17 +140,17 @@ const math = create(all, config)
math.range(0, 4) // Array [0, 1, 2, 3]
// change the configuration from Arrays to Matrices
-math.config({
- matrix: 'Matrix' // Choose 'Matrix' (default) or 'Array'
-})
+math.config({ compute: { Matrix: { defaultType: 'Matrix' } } })
// range will output a Matrix
math.range(0, 4) // Matrix [0, 1, 2, 3]
// create an instance of math.js with BigNumber configuration
const bigmath = create(all, {
- number: 'BigNumber', // Choose 'number' (default), 'BigNumber', or 'Fraction'
- precision: 32 // 64 by default, only applicable for BigNumbers
+ number: 'BigNumber'
+ compute: {
+ BigNumber: { precision: 32 } // Would be 64 by default
+ }
})
// parser will parse numbers as BigNumber now:
@@ -141,16 +175,20 @@ bigmath.evaluate('1 / 3') // BigNumber, 0.33333333333333333333333333333333
// change the configuration of math from Matrices to Arrays
math.config({
- matrix: 'Array' // Choose 'Matrix' (default) or 'Array'
+ compute: {
+ Matrix: { defaultType: 'Array' }
+ }
})
// range will output an Array
math.range(0, 4) // Array [0, 1, 2, 3]
// create a new instance of math.js with bignumber configuration
- const bigmath = math.create({
- number: 'BigNumber', // Choose 'number' (default), 'BigNumber', or 'Fraction'
- precision: 32 // 64 by default, only applicable for BigNumbers
+ const bigmath = create(all, {
+ number: 'BigNumber'
+ compute: {
+ BigNumber: { precision: 32 } // Would be 64 by default
+ }
})
// parser will parse numbers as BigNumber now:
diff --git a/docs/core/extension.md b/docs/core/extension.md
index 11652456fa..e06d8c4d29 100644
--- a/docs/core/extension.md
+++ b/docs/core/extension.md
@@ -219,7 +219,8 @@ where:
- `recreateOnConfigChange: boolean`. If true, the imported factory will be
created again when there is a change in the configuration. This is for
example used for the constants like `pi`, which is different depending
- on the configsetting `number` which can be numbers or BigNumbers.
+ on the config option `compute.numberApproximate` which can be `number`
+ or `BigNumber`.
- `formerly: string`. If present, the created function will also be
accessible on the instance under the name given by the value of
`formerly` as a (deprecated) synonym for the specified `name`. This
diff --git a/docs/datatypes/bigints.md b/docs/datatypes/bigints.md
index 4176e2296b..54d9b55317 100644
--- a/docs/datatypes/bigints.md
+++ b/docs/datatypes/bigints.md
@@ -13,21 +13,32 @@ math.bigint('42')
```
Most functions can determine the type of output from the type of input:
-a `number` as input will return a `number` as output, a `bigint` as input returns
-a `bigint` as output. Functions which cannot determine the type of output
-from the input (for example `math.evaluate`) use the default number type `number`,
-which can be configured when instantiating math.js. To configure the use of
-`bigint` instead of [numbers](numbers.md) by default, configure math.js like:
+a `number` as input will return a `number` as output, a `bigint` as input
+returns a `bigint` as output, etc. However, when parsing a numeric literal
+like `'23'` or when computing the sum of an empty list of numbers, there is
+not any already-typed input to go by. The numeric type mathjs will try in such
+situations can be configured when instantiating math.js. To use `bigint`
+instead of [numbers](numbers.md),
```js
-math.config({
- number: 'bigint'
-})
+import { create, all } from 'mathjs'
+const math = create(all)
+
+math.config({ number: 'bigint' })
// use math
math.evaluate('70000000000000000123') // bigint 70000000000000000123n
```
+You may notice, however, in this setup the parser might encounter a non-integer
+literal like `2.5`, that can't be represented by a bigint. In such cases where
+the type specified by the top-level `number` configuration option is not
+appropriate, backup types can also be configured: the parser will use the
+`parse.numberFallback` option, that can be `number`, `BigNumber`, or
+`Fraction`; and computations (and similar items, like the values of physical
+constants) will use the `compute.numberApproximate` option, that can be
+`number` or `BigNumber`.
+
## Support
All basic arithmetic functions in math.js support `bigint`. Since `bigint` can only hold integer values, it is not applicable to for example trigonometric functions. When using a `bigint` in a function that does not support it, like `sqrt`, it will convert the `bigint` into a regular `number` and then execute the function:
diff --git a/docs/datatypes/bignumbers.md b/docs/datatypes/bignumbers.md
index 974e937d5b..02e4744724 100644
--- a/docs/datatypes/bignumbers.md
+++ b/docs/datatypes/bignumbers.md
@@ -15,17 +15,27 @@ math.bignumber('2.3e+500') // BigNumber, 2.3e+500
Most functions can determine the type of output from the type of input:
a number as input will return a number as output, a BigNumber as input returns
a BigNumber as output. Functions which cannot determine the type of output
-from the input (for example `math.evaluate`) use the default number type `number`,
+from the input (for example, parsing an expression using `math.evaluate`, or
+summing an empty list of numbers) use the default number type `number`,
which can be configured when instantiating math.js. To configure the use of
BigNumbers instead of [numbers](numbers.md) by default, configure math.js like:
```js
+import { create, all } from 'mathjs'
+const math = create(all)
+
math.config({
- number: 'BigNumber', // Default type of number:
- // 'number' (default), 'BigNumber', or 'Fraction'
- precision: 64, // Number of significant digits for BigNumbers
- relTol: 1e-60,
- absTol: 1e-63
+ number: 'BigNumber' , // Default type of number: 'number' (default),
+ // 'BigNumber', 'Fraction', or 'bigint'
+ compute: {
+ BigNumber: {
+ precision: 64 // Number of significant digits for BigNumbers
+ },
+ defaultRelTol: 1e-60, // consider numbers equal if they differ by
+ // less than this fraction of the size of the
+ // larger,
+ defaultAbsTol: 1e-63 // or if their absolute difference is less than
+ } // this.
})
// use math
@@ -33,15 +43,16 @@ math.evaluate('0.1 + 0.2') // BigNumber, 0.3
```
The default precision for BigNumber is 64 digits, and can be configured with
-the option `precision`.
-
-Note that we also change the configuration of `relTol` and `absTol`
-to be close to the precision limit of our BigNumbers. `relTol` and `absTol` are used for
-example in relational and rounding functions (`equal`, `larger`, `smaller`,
-`round`, `floor`, etc) to determine when a value is nearly equal,
-see [Equality](numbers.md#equality). If we would leave `relTol` and `absTol` unchanged,
-having the default value of `1e-12` and `1e-15` respectively, we could get inaccurate and misleading
-results since we're now working with a higher precision.
+the option `compute.BigNumber.precision`.
+
+Note that we also change the configuration of `compute.defaultRelTol` and
+`compute.defaultAbsTol` to be close to the precision limit of our BigNumbers.
+These options are used for example in relational and rounding functions
+(`equal`, `larger`, `smaller`, `round`, `floor`, etc) to determine when
+one value is nearly equal another, see [Equality](numbers.md#equality).
+If we would leave `defaultRelTol` and `defaultAbsTol` unchanged, having the
+default values of `1e-12` and `1e-15` respectively, we could get inaccurate
+and misleading results since we're now working with a higher precision.
## Support
diff --git a/docs/datatypes/fractions.md b/docs/datatypes/fractions.md
index 7edd61b616..aa2460633f 100644
--- a/docs/datatypes/fractions.md
+++ b/docs/datatypes/fractions.md
@@ -1,10 +1,12 @@
# Fractions
For calculations with fractions, math.js supports a `Fraction` data type.
-Fraction support is powered by [fraction.js](https://github.com/rawify/Fraction.js).
+Fraction support is powered by
+[fraction.js](https://github.com/rawify/Fraction.js).
Unlike [numbers](numbers.md) and [BigNumbers](./bignumbers.md), fractions can
-store numbers with infinitely repeating decimals, for example `1/3 = 0.3333333...`,
-which can be represented as `0.(3)`, or `2/7` which can be represented as `0.(285714)`.
+store numbers with infinitely repeating decimals, for example
+`1/3 = 0.3333333...`, which can be represented as `0.(3)`, or `2/7`, which can
+be represented as `0.(285714)`.
## Usage
@@ -25,24 +27,29 @@ math.multiply(math.fraction('1/4'), math.fraction('1/2')) // Fraction, 1/8
```
Note that not all functions support fractions. For example trigonometric
-functions doesn't support fractions. When not supported, the functions
+functions don't support fractions. When not supported, the functions
will convert the input to numbers and return a number as result.
Most functions will determine the type of output from the type of input:
a number as input will return a number as output, a Fraction as input returns
-a Fraction as output. Functions which cannot determine the type of output
-from the input (for example `math.evaluate`) use the default number type `number`,
-which can be configured when instantiating math.js. To configure the use of
-fractions instead of [numbers](numbers.md) by default, configure math.js like:
+a Fraction as output, etc. However, when parsing a numeric literal
+like `'23'` or when computing the sum of an empty list of numbers, there is
+not any already-typed input to go by. The numeric type mathjs will try in such
+situations can be configured when instantiating math.js. To use fractions
+instead of [numbers](numbers.md) by default, configure math.js like:
```js
-// Configure the default type of number: 'number' (default), 'BigNumber', or 'Fraction'
-math.config({
- number: 'Fraction'
-})
+import { create, all } from 'mathjs'
+const math = create(all)
+
+// Configure the default type of number:
+// 'number' (default), 'bigint', 'BigNumber', or 'Fraction'
+math.config({ number: 'Fraction' })
// use the expression parser
-math.evaluate('0.32 + 0.08') // Fraction, 2/5
+math.evaluate('0.32 + 0.08') // Fraction 2/5
+// Add up an empty list
+math.sum([]) // Fraction 0
```
## Support
diff --git a/docs/datatypes/matrices.md b/docs/datatypes/matrices.md
index 01178f7413..a85b979799 100644
--- a/docs/datatypes/matrices.md
+++ b/docs/datatypes/matrices.md
@@ -21,13 +21,15 @@ In most cases, the type of matrix output from functions is determined by the
function input: An `Array` as input will return an `Array`, a `Matrix` as input
will return a `Matrix`. In case of mixed input, a `Matrix` is returned.
For functions where the type of output cannot be determined from the
-input, the output is determined by the configuration option `matrix`,
-which can be a string `'Matrix'` (default) or `'Array'`. The function `size` is
-an exception: `size` always returns an `Array` containing numbers. Having a
-consistent output type in this case is most practical since the size is often
-used in JavaScript loops where the code can only use a flat Array with numbers.
-This also makes the function `size` consistent with the matrix method
-`matrix.size()`.
+input (such as `math.identity(n)` that only takes an integer parameter),
+the output type is determined by the configuration option
+`compute.Matrix.defaultType`, which can be a string `'Matrix'` (default) or
+`'Array'`. The function `size()`, however, does not depend on this
+`defaultType` option: `size` always returns an `Array` containing numbers.
+Having a consistent output type in this case is most practical since the
+size is often used in JavaScript loops where the code can only use a flat
+Array with numbers. This uniform return type also makes the function `size`
+consistent with the matrix method `matrix.size()`.
```js
// create an array and a matrix
@@ -43,7 +45,7 @@ math.add(array, matrix) // Matrix, [[9, 1], [-3, 6]]
math.multiply(array, matrix) // Matrix, [[14, 2], [-13, 8]]
// create a matrix. Type of output of function ones is determined by the
-// configuration option `matrix`
+// configuration option `compute.Matrix.defaultType`
math.ones(2, 3) // Matrix, [[1, 1, 1], [1, 1, 1]]
```
@@ -105,7 +107,7 @@ The functions `ones`, `zeros`, and `identity` also accept a single array
or matrix containing the dimensions for the matrix. When the input is an Array,
the functions will output an Array. When the input is a Matrix, the output will
be a Matrix. Note that in case of numbers as arguments, the output is
-determined by the option `matrix` as discussed in section
+determined by the option `compute.Matrix.defaultType` as discussed in section
[Arrays and matrices](#arrays-and-matrices).
```js
@@ -182,8 +184,8 @@ Math.js uses geometric dimensions:
- A matrix is two or multidimensional.
The size of a matrix can be calculated with the function `size`. This function
-returns an `Array`, giving the length of its input (`Matrix` or `Array`) in
-each dimension. You can also call `size()` as a method on a Matrix.
+returns an `Array` of numbers, giving the length of its input (`Matrix` or
+`Array`) in each dimension. You can also call `size()` as a method on a Matrix.
```js
// get the size of a scalar
@@ -206,7 +208,7 @@ b.size() // Array, [2, 3]
// get the size of a multi-dimensional array
const c = [[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]]
-math.size(c) // Array, [2, 2, 3]
+math.size(c) // Array [2, 2, 3]
```
Note that the dimensions themselves do not have a meaning attached.
@@ -295,7 +297,7 @@ math.subset(m, math.index(1, [2])) // [22] (row dimension eliminated, co
math.subset(m, math.index([1], 2)) // [22] (column dimension eliminated, row dimension preserved as array)
math.subset(m, math.index([1], [2])) // [[22]] (both dimensions preserved as arrays)
-math.config({legacySubset: true}) // switch to legacy behavior
+math.config({ compatibility: { subset: true } }) // switch to legacy behavior
math.subset(m, math.index(1, 2)) // 22
math.subset(m, math.index(1, [2])) // 22
math.subset(m, math.index([1], 2)) // 22
@@ -342,10 +344,11 @@ e.subset(math.index(1, 2), 5) // Matrix, [[0, 0, 0], [0, 0, 5]]
With the release of math.js v15, the behavior of `subset` when indexing matrices and arrays has changed. If your code relies on the previous behavior (where indexing with an array or matrix of size 1 would always return the value itself), you may need to update your code or enable legacy mode.
-To maintain the old indexing behavior without need for any code changes, use the configuration option `legacySubset`:
+To maintain the old indexing behavior without need for any code changes, use
+the deprecated configuration compatibility option `subset`:
```js
-math.config({ legacySubset: true })
+math.config({ compatibility: { subset: true } })
```
To migrate your code, you'll have to change all matrix indexes from the old index notation to the new index notation. Basically: scalar indexes have to be wrapped in array brackets if you want an array as output. Here some examples:
diff --git a/docs/datatypes/numbers.md b/docs/datatypes/numbers.md
index f082d5cd6f..6374a075c3 100644
--- a/docs/datatypes/numbers.md
+++ b/docs/datatypes/numbers.md
@@ -13,15 +13,20 @@ Math.js supports three types of numbers:
Most functions can determine the type of output from the type of input:
a number as input will return a number as output, a BigNumber as input returns
-a BigNumber as output. Functions which cannot determine the type of output
-from the input (for example `math.evaluate`) use the default number type, which
-can be configured when instantiating math.js:
+a BigNumber as output, and so on. However, when parsing a numeric literal
+like `'23'` or when computing the sum of an empty list of numbers, there is
+not any already-typed input to go by. The numeric type mathjs will try in such
+situations can be configured when instantiating math.js, by the top-level
+configuration option `number`. Although its default value is the string
+`'number'` meaning to use the built-in JavaScript number type, here's how
+you would explicitly configure it that way if it were necessary:
```js
-math.config({
- number: 'number' // Default type of number:
- // 'number' (default), 'BigNumber', or 'Fraction'
-})
+import { create, all } from 'mathjs'
+const math = create(all)
+
+math.config({ number: 'number' }) // Default type of number:
+ // 'number' (default), 'bigint', 'BigNumber', or 'Fraction'
```
## Round-off errors
@@ -73,20 +78,26 @@ false, as the addition `0.1 + 0.2` introduces a round-off error and does not
return exactly `0.3`.
To solve this problem, the relational functions of math.js check whether the
-relative and absolute differences between the compared values is smaller than the configured
-option `relTol` and `absTol`. In pseudo code (without exceptions for 0, Infinity and NaN):
+relative and absolute differences between the compared values is smaller than
+the configuration options `compute.defaultRelTol` and `compute.defaultAbsTol`.
+In pseudo code (without exceptions for 0, Infinity and NaN):
abs(a-b) <= max(relTol * max(abs(a), abs(b)), absTol)
where:
- - `relTol` is the relative tolerance between x and y and `absTol` the absolute tolerance. Relative tolerance and absolute tolerance are configurable and are `1e-12` and `1e-15` respectively by default. See [Configuration](../core/configuration.md).
- - `DBL_EPSILON` is the minimum positive floating point number such that
- `1.0 + DBL_EPSILON !== 1.0`. This is a constant with a value of approximately
- `2.2204460492503130808472633361816e-16`.
+ - `relTol` is the relative tolerance between x and y and `absTol` the absolute
+ tolerance. Relative tolerance and absolute tolerance are configurable and
+ are `1e-12` and `1e-15`, respectively, by default. See
+ [Configuration](../core/configuration.md).
-Note that the relational functions cannot be used to compare small values
-(`< 2.22e-16`). These values are all considered equal to zero.
+Note that values of the built-in JavaScript number type, based on the IEEE
+64-bit floating-point standard, have their own approximation properties which
+occur when they cannot keep sufficiently many significant digits to represent
+a result exactly. For example, `DBL_EPSILON` is the minimum positive number
+value such that `1.0 + DBL_EPSILON` is distinct from the number `1.0` itself.
+`DBL_EPSILON` is a constant with a value of approximately
+`2.220446049250313e-16`.
Examples:
@@ -95,9 +106,18 @@ Examples:
console.log(0.1 + 0.2 === 0.3) // false
console.log(math.equal(0.1 + 0.2, 0.3)) // true
-// small values (< 2.22e-16) cannot be compared
+// small values create difficulties with comparison, under the default
+// configuration:
console.log(3e-20 === 3.1e-20) // false
-console.log(math.equal(3e-20, 3.1e-20)) // true
+console.log(math.equal(3e-20, 3.1e-20)) // true, because the difference
+// 1e-21 is smaller than the default absolute tolerance.
+
+// If you will be working with many very small values and want to
+// rely primarily on relative difference for testing equality, configure
+// the absolute tolerance much smaller:
+import { create, all } from 'mathjs'
+const smallmath = create(all, { compute: { defaultAbsTol: 1e-64 } })
+console.log(smallmath.equal(3e-20, 3.1e-20)) // false
```
The available relational functions are: `compare`, `equal`, `larger`,
diff --git a/docs/datatypes/units.md b/docs/datatypes/units.md
index 3a1a39513b..1ae8fad9c8 100644
--- a/docs/datatypes/units.md
+++ b/docs/datatypes/units.md
@@ -215,14 +215,14 @@ math.bignumber(math.unit(10, 'inch')).toNumeric('cm') // BigNumber 25.4
math.unit(math.bignumber(10), 'inch').toNumeric('cm') // BigNumber 25.4
```
-When using the expression parser, it is possible to configure numeric values to be parsed as `Fraction` or `BigNumber`:
+When using the expression parser, it is possible to configure numeric values
+to be parsed as other types:
```js
math.config({ number: 'Fraction' })
math.evaluate('10 inch').toNumeric('cm') // Fraction 127/5
```
-
## API
A `Unit` object contains the following functions:
diff --git a/docs/expressions/syntax.md b/docs/expressions/syntax.md
index 2b8b39d8cc..3461d775fc 100644
--- a/docs/expressions/syntax.md
+++ b/docs/expressions/syntax.md
@@ -521,20 +521,42 @@ math.evaluate('bignumber(0.1) + bignumber(0.2)') // BigNumber, 0.3
```
The default number type of the expression parser can be changed at instantiation
-of math.js. The expression parser parses numbers as BigNumber by default:
+of math.js. To make the expression parser interpret numeric literals as
+BigNumber values:
```js
-// Configure the type of number: 'number' (default), 'BigNumber', or 'Fraction'
-math.config({number: 'BigNumber'})
+import { create, all } from 'mathjs'
+const math = create(all)
-// all numbers are parsed as BigNumber
-math.evaluate('0.1 + 0.2') // BigNumber, 0.3
+// Configure the type of number.
+// Supported values are 'number' (default), 'bigint', 'BigNumber', or 'Fraction'
+math.config({ number: 'BigNumber' })
+
+// all numbers are now parsed as BigNumber
+math.evaluate('0.1 + 0.2') // BigNumber 0.3
+```
+
+Note however that some of the allowed `number` types cannot represent all
+numeric literals that might be encountered in an expression. For example, there
+is no `bigint` representation of `'2.3'`. To handle such cases, mathjs has an
+additional configuration parameter, `parse.numberFallback`. Continuing the
+above example:
+
+```
+math.config({
+ number: 'bigint',
+ parse: { numberFallback: 'Fraction' }
+})
+
+// Now intebers are parsed as bigint, and decimals as exact Fractions:
+math.evaluate('1 + 2') // bigint 3
+math.evaluate('0.1 + 0.2') // Fraction 3/10
```
BigNumbers can be converted to numbers and vice versa using the functions
`number` and `bignumber`. When converting a BigNumber to a Number, the high
-precision of the BigNumber will be lost. When a BigNumber is too large to be represented
-as Number, it will be initialized as `Infinity`.
+precision of the BigNumber will be lost. When a BigNumber is too large to be
+represented as Number, it will convert to `Infinity`.
### Complex numbers
@@ -713,13 +735,16 @@ parser.evaluate('c[end - 1 : -1 : 2]') // Matrix, [8, 7, 6]
With mathjs v15, matrix indexing has changed to be more consistent and predictable. In v14, using a scalar index would sometimes reduce the dimensionality of the result. In v15, if you want to preserve dimensions, use array, matrix, or range indices. If you want a scalar value, use scalar indices.
-To maintain the old indexing behavior without need for any code changes, use the configuration option `legacySubset`:
+To maintain the old indexing behavior without need for any code changes, use
+the configuration compatibility option `subset`:
```js
-math.config({ legacySubset: true })
+math.config({ compatibility: { subset: true } })
```
-To migrate your code, you'll have to change all matrix indexes from the old index notation to the new index notation. Basically: scalar indexes have to be wrapped in array brackets if you want an array as output. Here some examples:
+To migrate your code, you'll have to change all matrix indexes from the old
+index notation to the new index notation. Basically: scalar indexes have to
+be wrapped in array brackets if you want an array as output. Here some examples:
```js
parser = math.parser()
diff --git a/docs/reference/classes/unit.md b/docs/reference/classes/unit.md
index c3f88fed6a..5696c1972d 100644
--- a/docs/reference/classes/unit.md
+++ b/docs/reference/classes/unit.md
@@ -218,8 +218,8 @@ Converts a unit to the most appropriate display unit with optional unitList and
### Unit.parse(str) ⇒ Unit
-Parse a string into a unit. The value of the unit is parsed as number,
-BigNumber, or Fraction depending on the math.js config setting `number`.
+Parse a string into a unit. The value of the unit is parsed as the
+type given by the math.js config setting `number`.
Throws an exception if the provided string does not contain a valid unit or
cannot be parsed.
diff --git a/src/constants.js b/src/constants.js
index 90b279d50a..e17397c0e1 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -12,102 +12,76 @@ export const createTrue = /* #__PURE__ */ factory('true', [], () => true)
export const createFalse = /* #__PURE__ */ factory('false', [], () => false)
export const createNull = /* #__PURE__ */ factory('null', [], () => null)
-export const createInfinity = /* #__PURE__ */ recreateFactory(
- 'Infinity',
- ['config', '?BigNumber'],
- ({ config, BigNumber }) => (config.number === 'BigNumber')
- ? new BigNumber(Infinity)
- : Infinity
-)
-
-export const createNaN = /* #__PURE__ */ recreateFactory(
- 'NaN',
- ['config', '?BigNumber'],
- ({ config, BigNumber }) => (config.number === 'BigNumber')
- ? new BigNumber(NaN)
- : NaN
-)
-
-export const createPi = /* #__PURE__ */ recreateFactory(
- 'pi',
- ['config', '?BigNumber'],
- ({ config, BigNumber }) => (config.number === 'BigNumber')
- ? createBigNumberPi(BigNumber)
- : pi
-)
-
-export const createTau = /* #__PURE__ */ recreateFactory(
- 'tau',
- ['config', '?BigNumber'],
- ({ config, BigNumber }) => (config.number === 'BigNumber')
- ? createBigNumberTau(BigNumber)
- : tau
-)
-
-export const createE = /* #__PURE__ */ recreateFactory(
- 'e',
- ['config', '?BigNumber'],
- ({ config, BigNumber }) => (config.number === 'BigNumber')
- ? createBigNumberE(BigNumber)
- : e
-)
+function createConstant (name, generators) {
+ return recreateFactory(name, ['config', '?BigNumber'], (dep) => {
+ const constType = dep.config.compute.numberApproximate
+ return generators[constType](dep[constType])
+ })
+}
-// golden ratio, (1+sqrt(5))/2
-export const createPhi = /* #__PURE__ */ recreateFactory(
- 'phi',
- ['config', '?BigNumber'],
- ({ config, BigNumber }) => (config.number === 'BigNumber')
- ? createBigNumberPhi(BigNumber)
- : phi
-)
+export const createInfinity = /* #__PURE__ */ createConstant('Infinity', {
+ number: () => Infinity,
+ BigNumber: Big => new Big(Infinity)
+})
-export const createLN2 = /* #__PURE__ */ recreateFactory(
- 'LN2',
- ['config', '?BigNumber'],
- ({ config, BigNumber }) => (config.number === 'BigNumber')
- ? new BigNumber(2).ln()
- : Math.LN2
-)
+export const createNaN = /* #__PURE__ */ createConstant('NaN', {
+ number: () => NaN,
+ BigNumber: Big => new Big(NaN)
+})
-export const createLN10 = /* #__PURE__ */ recreateFactory(
- 'LN10',
- ['config', '?BigNumber'],
- ({ config, BigNumber }) => (config.number === 'BigNumber')
- ? new BigNumber(10).ln()
- : Math.LN10
-)
+export const createPi = /* #__PURE__ */ createConstant('pi', {
+ number: () => pi,
+ BigNumber: Big => createBigNumberPi(Big)
+})
-export const createLOG2E = /* #__PURE__ */ recreateFactory(
- 'LOG2E',
- ['config', '?BigNumber'],
- ({ config, BigNumber }) => (config.number === 'BigNumber')
- ? new BigNumber(1).div(new BigNumber(2).ln())
- : Math.LOG2E
-)
+export const createTau = /* #__PURE__ */ createConstant('tau', {
+ number: () => tau,
+ BigNumber: Big => createBigNumberTau(Big)
+})
-export const createLOG10E = /* #__PURE__ */ recreateFactory(
- 'LOG10E',
- ['config', '?BigNumber'],
- ({ config, BigNumber }) => (config.number === 'BigNumber')
- ? new BigNumber(1).div(new BigNumber(10).ln())
- : Math.LOG10E
-)
+export const createE = /* #__PURE__ */ createConstant('e', {
+ number: () => e,
+ BigNumber: Big => createBigNumberE(Big)
+})
-export const createSQRT1_2 = /* #__PURE__ */ recreateFactory( // eslint-disable-line camelcase
+// golden ratio, (1+sqrt(5))/2
+export const createPhi = /* #__PURE__ */ createConstant('phi', {
+ number: () => phi,
+ BigNumber: Big => createBigNumberPhi(Big)
+})
+
+export const createLN2 = /* #__PURE__ */ createConstant('LN2', {
+ number: () => Math.LN2,
+ BigNumber: Big => new Big(2).ln()
+})
+
+export const createLN10 = /* #__PURE__ */ createConstant('LN10', {
+ number: () => Math.LN10,
+ BigNumber: Big => new Big(10).ln()
+})
+
+export const createLOG2E = /* #__PURE__ */ createConstant('LOG2E', {
+ number: () => Math.LOG2E,
+ BigNumber: Big => new Big(1).div(new Big(2).ln())
+})
+
+export const createLOG10E = /* #__PURE__ */ createConstant('LOG10E', {
+ number: () => Math.LOG10E,
+ BigNumber: Big => new Big(1).div(new Big(10).ln())
+})
+
+export const createSQRT1_2 = /* #__PURE__ */ createConstant( // eslint-disable-line camelcase
'SQRT1_2',
- ['config', '?BigNumber'],
- ({ config, BigNumber }) => (config.number === 'BigNumber')
- ? new BigNumber('0.5').sqrt()
- : Math.SQRT1_2
+ {
+ number: () => Math.SQRT1_2,
+ BigNumber: Big => new Big('0.5').sqrt()
+ }
)
-export const createSQRT2 = /* #__PURE__ */ recreateFactory(
- 'SQRT2',
- ['config', '?BigNumber'],
- ({ config, BigNumber }) => (config.number === 'BigNumber')
- ? new BigNumber(2).sqrt()
- : Math.SQRT2
-)
+export const createSQRT2 = /* #__PURE__ */ createConstant('SQRT2', {
+ number: () => Math.SQRT2,
+ BigNumber: Big => new Big(2).sqrt()
+})
export const createI = /* #__PURE__ */ recreateFactory(
'i',
diff --git a/src/core/config.js b/src/core/config.js
index f777ae6181..5c70a734f0 100644
--- a/src/core/config.js
+++ b/src/core/config.js
@@ -1,37 +1,93 @@
+import { isNumber } from '../utils/is.js'
+
export const DEFAULT_CONFIG = {
- // minimum relative difference between two compared values,
- // used by all comparison functions
- relTol: 1e-12,
+ compatibility: {
+ // legacy behavior for matrix subset. When true, the subset function
+ // returns a matrix or array with the same size as the index (except for
+ // scalars). When false, it returns a matrix or array with a size
+ // depending on the type of index.
+ subset: false
+ },
- // minimum absolute difference between two compared values,
- // used by all comparison functions
- absTol: 1e-15,
+ compute: {
+ // minimum absolute difference between two compared values of
+ // floating-point (inexact) types, used by all comparison functions
+ defaultAbsTol: 1e-15,
- // type of default matrix output. Choose 'matrix' (default) or 'array'
- matrix: 'Matrix',
+ // minimum relative difference between two compared values of
+ // floating-point (inexact) types, used by all comparison functions
+ defaultRelTol: 1e-12,
- // type of default number output. Choose 'number' (default) 'BigNumber', 'bigint', or 'Fraction'
- number: 'number',
+ // type used for floating-point/approximate real values as output
+ // when the type is not uniquely determined by the input types (e.g.,
+ // square root of a bigint or the value of a mathematical constant)
+ numberApproximate: 'number',
+
+ // random seed for seeded pseudo random number generation
+ // null = randomly seed
+ randomSeed: null,
+
+ // Is the output type of each function uniform? When true, output type
+ // depends only on the input types. When false (default), output type
+ // can vary depending on input values within a type. For example,
+ // `math.sqrt(-4)` returns `math.complex('2i')` when
+ // uniformType is false, and returns `NaN` when true.
+ uniformType: false,
- // type of fallback used for config { number: 'bigint' } when a value cannot be represented
- // in the configured numeric type. Choose 'number' (default) or 'BigNumber'.
- numberFallback: 'number',
+ BigNumber: {
+ // Number of significant digits to keep
+ precision: 64
+ },
- // number of significant digits in BigNumbers
- precision: 64,
+ Matrix: {
+ // default representation of Matrices to use
+ defaultType: 'Matrix'
+ }
+ },
- // predictable output type of functions. When true, output type depends only
- // on the input types. When false (default), output type can vary depending
- // on input values. For example `math.sqrt(-4)` returns `complex('2i')` when
- // predictable is false, and returns `NaN` when true.
- predictable: false,
+ // The overall default number type, to be used in parsing and computation,
+ // when the type for numbers is not otherwise determined and this type
+ // is suitable for the representation needed. There are alternate type
+ // specification for compute and parse when this type is not suitable.
+ number: 'number',
+
+ parse: {
+ // In case a given textual representation cannot be converted to the
+ // selected type specified by the general top-level `number` option,
+ // what type should be tried as an alternative?
+ numberFallback: 'number'
+ }
+}
- // random seed for seeded pseudo random number generation
- // null = randomly seed
- randomSeed: null,
+function isStringNumberObjectOrNull (s) {
+ return s === null | ['string', 'number', 'object'].includes(typeof s)
+}
- // legacy behavior for matrix subset. When true, the subset function
- // returns a matrix or array with the same size as the index (except for scalars).
- // When false, it returns a matrix or array with a size depending on the type of index.
- legacySubset: false
+// For each configuration option, either an array of allowed values or
+// a boolean predicate specifying whether an option value is allowed.
+export const ALLOWED_CONFIG = {
+ compatibility: {
+ subset: [true, false]
+ },
+ compute: {
+ defaultAbsTol: isNumber,
+ defaultRelTol: isNumber,
+ // we could conceptually allow Fraction for the following
+ // numberApproximate option, but that would involve rational approximation
+ // algorithms that we do not currently have implemented (see, for example,
+ // https://www.ams.org/journals/mcom/1995-64-211/S0025-5718-1995-1297479-9/S0025-5718-1995-1297479-9.pdf
+ numberApproximate: ['number', 'BigNumber'],
+ randomSeed: isStringNumberObjectOrNull,
+ uniformType: [true, false],
+ BigNumber: {
+ precision: Number.isInteger
+ },
+ Matrix: {
+ defaultType: ['Array', 'Matrix']
+ }
+ },
+ number: ['bigint', 'BigNumber', 'Fraction', 'number'],
+ parse: {
+ numberFallback: ['BigNumber', 'Fraction', 'number']
+ }
}
diff --git a/src/core/create.js b/src/core/create.js
index bb3a7bbe04..99fd896704 100644
--- a/src/core/create.js
+++ b/src/core/create.js
@@ -48,7 +48,7 @@ import {
isUndefined,
isUnit
} from '../utils/is.js'
-import { deepFlatten, isLegacyFactory } from '../utils/object.js'
+import { clone, deepFlatten, isLegacyFactory } from '../utils/object.js'
import * as emitter from './../utils/emitter.js'
import { DEFAULT_CONFIG } from './config.js'
import { configFactory } from './function/config.js'
@@ -63,41 +63,19 @@ import { importFactory } from './function/import.js'
* const config = { number: 'BigNumber' }
* const mathjs2 = create(all, config)
*
- * @param {Object} [factories] An object with factory functions
- * The object can contain nested objects,
- * all nested objects will be flattened.
- * @param {Object} [config] Available options:
- * {number} relTol
- * Minimum relative difference between two
- * compared values, used by all comparison functions.
- * {number} absTol
- * Minimum absolute difference between two
- * compared values, used by all comparison functions.
- * {string} matrix
- * A string 'Matrix' (default) or 'Array'.
- * {string} number
- * A string 'number' (default), 'BigNumber', or 'Fraction'
- * {number} precision
- * The number of significant digits for BigNumbers.
- * Not applicable for Numbers.
- * {boolean} predictable
- * Predictable output type of functions. When true,
- * output type depends only on the input types. When
- * false (default), output type can vary depending
- * on input values. For example `math.sqrt(-4)`
- * returns `complex('2i')` when predictable is false, and
- * returns `NaN` when true.
- * {string} randomSeed
- * Random seed for seeded pseudo random number generator.
- * Set to null to randomly seed.
- * @returns {Object} Returns a bare-bone math.js instance containing
- * functions:
- * - `import` to add new functions
- * - `config` to change configuration
- * - `on`, `off`, `once`, `emit` for events
+ * @param {Object} [factories]
+ * An object with factory functions. The object can contain nested objects,
+ * and all nested objects will be flattened.
+ * @param {Object} [config]
+ * See the `config()` documentation for the list of available options.
+ * @returns {Object}
+ * Returns a bare-bone math.js instance containing functions:
+ * - `import` to add new functions
+ * - `config` to change configuration
+ * - `on`, `off`, `once`, `emit` for events
*/
export function create (factories, config) {
- const configInternal = Object.assign({}, DEFAULT_CONFIG, config)
+ const configInternal = clone(DEFAULT_CONFIG)
// simple test for ES5 support
if (typeof Object.create !== 'function') {
@@ -157,6 +135,7 @@ export function create (factories, config) {
// load config function and apply provided config
math.config = configFactory(configInternal, math.emit)
+ math.config(config)
math.expression = {
transform: {},
diff --git a/src/core/function/config.js b/src/core/function/config.js
index 5be65558f6..2d0523478f 100644
--- a/src/core/function/config.js
+++ b/src/core/function/config.js
@@ -1,8 +1,25 @@
import { clone, deepExtend } from '../../utils/object.js'
-import { DEFAULT_CONFIG } from '../config.js'
+import { DEFAULT_CONFIG, ALLOWED_CONFIG } from '../config.js'
-export const MATRIX_OPTIONS = ['Matrix', 'Array'] // valid values for option matrix
-export const NUMBER_OPTIONS = ['number', 'BigNumber', 'bigint', 'Fraction'] // valid values for option number
+// object of options that are deprecated or discontinued, possibly with
+// a synonymous current option.
+const REMAP_CONFIG = {
+ epsilon: [
+ 'discontinued',
+ 'compute.defaultRelTol and/or compute.defaultAbsTol'
+ ],
+ relTol: ['deprecated', ['compute', 'defaultRelTol']],
+ absTol: ['deprecated', ['compute', 'defaultAbsTol']],
+ matrix: ['deprecated', ['compute', 'Matrix', 'defaultType']],
+ numberFallback: ['deprecated', ['parse', 'numberFallback']],
+ precision: ['deprecated', ['compute', 'BigNumber', 'precision']],
+ predictable: ['deprecated', ['compute', 'uniformType']],
+ randomSeed: ['deprecated', ['compute', 'randomSeed']],
+ legacySubset: ['deprecated', ['compatibility', 'subset']],
+ compatibility: {
+ subset: 'deprecated'
+ }
+}
export function configFactory (config, emit) {
/**
@@ -13,7 +30,16 @@ export function configFactory (config, emit) {
*
* Syntax:
*
- * math.config(config: Object): Object
+ * math.config()
+ * math.config(config)
+ *
+ * Where:
+ *
+ * The argument `config` is a plain object specifying new configuration
+ * options that this instance should use. Available options:
+ *
+ * The `config` function returns an object reporting the values of all
+ * configuration options after the new ones, if any, have been set.
*
* Examples:
*
@@ -27,74 +53,46 @@ export function configFactory (config, emit) {
* math.config({number: 'Fraction'})
* math.evaluate('0.4') // outputs Fraction 2/5
*
- * @param {Object} [options] Available options:
- * {number} relTol
- * Minimum relative difference between two
- * compared values, used by all comparison functions.
- * {number} absTol
- * Minimum absolute difference between two
- * compared values, used by all comparison functions.
- * {string} matrix
- * A string 'Matrix' (default) or 'Array'.
- * {string} number
- * A string 'number' (default), 'BigNumber', 'bigint', or 'Fraction'
- * {number} precision
- * The number of significant digits for BigNumbers.
- * Not applicable for Numbers.
- * {string} parenthesis
- * How to display parentheses in LaTeX and string
- * output.
- * {string} randomSeed
- * Random seed for seeded pseudo random number generator.
- * Set to null to randomly seed.
+ * @param {Object} [options] Configuration options to be set
* @return {Object} Returns the current configuration
*/
function _config (options) {
- if (options) {
- if (options.epsilon !== undefined) {
- // this if is only for backwards compatibility, it can be removed in the future.
- console.warn('Warning: The configuration option "epsilon" is deprecated. Use "relTol" and "absTol" instead.')
- const optionsFix = clone(options)
- optionsFix.relTol = options.epsilon
- optionsFix.absTol = options.epsilon * 1e-3
- delete optionsFix.epsilon
- return _config(optionsFix)
- }
-
- if (options.legacySubset === true) {
- // this if is only for backwards compatibility, it can be removed in the future.
- console.warn('Warning: The configuration option "legacySubset" is for compatibility only and might be deprecated in the future.')
- }
- const prev = clone(config)
-
- // validate some of the options
- validateOption(options, 'matrix', MATRIX_OPTIONS)
- validateOption(options, 'number', NUMBER_OPTIONS)
-
- // merge options
- deepExtend(config, options)
-
- const curr = clone(config)
-
- const changes = clone(options)
-
- // emit 'config' event
- emit('config', curr, prev, changes)
-
- return curr
- } else {
- return clone(config)
+ if (!options) return clone(config)
+ // The following modernize call always clones options
+ options = modernizeOptions(options, REMAP_CONFIG)
+ // Special case for backward compatibility:
+ if (options.number === 'BigNumber' &&
+ !options.compute?.numberApproximate &&
+ config.number === 'number' &&
+ config.compute.numberApproximate === 'number'
+ ) {
+ console.warn(
+ 'For backward compatibility, copying number option setting of ' +
+ `'${options.number}' to compute.numberApproximate. To avoid this ` +
+ 'warning, set compute.numberApproximate explicitly.'
+ )
+ if (!options.compute) options.compute = {}
+ options.compute.numberApproximate = options.number
}
+ validateOptions(options, ALLOWED_CONFIG)
+ const prev = clone(config)
+ deepExtend(config, options) // merge options
+ const curr = clone(config)
+ emit('config', curr, prev, options)
+ return curr
}
// attach the valid options to the function so they can be extended
- _config.MATRIX_OPTIONS = MATRIX_OPTIONS
- _config.NUMBER_OPTIONS = NUMBER_OPTIONS
+ _config.ALLOWED_CONFIG = ALLOWED_CONFIG
// attach the config properties as readonly properties to the config function
Object.keys(DEFAULT_CONFIG).forEach(key => {
Object.defineProperty(_config, key, {
- get: () => config[key],
+ get: () => {
+ const res = config[key]
+ if (typeof res !== 'object') return res
+ return Object.freeze(clone(res))
+ },
enumerable: true,
configurable: true
})
@@ -104,15 +102,120 @@ export function configFactory (config, emit) {
}
/**
- * Validate an option
+ * Translate options to current synonyms and warn about
+ * discontinued options. Throws on discontinued options.
+ * @param {Object} options Object with options
+ * @param {Object} remapping Object specifying remapping
+ * @param {Function} warn Function to call with warnings
+ * @param {Array} path the nested path being processed
+ * @param {Object} base where to put remapped options
+ * @returns {Object} a clone of options with modified parameters if necessary
+ */
+export function modernizeOptions ( // exported solely for testing
+ options, remapping, warn = console.warn, path = [], base = clone(options)
+) {
+ for (const key in remapping) {
+ if (!Object.prototype.hasOwnProperty.call(remapping, key)) continue
+ const newPath = [...path, key]
+ if (key in options) {
+ let state = 'normal'
+ let translations = []
+ if (typeof remapping[key] === 'string') {
+ state = remapping[key]
+ } else if (Array.isArray(remapping[key])) {
+ state = remapping[key][0]
+ translations = remapping[key].slice(1)
+ } else { // subobject remapping
+ const adjusted = modernizeOptions(
+ options[key], remapping[key], warn, newPath, base)
+ if (Object.keys(adjusted).length === 0) {
+ delete objectAt(base, path)[key]
+ }
+ continue
+ }
+ if (state === 'discontinued') {
+ throw new Error(
+ `attempt to set discontinued config option '${newPath.join('.')}' ` +
+ `use '${translations}' instead.`)
+ } else if (state === 'deprecated') {
+ if (translations.length > 0) {
+ warn(
+ `Translating deprecated config option '${newPath.join('.')}' ` +
+ 'to its equivalent ' +
+ `'${translations.map(tran => tran.join('.')).join("' and '")}'.`)
+ } else {
+ if (options[key]) {
+ warn(`Setting deprecated config option '${newPath.join('.')}'.`)
+ }
+ }
+ }
+ if (translations.length > 0) {
+ for (const translation of translations) {
+ const tPathLen = translation.length - 1
+ const tPath = translation.slice(0, tPathLen)
+ const tKey = translation[tPathLen]
+ objectAt(base, tPath)[tKey] = options[key]
+ }
+ delete objectAt(base, path)[key]
+ }
+ }
+ }
+ return objectAt(base, path)
+}
+
+/**
+ * Returns a subobject at a path of successive keys
+ * @param {Object} base any object
+ * @param {Array} path Array of successive keys
+ * @returns base[path[0]][path[1]]...
+ */
+function objectAt (base, path) {
+ if (path.length === 0) return base
+ const key = path[0]
+ if (!(key in base)) base[key] = {}
+ if (path.length === 1) return base[key]
+ return objectAt(base[key], path.slice(1))
+}
+
+/**
+ * Validate options. A guard is either a list of allowed values or a boolean
+ * predicate on values.
* @param {Object} options Object with options
- * @param {string} name Name of the option to validate
- * @param {Array.} values Array with valid values for this option
+ * @param {Object} guards Object with guards
+ * @param {Array} path used only in recursive calls to track path
*/
-function validateOption (options, name, values) {
- if (options[name] !== undefined && !values.includes(options[name])) {
- // unknown value
- console.warn('Warning: Unknown value "' + options[name] + '" for configuration option "' + name + '". ' +
- 'Available options: ' + values.map(value => JSON.stringify(value)).join(', ') + '.')
+function validateOptions (options, guards, path = []) {
+ for (const key in options) {
+ if (!Object.prototype.hasOwnProperty.call(options, key)) continue
+ const newPath = [...path, key]
+ if (!(key in guards)) {
+ // TODO: Should this be an error?
+ console.warn(
+ `No validation guards for ${newPath.join('.')} in config options;` +
+ 'are you trying to set an unrecognized option?')
+ continue
+ }
+ // Special case: don't descend into randomSeed,
+ // because the intended value might be an object :/
+ if (key !== 'randomSeed' &&
+ !Array.isArray(options[key]) &&
+ typeof options[key] === 'object'
+ ) {
+ validateOptions(options[key], guards[key], newPath)
+ } else {
+ if (Array.isArray(guards[key])) {
+ if (!guards[key].includes(options[key])) {
+ throw new Error(
+ `Attempt to set config option ${newPath.join('.')} to ` +
+ `'${options[key]}', not in allowed values ${guards[key]}.`)
+ }
+ } else {
+ if (!guards[key](options[key])) {
+ throw new Error(
+ `Attempt to set config option ${newPath.join('.')} to ` +
+ `'${options[key]}', not satisfying: ${guards[key].name}.`)
+ }
+ }
+ }
}
}
diff --git a/src/entry/configReadonly.js b/src/entry/configReadonly.js
index 1fe4abdc3d..53ee531d3b 100644
--- a/src/entry/configReadonly.js
+++ b/src/entry/configReadonly.js
@@ -1,5 +1,4 @@
-import { DEFAULT_CONFIG } from '../core/config.js'
-import { MATRIX_OPTIONS, NUMBER_OPTIONS } from '../core/function/config.js'
+import { DEFAULT_CONFIG, ALLOWED_CONFIG } from '../core/config.js'
// create a read-only version of config
export const config = function (options) {
@@ -15,4 +14,4 @@ export const config = function (options) {
return Object.freeze(DEFAULT_CONFIG)
}
-Object.assign(config, DEFAULT_CONFIG, { MATRIX_OPTIONS, NUMBER_OPTIONS })
+Object.assign(config, DEFAULT_CONFIG, { ALLOWED_CONFIG })
diff --git a/src/expression/embeddedDocs/embeddedDocs.js b/src/expression/embeddedDocs/embeddedDocs.js
index 2e4383beb4..ab3e928d7d 100644
--- a/src/expression/embeddedDocs/embeddedDocs.js
+++ b/src/expression/embeddedDocs/embeddedDocs.js
@@ -80,6 +80,7 @@ import { roundDocs } from './function/arithmetic/round.js'
import { signDocs } from './function/arithmetic/sign.js'
import { sqrtDocs } from './function/arithmetic/sqrt.js'
import { sqrtmDocs } from './function/arithmetic/sqrtm.js'
+import { zeroDocs } from './function/arithmetic/zero.js'
import { sylvesterDocs } from './function/algebra/sylvester.js'
import { schurDocs } from './function/algebra/schur.js'
import { lyapDocs } from './function/algebra/lyap.js'
@@ -408,6 +409,7 @@ export const embeddedDocs = {
unaryPlus: unaryPlusDocs,
xgcd: xgcdDocs,
invmod: invmodDocs,
+ zero: zeroDocs,
// functions - bitwise
bitAnd: bitAndDocs,
diff --git a/src/expression/embeddedDocs/function/arithmetic/zero.js b/src/expression/embeddedDocs/function/arithmetic/zero.js
new file mode 100644
index 0000000000..4cf2c00634
--- /dev/null
+++ b/src/expression/embeddedDocs/function/arithmetic/zero.js
@@ -0,0 +1,8 @@
+export const zeroDocs = {
+ name: 'zero',
+ category: 'arithmetic',
+ syntax: ['zero(x)'],
+ description: 'returns the additive identity of the same type as x',
+ examples: ['zero(2/3)', 'zero([[1, -1, 1], [-1, 2, -1]])'],
+ seealso: ['typeOf', 'numeric']
+}
diff --git a/src/expression/node/ArrayNode.js b/src/expression/node/ArrayNode.js
index 145e96152f..7633fa2c3b 100644
--- a/src/expression/node/ArrayNode.js
+++ b/src/expression/node/ArrayNode.js
@@ -47,7 +47,7 @@ export const createArrayNode = /* #__PURE__ */ factory(name, dependencies, ({ No
return item._compile(math, argNames)
})
- const asMatrix = (math.config.matrix !== 'Array')
+ const asMatrix = (math.config.compute.Matrix.defaultType !== 'Array')
if (asMatrix) {
const matrix = math.matrix
return function evalArrayNode (scope, args, context) {
diff --git a/src/expression/transform/max.transform.js b/src/expression/transform/max.transform.js
index e0716ba196..c954655003 100644
--- a/src/expression/transform/max.transform.js
+++ b/src/expression/transform/max.transform.js
@@ -6,25 +6,26 @@ import { lastDimToZeroBase } from './utils/lastDimToZeroBase.js'
const name = 'max'
const dependencies = ['typed', 'config', 'numeric', 'larger', 'isNaN']
-export const createMaxTransform = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, numeric, larger, isNaN: mathIsNaN }) => {
- const max = createMax({ typed, config, numeric, larger, isNaN: mathIsNaN })
+export const createMaxTransform = /* #__PURE__ */ factory(
+ name, dependencies, provided => {
+ const max = createMax(provided)
- /**
- * Attach a transform function to math.max
- * Adds a property transform containing the transform function.
- *
- * This transform changed the last `dim` parameter of function max
- * from one-based to zero based
- */
- return typed('max', {
- '...any': function (args) {
- args = lastDimToZeroBase(args)
+ /**
+ * Attach a transform function to math.max
+ * Adds a property transform containing the transform function.
+ *
+ * This transform changed the last `dim` parameter of function max
+ * from one-based to zero based
+ */
+ return provided.typed('max', {
+ '...any': function (args) {
+ args = lastDimToZeroBase(args)
- try {
- return max.apply(null, args)
- } catch (err) {
- throw errorTransform(err)
+ try {
+ return max.apply(null, args)
+ } catch (err) {
+ throw errorTransform(err)
+ }
}
- }
- })
-}, { isTransformFunction: true })
+ })
+ }, { isTransformFunction: true })
diff --git a/src/expression/transform/min.transform.js b/src/expression/transform/min.transform.js
index 825285ed7b..5297f48fd5 100644
--- a/src/expression/transform/min.transform.js
+++ b/src/expression/transform/min.transform.js
@@ -6,25 +6,26 @@ import { lastDimToZeroBase } from './utils/lastDimToZeroBase.js'
const name = 'min'
const dependencies = ['typed', 'config', 'numeric', 'smaller', 'isNaN']
-export const createMinTransform = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, numeric, smaller, isNaN: mathIsNaN }) => {
- const min = createMin({ typed, config, numeric, smaller, isNaN: mathIsNaN })
+export const createMinTransform = /* #__PURE__ */ factory(
+ name, dependencies, provided => {
+ const min = createMin(provided)
- /**
- * Attach a transform function to math.min
- * Adds a property transform containing the transform function.
- *
- * This transform changed the last `dim` parameter of function min
- * from one-based to zero based
- */
- return typed('min', {
- '...any': function (args) {
- args = lastDimToZeroBase(args)
+ /**
+ * Attach a transform function to math.min
+ * Adds a property transform containing the transform function.
+ *
+ * This transform changed the last `dim` parameter of function min
+ * from one-based to zero based
+ */
+ return provided.typed('min', {
+ '...any': function (args) {
+ args = lastDimToZeroBase(args)
- try {
- return min.apply(null, args)
- } catch (err) {
- throw errorTransform(err)
+ try {
+ return min.apply(null, args)
+ } catch (err) {
+ throw errorTransform(err)
+ }
}
- }
- })
-}, { isTransformFunction: true })
+ })
+ }, { isTransformFunction: true })
diff --git a/src/expression/transform/range.transform.js b/src/expression/transform/range.transform.js
index 67211d4b94..16a9f1f6aa 100644
--- a/src/expression/transform/range.transform.js
+++ b/src/expression/transform/range.transform.js
@@ -2,27 +2,33 @@ import { factory } from '../../utils/factory.js'
import { createRange } from '../../function/matrix/range.js'
const name = 'range'
-const dependencies = ['typed', 'config', '?matrix', '?bignumber', 'equal', 'smaller', 'smallerEq', 'larger', 'largerEq', 'add', 'isZero', 'isPositive']
+const dependencies = [
+ 'typed', 'config', '?matrix', '?bignumber',
+ 'equal', 'smaller', 'smallerEq', 'larger', 'largerEq',
+ 'add', 'isZero', 'isPositive'
+]
-export const createRangeTransform = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, matrix, bignumber, equal, smaller, smallerEq, larger, largerEq, add, isZero, isPositive }) => {
- const range = createRange({ typed, config, matrix, bignumber, equal, smaller, smallerEq, larger, largerEq, add, isZero, isPositive })
+export const createRangeTransform = /* #__PURE__ */ factory(
+ name, dependencies, provided => {
+ const range = createRange(provided)
+ /**
+ * Attach a transform function to math.range
+ * Adds a property transform containing the transform function.
+ *
+ * This transform creates a range which includes the end value
+ */
+ return provided.typed('range', {
+ '...any': function (args) {
+ const lastIndex = args.length - 1
+ const last = args[lastIndex]
+ if (typeof last !== 'boolean') {
+ // append a parameter includeEnd=true
+ args.push(true)
+ }
- /**
- * Attach a transform function to math.range
- * Adds a property transform containing the transform function.
- *
- * This transform creates a range which includes the end value
- */
- return typed('range', {
- '...any': function (args) {
- const lastIndex = args.length - 1
- const last = args[lastIndex]
- if (typeof last !== 'boolean') {
- // append a parameter includeEnd=true
- args.push(true)
+ return range.apply(null, args)
}
-
- return range.apply(null, args)
- }
- })
-}, { isTransformFunction: true })
+ })
+ },
+ { isTransformFunction: true }
+)
diff --git a/src/expression/transform/sum.transform.js b/src/expression/transform/sum.transform.js
index 9ce352e69b..6b75e80664 100644
--- a/src/expression/transform/sum.transform.js
+++ b/src/expression/transform/sum.transform.js
@@ -13,18 +13,19 @@ import { lastDimToZeroBase } from './utils/lastDimToZeroBase.js'
const name = 'sum'
const dependencies = ['typed', 'config', 'add', 'numeric']
-export const createSumTransform = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, add, numeric }) => {
- const sum = createSum({ typed, config, add, numeric })
+export const createSumTransform = /* #__PURE__ */ factory(
+ name, dependencies, provided => {
+ const sum = createSum(provided)
- return typed(name, {
- '...any': function (args) {
- args = lastDimToZeroBase(args)
+ return provided.typed(name, {
+ '...any': function (args) {
+ args = lastDimToZeroBase(args)
- try {
- return sum.apply(null, args)
- } catch (err) {
- throw errorTransform(err)
+ try {
+ return sum.apply(null, args)
+ } catch (err) {
+ throw errorTransform(err)
+ }
}
- }
- })
-}, { isTransformFunction: true })
+ })
+ }, { isTransformFunction: true })
diff --git a/src/factoriesAny.js b/src/factoriesAny.js
index 15ea5de0d0..203a1f9516 100644
--- a/src/factoriesAny.js
+++ b/src/factoriesAny.js
@@ -121,6 +121,7 @@ export { createLog1p } from './function/arithmetic/log1p.js'
export { createNthRoots } from './function/arithmetic/nthRoots.js'
export { createDotPow } from './function/arithmetic/dotPow.js'
export { createDotDivide } from './function/arithmetic/dotDivide.js'
+export { createZero } from './function/arithmetic/zero.js'
export { createLsolve } from './function/algebra/solver/lsolve.js'
export { createUsolve } from './function/algebra/solver/usolve.js'
export { createLsolveAll } from './function/algebra/solver/lsolveAll.js'
diff --git a/src/factoriesNumber.js b/src/factoriesNumber.js
index 73a0eaafb5..38b7a9d79d 100644
--- a/src/factoriesNumber.js
+++ b/src/factoriesNumber.js
@@ -134,6 +134,7 @@ export const createAdd = /* #__PURE__ */ createNumberFactory('add', addNumber)
export { createHypot } from './function/arithmetic/hypot.js'
export const createNorm = /* #__PURE__ */ createNumberFactory('norm', normNumber)
export const createDivide = /* #__PURE__ */ createNumberFactory('divide', divideNumber)
+export { createZeroNumber } from './function/arithmetic/zero.js'
// bitwise
export const createBitAnd = /* #__PURE__ */ createNumberFactory('bitAnd', bitAndNumber)
diff --git a/src/function/algebra/rationalize.js b/src/function/algebra/rationalize.js
index 4c901ee08f..00877a1b08 100644
--- a/src/function/algebra/rationalize.js
+++ b/src/function/algebra/rationalize.js
@@ -3,7 +3,6 @@ import { factory } from '../../utils/factory.js'
const name = 'rationalize'
const dependencies = [
- 'config',
'typed',
'equal',
'isZero',
@@ -32,7 +31,6 @@ const dependencies = [
]
export const createRationalize = /* #__PURE__ */ factory(name, dependencies, ({
- config,
typed,
equal,
isZero,
diff --git a/src/function/algebra/simplifyConstant.js b/src/function/algebra/simplifyConstant.js
index f7a2417809..221b75394b 100644
--- a/src/function/algebra/simplifyConstant.js
+++ b/src/function/algebra/simplifyConstant.js
@@ -12,6 +12,7 @@ const dependencies = [
'matrix',
'isBounded',
'?fraction',
+ '?Fraction',
'?bignumber',
'AccessorNode',
'ArrayNode',
@@ -30,6 +31,7 @@ export const createSimplifyConstant = /* #__PURE__ */ factory(name, dependencies
matrix,
isBounded,
fraction,
+ Fraction,
bignumber,
AccessorNode,
ArrayNode,
@@ -93,7 +95,15 @@ export const createSimplifyConstant = /* #__PURE__ */ factory(name, dependencies
function _eval (fnname, args, options) {
try {
- return mathWithTransform[fnname].apply(null, args)
+ const result = mathWithTransform[fnname].apply(null, args)
+ if (isFraction(result) && fnname !== 'fraction' &&
+ args.every(arg => !isFraction(arg) || arg.fromNumber)
+ ) {
+ result.fromNumber = true
+ } else if (result && typeof result === 'object' && 'fromNumber' in result) {
+ delete result.fromNumber
+ }
+ return result
} catch (ignore) {
// sometimes the implicit type conversion causes the evaluation to fail, so we'll try again after removing Fractions
args = args.map(_removeFractions)
@@ -102,7 +112,11 @@ export const createSimplifyConstant = /* #__PURE__ */ factory(name, dependencies
}
const _toNode = typed({
- Fraction: _fractionToNode,
+ Fraction: function (f) {
+ if (f.fromNumber) return _fractionToNode(f)
+ if (f.s < 0) return unaryMinusNode(new ConstantNode(f.neg()))
+ return new ConstantNode(f)
+ },
number: function (n) {
if (n < 0) {
return unaryMinusNode(new ConstantNode(-n))
@@ -132,6 +146,25 @@ export const createSimplifyConstant = /* #__PURE__ */ factory(name, dependencies
}
})
+ function _fractionToNode (f) {
+ // This is a fraction that came from a JavaScript number, directly or indirectly.
+ // We restore it to either a whole number or a quotient of whole numbers, but
+ // we don't use bigints because they do not divide as expected.
+ const fromBigInt = config.number === 'BigNumber' && bignumber
+ ? x => bignumber(x)
+ : x => Number(x)
+
+ const numeratorValue = fromBigInt(f.n)
+ const numeratorNode = (f.s < 0n)
+ ? new OperatorNode('-', 'unaryMinus', [new ConstantNode(numeratorValue)])
+ : new ConstantNode(fromBigInt(numeratorValue))
+
+ return (f.d === 1n)
+ ? numeratorNode
+ : new OperatorNode(
+ '/', 'divide', [numeratorNode, new ConstantNode(fromBigInt(f.d))])
+ }
+
function _ensureNode (thing) {
if (isNode(thing)) {
return thing
@@ -150,6 +183,7 @@ export const createSimplifyConstant = /* #__PURE__ */ factory(name, dependencies
: Infinity // no limit by default
if (f.valueOf() === n && f.n < fractionsLimit && f.d < fractionsLimit) {
+ f.fromNumber = true
return f
}
}
@@ -212,20 +246,6 @@ export const createSimplifyConstant = /* #__PURE__ */ factory(name, dependencies
return new OperatorNode('-', 'unaryMinus', [n])
}
- function _fractionToNode (f) {
- // note: we convert await from bigint values, because bigint values gives issues with divisions: 1n/2n=0n and not 0.5
- const fromBigInt = (value) => config.number === 'BigNumber' && bignumber ? bignumber(value) : Number(value)
-
- const numeratorValue = f.s * f.n
- const numeratorNode = (numeratorValue < 0n)
- ? new OperatorNode('-', 'unaryMinus', [new ConstantNode(-fromBigInt(numeratorValue))])
- : new ConstantNode(fromBigInt(numeratorValue))
-
- return (f.d === 1n)
- ? numeratorNode
- : new OperatorNode('/', 'divide', [numeratorNode, new ConstantNode(fromBigInt(f.d))])
- }
-
/* Handles constant indexing of ArrayNodes, matrices, and ObjectNodes */
function _foldAccessor (obj, index, options) {
if (!isIndexNode(index)) { // don't know what to do with that...
@@ -353,6 +373,41 @@ export const createSimplifyConstant = /* #__PURE__ */ factory(name, dependencies
// destroys the original node and returns a folded one
function foldFraction (node, options) {
+ const binaryAdvise = ['add', 'sub', 'mul', 'div', 'pow']
+ const unaryAdvise = ['floor', 'ceil', 'round', 'clone']
+ const old = {}
+ if (Fraction) {
+ for (const op of binaryAdvise) {
+ old[op] = Fraction.prototype[op]
+ Fraction.prototype[op] = function (a, b) {
+ const result = old[op].call(this, a, b)
+ if (this.fromNumber && a && typeof a === 'object' && a.fromNumber) {
+ result.fromNumber = true
+ }
+ return result
+ }
+ }
+ for (const op of unaryAdvise) {
+ old[op] = Fraction.prototype[op]
+ Fraction.prototype[op] = function (...args) {
+ const result = old[op].call(this, ...args)
+ if (this.fromNumber) result.fromNumber = true
+ return result
+ }
+ }
+ }
+ try {
+ return _foldFraction(node, options)
+ } finally {
+ if (Fraction) {
+ for (const op of unaryAdvise.concat(binaryAdvise)) {
+ Fraction.prototype[op] = old[op]
+ }
+ }
+ }
+ }
+
+ function _foldFraction (node, options) {
switch (node.type) {
case 'SymbolNode':
return node
@@ -373,7 +428,7 @@ export const createSimplifyConstant = /* #__PURE__ */ factory(name, dependencies
// Process operators as OperatorNode
const operatorFunctions = ['add', 'multiply']
if (!operatorFunctions.includes(node.name)) {
- const args = node.args.map(arg => foldFraction(arg, options))
+ const args = node.args.map(arg => _foldFraction(arg, options))
// If all args are numbers
if (!args.some(isNode)) {
@@ -409,7 +464,7 @@ export const createSimplifyConstant = /* #__PURE__ */ factory(name, dependencies
let res
const makeNode = createMakeNodeFunction(node)
if (isOperatorNode(node) && node.isUnary()) {
- args = [foldFraction(node.args[0], options)]
+ args = [_foldFraction(node.args[0], options)]
if (!isNode(args[0])) {
res = _eval(fn, args, options)
} else {
@@ -417,8 +472,7 @@ export const createSimplifyConstant = /* #__PURE__ */ factory(name, dependencies
}
} else if (isAssociative(node, options.context)) {
args = allChildren(node, options.context)
- args = args.map(arg => foldFraction(arg, options))
-
+ args = args.map(arg => _foldFraction(arg, options))
if (isCommutative(fn, options.context)) {
// commutative binary operator
const consts = []
@@ -446,21 +500,21 @@ export const createSimplifyConstant = /* #__PURE__ */ factory(name, dependencies
}
} else {
// non-associative binary operator
- args = node.args.map(arg => foldFraction(arg, options))
+ args = node.args.map(arg => _foldFraction(arg, options))
res = foldOp(fn, args, makeNode, options)
}
return res
}
case 'ParenthesisNode':
// remove the uneccessary parenthesis
- return foldFraction(node.content, options)
+ return _foldFraction(node.content, options)
case 'AccessorNode':
return _foldAccessor(
- foldFraction(node.object, options),
- foldFraction(node.index, options),
+ _foldFraction(node.object, options),
+ _foldFraction(node.index, options),
options)
case 'ArrayNode': {
- const foldItems = node.items.map(item => foldFraction(item, options))
+ const foldItems = node.items.map(item => _foldFraction(item, options))
if (foldItems.some(isNode)) {
return new ArrayNode(foldItems.map(_ensureNode))
}
diff --git a/src/function/algebra/sylvester.js b/src/function/algebra/sylvester.js
index 53d0c3d0b5..cf2d58dc42 100644
--- a/src/function/algebra/sylvester.js
+++ b/src/function/algebra/sylvester.js
@@ -35,8 +35,7 @@ export const createSylvester = /* #__PURE__ */ factory(name, dependencies, (
subtract,
identity,
lusolve,
- abs,
- config
+ abs
}
) => {
/**
diff --git a/src/function/algebra/symbolicEqual.js b/src/function/algebra/symbolicEqual.js
index 8494ae93ad..0da5ec176e 100644
--- a/src/function/algebra/symbolicEqual.js
+++ b/src/function/algebra/symbolicEqual.js
@@ -6,14 +6,16 @@ const dependencies = [
'parse',
'simplify',
'typed',
- 'OperatorNode'
+ 'OperatorNode',
+ 'isZero'
]
export const createSymbolicEqual = /* #__PURE__ */ factory(name, dependencies, ({
parse,
simplify,
typed,
- OperatorNode
+ OperatorNode,
+ isZero
}) => {
/**
* Attempts to determine if two expressions are symbolically equal, i.e.
@@ -56,7 +58,7 @@ export const createSymbolicEqual = /* #__PURE__ */ factory(name, dependencies, (
function _symbolicEqual (e1, e2, options = {}) {
const diff = new OperatorNode('-', 'subtract', [e1, e2])
const simplified = simplify(diff, {}, options)
- return (isConstantNode(simplified) && !(simplified.value))
+ return (isConstantNode(simplified) && isZero(simplified.value))
}
return typed(name, {
diff --git a/src/function/arithmetic/cbrt.js b/src/function/arithmetic/cbrt.js
index ae71eca054..d1f997826c 100644
--- a/src/function/arithmetic/cbrt.js
+++ b/src/function/arithmetic/cbrt.js
@@ -97,7 +97,7 @@ export const createCbrt = /* #__PURE__ */ factory(name, dependencies, ({ config,
new Complex(cbrtNumber(abs), 0).mul(new Complex(0, arg3 - Math.PI * 2 / 3).exp())
]
- return (config.matrix === 'Array') ? all : matrix(all)
+ return (config.compute.Matrix.defaultType === 'Array') ? all : matrix(all)
} else {
return principal
}
diff --git a/src/function/arithmetic/ceil.js b/src/function/arithmetic/ceil.js
index a3f40bbbed..b921d74a2f 100644
--- a/src/function/arithmetic/ceil.js
+++ b/src/function/arithmetic/ceil.js
@@ -15,13 +15,15 @@ const bigTen = new Decimal(10)
export const createCeilNumber = /* #__PURE__ */ factory(
name, ['typed', 'config', 'round'], ({ typed, config, round }) => {
function _ceilNumber (x) {
+ const relTol = config.compute.defaultRelTol
+ const absTol = config.compute.defaultAbsTol
// See ./floor.js _floorNumber for rationale here
const c = Math.ceil(x)
const r = round(x)
if (c === r) return c
if (
- nearlyEqual(x, r, config.relTol, config.absTol) &&
- !nearlyEqual(x, c, config.relTol, config.absTol)
+ nearlyEqual(x, r, relTol, absTol) &&
+ !nearlyEqual(x, c, relTol, absTol)
) {
return r
}
@@ -54,7 +56,8 @@ export const createCeil = /* #__PURE__ */ factory(name, dependencies, ({ typed,
const ceilNumber = createCeilNumber({ typed, config, round })
function _bigCeil (x) {
// see ./floor.js _floorNumber for rationale
- const bne = (a, b) => bigNearlyEqual(a, b, config.relTol, config.absTol)
+ const bne = (a, b) => bigNearlyEqual(
+ a, b, config.compute.defaultRelTol, config.compute.defaultAbsTol)
const c = x.ceil()
const r = round(x)
if (c.eq(r)) return c
diff --git a/src/function/arithmetic/floor.js b/src/function/arithmetic/floor.js
index 752d06864d..eec22096ec 100644
--- a/src/function/arithmetic/floor.js
+++ b/src/function/arithmetic/floor.js
@@ -23,9 +23,11 @@ export const createFloorNumber = /* #__PURE__ */ factory(
// OK, they are different. If x is truly distinct from f but
// appears indistinguishable from r, presume it really is just
// the integer r with rounding/computation error, and return that
+ const relTol = config.compute.defaultRelTol
+ const absTol = config.compute.defaultAbsTol
if (
- nearlyEqual(x, r, config.relTol, config.absTol) &&
- !nearlyEqual(x, f, config.relTol, config.absTol)
+ nearlyEqual(x, r, relTol, absTol) &&
+ !nearlyEqual(x, f, relTol, absTol)
) {
return r
}
@@ -61,7 +63,8 @@ export const createFloor = /* #__PURE__ */ factory(name, dependencies, ({ typed,
const floorNumber = createFloorNumber({ typed, config, round })
function _bigFloor (x) {
// see _floorNumber above for rationale
- const bne = (a, b) => bigNearlyEqual(a, b, config.relTol, config.absTol)
+ const bne = (a, b) => bigNearlyEqual(
+ a, b, config.compute.defaultRelTol, config.compute.defaultAbsTol)
const f = x.floor()
const r = round(x)
if (f.eq(r)) return f
diff --git a/src/function/arithmetic/invmod.js b/src/function/arithmetic/invmod.js
index a3f880601f..aa905ac3bb 100644
--- a/src/function/arithmetic/invmod.js
+++ b/src/function/arithmetic/invmod.js
@@ -1,9 +1,9 @@
import { factory } from '../../utils/factory.js'
const name = 'invmod'
-const dependencies = ['typed', 'config', 'BigNumber', 'xgcd', 'equal', 'smaller', 'mod', 'add', 'isInteger']
+const dependencies = ['typed', 'BigNumber', 'xgcd', 'equal', 'smaller', 'mod', 'add', 'isInteger']
-export const createInvmod = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, BigNumber, xgcd, equal, smaller, mod, add, isInteger }) => {
+export const createInvmod = /* #__PURE__ */ factory(name, dependencies, ({ typed, BigNumber, xgcd, equal, smaller, mod, add, isInteger }) => {
/**
* Calculate the (modular) multiplicative inverse of a modulo b. Solution to the equation `ax ≣ 1 (mod b)`
* See https://en.wikipedia.org/wiki/Modular_multiplicative_inverse.
diff --git a/src/function/arithmetic/log.js b/src/function/arithmetic/log.js
index 3dadeaa40e..f40b32be5d 100644
--- a/src/function/arithmetic/log.js
+++ b/src/function/arithmetic/log.js
@@ -52,7 +52,7 @@ export const createLog = /* #__PURE__ */ factory(name, dependencies, ({ typed, t
return typed(name, {
number: function (x) {
- if (x >= 0 || config.predictable) {
+ if (x >= 0 || config.compute.uniformType) {
return logNumber(x)
} else {
// negative value -> complex value computation
@@ -60,12 +60,13 @@ export const createLog = /* #__PURE__ */ factory(name, dependencies, ({ typed, t
}
},
- bigint: promoteLogarithm(nlg16, logNumber, config, complexLogNumber),
+ bigint: promoteLogarithm(
+ nlg16, logNumber, config.compute.uniformType, complexLogNumber),
Complex: complexLog,
BigNumber: function (x) {
- if (!x.isNegative() || config.predictable) {
+ if (!x.isNegative() || config.compute.uniformType) {
return x.ln()
} else {
// downgrade to number, return Complex valued result
diff --git a/src/function/arithmetic/log10.js b/src/function/arithmetic/log10.js
index 8cde9a3d27..26c7c9a353 100644
--- a/src/function/arithmetic/log10.js
+++ b/src/function/arithmetic/log10.js
@@ -43,7 +43,7 @@ export const createLog10 = /* #__PURE__ */ factory(name, dependencies, ({ typed,
}
return typed(name, {
number: function (x) {
- if (x >= 0 || config.predictable) {
+ if (x >= 0 || config.compute.uniformType) {
return log10Number(x)
} else {
// negative value -> complex value computation
@@ -51,12 +51,13 @@ export const createLog10 = /* #__PURE__ */ factory(name, dependencies, ({ typed,
}
},
- bigint: promoteLogarithm(log16, log10Number, config, complexLogNumber),
+ bigint: promoteLogarithm(
+ log16, log10Number, config.compute.uniformType, complexLogNumber),
Complex: complexLog,
BigNumber: function (x) {
- if (!x.isNegative() || config.predictable) {
+ if (!x.isNegative() || config.compute.uniformType) {
return x.log()
} else {
// downgrade to number, return Complex valued result
diff --git a/src/function/arithmetic/log1p.js b/src/function/arithmetic/log1p.js
index a210750d56..eeef8e20a9 100644
--- a/src/function/arithmetic/log1p.js
+++ b/src/function/arithmetic/log1p.js
@@ -39,19 +39,18 @@ export const createLog1p = /* #__PURE__ */ factory(name, dependencies, ({ typed,
*/
return typed(name, {
number: function (x) {
- if (x >= -1 || config.predictable) {
+ if (x >= -1 || config.compute.uniformType) {
return _log1p(x)
- } else {
- // negative value -> complex value computation
- return _log1pComplex(new Complex(x, 0))
}
+ // negative value -> complex value computation
+ return _log1pComplex(new Complex(x, 0))
},
Complex: _log1pComplex,
BigNumber: function (x) {
const y = x.plus(1)
- if (!y.isNegative() || config.predictable) {
+ if (!y.isNegative() || config.compute.uniformType) {
return y.ln()
} else {
// downgrade to number, return Complex valued result
@@ -75,6 +74,11 @@ export const createLog1p = /* #__PURE__ */ factory(name, dependencies, ({ typed,
*/
function _log1pComplex (x) {
const xRe1p = x.re + 1
+ // TODO: for |x| small compared to 1, we should actually use the
+ // Taylor series of sqrt(1+x) to express the result of the sqrt
+ // call below in the form 1 + epsilon for some small epsilon, and then
+ // use _log1p on that epsilon. Right now we are giving up lots of
+ // accuracy near the origin in the real part of the result.
return new Complex(
Math.log(Math.sqrt(xRe1p * xRe1p + x.im * x.im)),
Math.atan2(x.im, xRe1p)
diff --git a/src/function/arithmetic/log2.js b/src/function/arithmetic/log2.js
index 19b239f7cf..864c66c144 100644
--- a/src/function/arithmetic/log2.js
+++ b/src/function/arithmetic/log2.js
@@ -38,7 +38,7 @@ export const createLog2 = /* #__PURE__ */ factory(name, dependencies, ({ typed,
return typed(name, {
number: function (x) {
- if (x >= 0 || config.predictable) {
+ if (x >= 0 || config.compute.uniformType) {
return log2Number(x)
} else {
// negative value -> complex value computation
@@ -46,12 +46,13 @@ export const createLog2 = /* #__PURE__ */ factory(name, dependencies, ({ typed,
}
},
- bigint: promoteLogarithm(4, log2Number, config, complexLog2Number),
+ bigint: promoteLogarithm(
+ 4, log2Number, config.compute.uniformType, complexLog2Number),
Complex: _log2Complex,
BigNumber: function (x) {
- if (!x.isNegative() || config.predictable) {
+ if (!x.isNegative() || config.compute.uniformType) {
return x.log(2)
} else {
// downgrade to number, return Complex valued result
diff --git a/src/function/arithmetic/nthRoots.js b/src/function/arithmetic/nthRoots.js
index 42abfef79b..0a995d8102 100644
--- a/src/function/arithmetic/nthRoots.js
+++ b/src/function/arithmetic/nthRoots.js
@@ -1,9 +1,9 @@
import { factory } from '../../utils/factory.js'
const name = 'nthRoots'
-const dependencies = ['config', 'typed', 'divideScalar', 'Complex']
+const dependencies = ['typed', 'divideScalar', 'Complex']
-export const createNthRoots = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, divideScalar, Complex }) => {
+export const createNthRoots = /* #__PURE__ */ factory(name, dependencies, ({ typed, divideScalar, Complex }) => {
/**
* Each function here returns a real multiple of i as a Complex value.
* @param {number} val
diff --git a/src/function/arithmetic/pow.js b/src/function/arithmetic/pow.js
index f7dfba37d5..1c9280360a 100644
--- a/src/function/arithmetic/pow.js
+++ b/src/function/arithmetic/pow.js
@@ -27,7 +27,8 @@ export const createPow = /* #__PURE__ */ factory(name, dependencies, ({ typed, c
*
* For cubic roots of negative numbers, the function returns the principal
* root by default. In order to let the function return the real root,
- * math.js can be configured with `math.config({predictable: true})`.
+ * math.js can be configured with
+ * `math.config({compute: {uniformType: true})`.
* To retrieve all cubic roots of a value, use `math.cbrt(x, true)`.
*
* Syntax:
@@ -63,7 +64,7 @@ export const createPow = /* #__PURE__ */ factory(name, dependencies, ({ typed, c
},
'BigNumber, BigNumber': function (x, y) {
- if (y.isInteger() || x >= 0 || config.predictable) {
+ if (y.isInteger() || x >= 0 || config.compute.uniformType) {
return x.pow(y)
} else {
return new Complex(x.toNumber(), 0).pow(y.toNumber(), 0)
@@ -79,8 +80,9 @@ export const createPow = /* #__PURE__ */ factory(name, dependencies, ({ typed, c
return result
}
- if (config.predictable) {
- throw new Error('Result of pow is non-rational and cannot be expressed as a fraction')
+ if (config.compute.uniformType) {
+ throw new Error(
+ 'Result of pow is non-rational and cannot be expressed as a fraction')
} else {
return _pow(x.valueOf(), y.valueOf())
}
@@ -113,8 +115,8 @@ export const createPow = /* #__PURE__ */ factory(name, dependencies, ({ typed, c
*/
function _pow (x, y) {
// Alternatively could define a 'realmode' config option or something, but
- // 'predictable' will work for now
- if (config.predictable && !isInteger(y) && x < 0) {
+ // 'uniformType' will work for now
+ if (config.compute.uniformType && !isInteger(y) && x < 0) {
// Check to see if y can be represented as a fraction
try {
const yFrac = fraction(y)
@@ -131,16 +133,16 @@ export const createPow = /* #__PURE__ */ factory(name, dependencies, ({ typed, c
// Unable to express y as a fraction, so continue on
}
- // **for predictable mode** x^Infinity === NaN if x < -1
+ // **for uniformType mode** x^Infinity === NaN if x < -1
// N.B. this behavour is different from `Math.pow` which gives
// (-2)^Infinity === Infinity
- if (config.predictable &&
+ if (config.compute.uniformType &&
((x < -1 && y === Infinity) ||
(x > -1 && x < 0 && y === -Infinity))) {
return NaN
}
- if (isInteger(y) || x >= 0 || config.predictable) {
+ if (isInteger(y) || x >= 0 || config.compute.uniformType) {
return powNumber(x, y)
} else {
// TODO: the following infinity checks are duplicated from powNumber. Deduplicate this somehow
diff --git a/src/function/arithmetic/round.js b/src/function/arithmetic/round.js
index 738559ce80..e7c8cf701c 100644
--- a/src/function/arithmetic/round.js
+++ b/src/function/arithmetic/round.js
@@ -75,19 +75,25 @@ export const createRound = /* #__PURE__ */ factory(name, dependencies, ({ typed,
*/
return typed(name, {
number: function (x) {
+ const opts = config.compute
// Handle round off errors by first rounding to relTol precision
- const xEpsilon = roundNumber(x, toExponent(config.relTol))
- const xSelected = nearlyEqual(x, xEpsilon, config.relTol, config.absTol) ? xEpsilon : x
+ const xEpsilon = roundNumber(x, toExponent(opts.defaultRelTol))
+ const xSelected = nearlyEqual(x, xEpsilon, opts.defaultRelTol, opts.defaultAbsTol)
+ ? xEpsilon
+ : x
return roundNumber(xSelected)
},
'number, number': function (x, n) {
+ const opts = config.compute
// Same as number: unless user specifies more decimals than relTol
- const epsilonExponent = toExponent(config.relTol)
+ const epsilonExponent = toExponent(opts.defaultRelTol)
if (n >= epsilonExponent) { return roundNumber(x, n) }
const xEpsilon = roundNumber(x, epsilonExponent)
- const xSelected = nearlyEqual(x, xEpsilon, config.relTol, config.absTol) ? xEpsilon : x
+ const xSelected = nearlyEqual(x, xEpsilon, opts.defaultRelTol, config.defaultAbsTol)
+ ? xEpsilon
+ : x
return roundNumber(xSelected, n)
},
@@ -115,21 +121,26 @@ export const createRound = /* #__PURE__ */ factory(name, dependencies, ({ typed,
},
BigNumber: function (x) {
+ const opts = config.compute
// Handle round off errors by first rounding to relTol precision
- const xEpsilon = new BigNumber(x).toDecimalPlaces(toExponent(config.relTol))
- const xSelected = bigNearlyEqual(x, xEpsilon, config.relTol, config.absTol) ? xEpsilon : x
+ const xEpsilon = new BigNumber(x).toDecimalPlaces(
+ toExponent(opts.defaultRelTol))
+ const xSelected =
+ bigNearlyEqual(x, xEpsilon, opts.defaultRelTol, opts.defaultAbsTol) ? xEpsilon : x
return xSelected.toDecimalPlaces(0)
},
'BigNumber, BigNumber': function (x, n) {
+ const opts = config.compute
if (!n.isInteger()) { throw new TypeError(NO_INT) }
// Same as BigNumber: unless user specifies more decimals than relTol
- const epsilonExponent = toExponent(config.relTol)
+ const epsilonExponent = toExponent(opts.defaultRelTol)
if (n >= epsilonExponent) { return x.toDecimalPlaces(n.toNumber()) }
const xEpsilon = x.toDecimalPlaces(epsilonExponent)
- const xSelected = bigNearlyEqual(x, xEpsilon, config.relTol, config.absTol) ? xEpsilon : x
+ const xSelected =
+ bigNearlyEqual(x, xEpsilon, opts.defaultRelTol, opts.defaultAbsTol) ? xEpsilon : x
return xSelected.toDecimalPlaces(n.toNumber())
},
diff --git a/src/function/arithmetic/sqrt.js b/src/function/arithmetic/sqrt.js
index 8174dd72e3..83b179fd86 100644
--- a/src/function/arithmetic/sqrt.js
+++ b/src/function/arithmetic/sqrt.js
@@ -38,7 +38,7 @@ export const createSqrt = /* #__PURE__ */ factory(name, dependencies, ({ config,
},
BigNumber: function (x) {
- if (!x.isNegative() || config.predictable) {
+ if (!x.isNegative() || config.compute.uniformType) {
return x.sqrt()
} else {
// negative value -> downgrade to number to do complex value computation
@@ -62,7 +62,7 @@ export const createSqrt = /* #__PURE__ */ factory(name, dependencies, ({ config,
function _sqrtNumber (x) {
if (isNaN(x)) {
return NaN
- } else if (x >= 0 || config.predictable) {
+ } else if (x >= 0 || config.compute.uniformType) {
return Math.sqrt(x)
} else {
return new Complex(x, 0).sqrt()
diff --git a/src/function/arithmetic/unaryMinus.js b/src/function/arithmetic/unaryMinus.js
index 98148de0bd..08c79209d8 100644
--- a/src/function/arithmetic/unaryMinus.js
+++ b/src/function/arithmetic/unaryMinus.js
@@ -3,9 +3,11 @@ import { deepMap } from '../../utils/collection.js'
import { unaryMinusNumber } from '../../plain/number/index.js'
const name = 'unaryMinus'
-const dependencies = ['typed']
+const dependencies = ['typed', 'config', 'numeric']
-export const createUnaryMinus = /* #__PURE__ */ factory(name, dependencies, ({ typed }) => {
+export const createUnaryMinus = /* #__PURE__ */ factory(name, dependencies, ({
+ typed, config, numeric
+}) => {
/**
* Inverse the sign of a value, apply a unary minus operation.
*
@@ -42,6 +44,8 @@ export const createUnaryMinus = /* #__PURE__ */ factory(name, dependencies, ({ t
return res
}),
+ boolean: x => numeric(x ? -1 : -0, config.number),
+
// deep map collection, skip zeros since unaryMinus(0) = 0
'Array | Matrix': typed.referToSelf(self => x => deepMap(x, self, true))
diff --git a/src/function/arithmetic/unaryPlus.js b/src/function/arithmetic/unaryPlus.js
index a6b2ccf9ce..2382305403 100644
--- a/src/function/arithmetic/unaryPlus.js
+++ b/src/function/arithmetic/unaryPlus.js
@@ -58,6 +58,8 @@ export const createUnaryPlus = /* #__PURE__ */ factory(name, dependencies, ({ ty
'Array | Matrix': typed.referToSelf(self => x => deepMap(x, self, true)),
boolean: function (x) {
+ // we know this value can be expressed as any numeric type,
+ // so no need to worry about compute.numberApproximate
return numeric(x ? 1 : 0, config.number)
},
diff --git a/src/function/arithmetic/xgcd.js b/src/function/arithmetic/xgcd.js
index 556798af59..97164185f2 100644
--- a/src/function/arithmetic/xgcd.js
+++ b/src/function/arithmetic/xgcd.js
@@ -32,7 +32,7 @@ export const createXgcd = /* #__PURE__ */ factory(name, dependencies, ({ typed,
'number, number': function (a, b) {
const res = xgcdNumber(a, b)
- return (config.matrix === 'Array')
+ return (config.compute.Matrix.defaultType === 'Array')
? res
: matrix(res)
},
@@ -91,6 +91,6 @@ export const createXgcd = /* #__PURE__ */ factory(name, dependencies, ({ typed,
} else {
res = [a, !a.isZero() ? lastx : 0, lasty]
}
- return (config.matrix === 'Array') ? res : matrix(res)
+ return (config.compute.Matrix.defaultType === 'Array') ? res : matrix(res)
}
})
diff --git a/src/function/arithmetic/zero.js b/src/function/arithmetic/zero.js
new file mode 100644
index 0000000000..933fbf0654
--- /dev/null
+++ b/src/function/arithmetic/zero.js
@@ -0,0 +1,55 @@
+import { factory } from '../../utils/factory.js'
+
+const name = 'zero'
+const dependencies = [
+ 'typed', 'config', 'numeric', '?BigNumber', '?Complex', '?Fraction', 'size', 'zeros'
+]
+
+export const createZeroNumber = /* #__PURE__ */ factory(
+ name, ['typed'], ({ typed }) => {
+ return typed(name, { number: () => 0 })
+ })
+
+export const createZero = /* #__PURE__ */ factory(name, dependencies, ({
+ typed, config, numeric, BigNumber, Complex, Fraction, size, zeros
+}) => {
+ /**
+ * Return the additive identity of the same type as the argument.
+ * If no argument is given, returns the zero of the config.number type.
+ *
+ * Syntax:
+ *
+ * math.zero()
+ * math.zero(x)
+ *
+ * Examples:
+ *
+ * math.zero(1.618) // returns 0
+ * math.zero(math.bignumber(222)) // BigNumber 0
+ * math.zero(math.fraction(1, 3)) // Fraction 0
+ * math.zero(math.evaluate('0 + 2i')) // Complex 0+0i
+ * math.zero([[2, 3, 4], [4, 5, 6]]) // [[0, 0, 0], [0, 0, 0]]
+ *
+ * See also:
+ * typeOf, numeric
+ *
+ * @param {MathType} x Any entity mathjs understands
+ * @return {MathType} Additive identity of same type as x
+ */
+ return typed(name, {
+ 'null|undefined': () => numeric(0, config.number),
+ number: () => 0,
+ bigint: () => 0n,
+ BigNumber: () => new BigNumber(0),
+ Complex: () => new Complex(0),
+ Fraction: () => new Fraction(0),
+ boolean: () => false,
+ Unit: typed.referToSelf(self => u => {
+ const result = u.clone()
+ result.value = self(u.value)
+ return result
+ }),
+ Array: A => zeros(size(A)).valueOf(),
+ Matrix: M => zeros(size(M))
+ })
+})
diff --git a/src/function/geometry/intersect.js b/src/function/geometry/intersect.js
index ea6836cff0..a6a126e2f9 100644
--- a/src/function/geometry/intersect.js
+++ b/src/function/geometry/intersect.js
@@ -2,17 +2,24 @@ import { factory } from '../../utils/factory.js'
const name = 'intersect'
const dependencies = [
- 'typed', 'config', 'abs', 'add', 'addScalar', 'matrix', 'multiply', 'multiplyScalar', 'divideScalar', 'subtract', 'smaller', 'equalScalar', 'flatten', 'isZero', 'isNumeric'
+ 'typed', 'abs', 'add', 'addScalar', 'matrix',
+ 'multiply', 'multiplyScalar', 'divideScalar', 'subtract',
+ 'smaller', 'equalScalar', 'flatten', 'isZero', 'isNumeric'
]
-export const createIntersect = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, abs, add, addScalar, matrix, multiply, multiplyScalar, divideScalar, subtract, smaller, equalScalar, flatten, isZero, isNumeric }) => {
+export const createIntersect = /* #__PURE__ */ factory(name, dependencies, ({
+ typed, abs, add, addScalar, matrix,
+ multiply, multiplyScalar, divideScalar, subtract,
+ smaller, equalScalar, flatten, isZero, isNumeric
+}) => {
/**
- * Calculates the point of intersection of two lines in two or three dimensions
- * and of a line and a plane in three dimensions. The inputs are in the form of
- * arrays or 1 dimensional matrices. The line intersection functions return null
- * if the lines do not meet.
+ * Calculates the point of intersection of two lines in two or three
+ * dimensions and of a line and a plane in three dimensions. The inputs are
+ * in the form of arrays or 1 dimensional matrices. The line intersection
+ * functions return null if the lines do not meet.
*
- * Note: Fill the plane coefficients as `x + y + z = c` and not as `x + y + z + c = 0`.
+ * Note: Fill the plane coefficients as `x + y + z = c` and not as
+ * `x + y + z + c = 0`.
*
* Syntax:
*
@@ -119,9 +126,7 @@ export const createIntersect = /* #__PURE__ */ factory(name, dependencies, ({ ty
const d2 = subtract(o2, p2b)
const det = subtract(multiplyScalar(d1[0], d2[1]), multiplyScalar(d2[0], d1[1]))
if (isZero(det)) return null
- if (smaller(abs(det), config.relTol)) {
- return null
- }
+
const d20o11 = multiplyScalar(d2[0], o1[1])
const d21o10 = multiplyScalar(d2[1], o1[0])
const d20o21 = multiplyScalar(d2[0], o2[1])
diff --git a/src/function/matrix/column.js b/src/function/matrix/column.js
index ef5e6c9dc3..57b10da86b 100644
--- a/src/function/matrix/column.js
+++ b/src/function/matrix/column.js
@@ -53,9 +53,8 @@ export const createColumn = /* #__PURE__ */ factory(name, dependencies, ({ typed
const rowRange = range(0, value.size()[0])
const index = new Index(rowRange, [column])
const result = value.subset(index)
- // once config.legacySubset just return result
- return isMatrix(result)
- ? result
- : matrix([[result]])
+ // Once config.compatibility.subset is discontinued, we will be able
+ // just to return the result:
+ return isMatrix(result) ? result : matrix([[result]])
}
})
diff --git a/src/function/matrix/eigs.js b/src/function/matrix/eigs.js
index deed883971..6b5402abbe 100644
--- a/src/function/matrix/eigs.js
+++ b/src/function/matrix/eigs.js
@@ -100,7 +100,7 @@ export const createEigs = /* #__PURE__ */ factory(name, dependencies, ({ config,
function doEigs (mat, opts = {}) {
const computeVectors = 'eigenvectors' in opts ? opts.eigenvectors : true
- const prec = opts.precision ?? config.relTol
+ const prec = opts.precision ?? config.compute.defaultRelTol
const result = computeValuesAndVectors(mat, prec, computeVectors)
if (opts.matricize) {
result.values = matrix(result.values)
diff --git a/src/function/matrix/eigs/realSymmetric.js b/src/function/matrix/eigs/realSymmetric.js
index 2e44e98866..d37d64913c 100644
--- a/src/function/matrix/eigs/realSymmetric.js
+++ b/src/function/matrix/eigs/realSymmetric.js
@@ -7,7 +7,9 @@ export function createRealSymmetric ({ config, addScalar, subtract, abs, atan, c
* @param {number} prec
* @param {'number' | 'BigNumber'} type
*/
- function main (arr, N, prec = config.relTol, type, computeVectors) {
+ function main (
+ arr, N, prec = config.compute.defaultRelTol, type, computeVectors
+ ) {
if (type === 'number') {
return diag(arr, prec, computeVectors)
}
@@ -85,7 +87,7 @@ export function createRealSymmetric ({ config, addScalar, subtract, abs, atan, c
// get angle
function getTheta (aii, ajj, aij) {
const denom = (ajj - aii)
- if (Math.abs(denom) <= config.relTol) {
+ if (Math.abs(denom) <= config.compute.defaultRelTol) {
return Math.PI / 4.0
} else {
return 0.5 * Math.atan(2.0 * aij / (ajj - aii))
@@ -95,7 +97,7 @@ export function createRealSymmetric ({ config, addScalar, subtract, abs, atan, c
// get angle
function getThetaBig (aii, ajj, aij) {
const denom = subtract(ajj, aii)
- if (abs(denom) <= config.relTol) {
+ if (abs(denom) <= config.compute.defaultRelTol) {
return bignumber(-1).acos().div(4)
} else {
return multiplyScalar(0.5, atan(multiply(2.0, aij, inv(denom))))
diff --git a/src/function/matrix/identity.js b/src/function/matrix/identity.js
index 5ee1cf0bc6..f527d0c100 100644
--- a/src/function/matrix/identity.js
+++ b/src/function/matrix/identity.js
@@ -14,6 +14,9 @@ const dependencies = [
]
export const createIdentity = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, matrix, BigNumber, DenseMatrix, SparseMatrix }) => {
+ function useMatrix (config) {
+ return config.compute.Matrix.defaultType === 'Matrix'
+ }
/**
* Create a 2-dimensional identity matrix with size m x n or n x n.
* The matrix has ones on the diagonal and zeros elsewhere.
@@ -46,7 +49,7 @@ export const createIdentity = /* #__PURE__ */ factory(name, dependencies, ({ typ
*/
return typed(name, {
'': function () {
- return (config.matrix === 'Matrix') ? matrix([]) : []
+ return useMatrix(config) ? matrix([]) : []
},
string: function (format) {
@@ -54,7 +57,7 @@ export const createIdentity = /* #__PURE__ */ factory(name, dependencies, ({ typ
},
'number | BigNumber': function (rows) {
- return _identity(rows, rows, config.matrix === 'Matrix' ? 'dense' : undefined)
+ return _identity(rows, rows, useMatrix(config) ? 'dense' : undefined)
},
'number | BigNumber, string': function (rows, format) {
@@ -62,7 +65,7 @@ export const createIdentity = /* #__PURE__ */ factory(name, dependencies, ({ typ
},
'number | BigNumber, number | BigNumber': function (rows, cols) {
- return _identity(rows, cols, config.matrix === 'Matrix' ? 'dense' : undefined)
+ return _identity(rows, cols, useMatrix(config) ? 'dense' : undefined)
},
'number | BigNumber, number | BigNumber, string': function (rows, cols, format) {
diff --git a/src/function/matrix/ones.js b/src/function/matrix/ones.js
index 5bd55b7719..5f55fcfe3e 100644
--- a/src/function/matrix/ones.js
+++ b/src/function/matrix/ones.js
@@ -43,7 +43,7 @@ export const createOnes = /* #__PURE__ */ factory(name, dependencies, ({ typed,
*/
return typed('ones', {
'': function () {
- return (config.matrix === 'Array')
+ return (config.compute.Matrix.defaultType === 'Array')
? _ones([])
: _ones([], 'default')
},
@@ -55,7 +55,7 @@ export const createOnes = /* #__PURE__ */ factory(name, dependencies, ({ typed,
if (typeof last === 'string') {
const format = size.pop()
return _ones(size, format)
- } else if (config.matrix === 'Array') {
+ } else if (config.compute.Matrix.defaultType === 'Array') {
return _ones(size)
} else {
return _ones(size, 'default')
diff --git a/src/function/matrix/range.js b/src/function/matrix/range.js
index d919eeb76a..03ed9f2666 100644
--- a/src/function/matrix/range.js
+++ b/src/function/matrix/range.js
@@ -35,7 +35,8 @@ export const createRange = /* #__PURE__ */ factory(name, dependencies, ({ typed,
* Option to specify whether to include the end or not. False by default.
*
* The function returns a `DenseMatrix` when the library is configured with
- * `config = { matrix: 'Matrix' }, and returns an Array otherwise.
+ * `config = {compute: {Matrix: {defaultType: 'Matrix'}}}, and returns
+ * an Array otherwise.
* Note that the type of the returned values is taken from the type of the
* provided start/end value. If only one of these is a built-in `number` type,
* it will be promoted to the type of the other endpoint. However, in the case
@@ -151,7 +152,7 @@ export const createRange = /* #__PURE__ */ factory(name, dependencies, ({ typed,
})
function _out (arr) {
- if (config.matrix === 'Matrix') {
+ if (config.compute.Matrix.defaultType === 'Matrix') {
return matrix ? matrix(arr) : noMatrix()
}
@@ -164,7 +165,7 @@ export const createRange = /* #__PURE__ */ factory(name, dependencies, ({ typed,
throw new SyntaxError('String "' + str + '" is no valid range')
}
- if (config.number === 'BigNumber') {
+ if (config.number === 'BigNumber') { // TODO: other number types ??
if (bignumber === undefined) {
noBignumber()
}
diff --git a/src/function/matrix/resize.js b/src/function/matrix/resize.js
index 3f28a91377..8e3a959267 100644
--- a/src/function/matrix/resize.js
+++ b/src/function/matrix/resize.js
@@ -66,7 +66,9 @@ export const createResize = /* #__PURE__ */ factory(name, dependencies, ({ confi
}
// check result should be a matrix
- const asMatrix = Array.isArray(x) ? false : (config.matrix !== 'Array')
+ const asMatrix = Array.isArray(x)
+ ? false
+ : (config.compute.Matrix.defaultType !== 'Array')
if (size.length === 0) {
// output a scalar
diff --git a/src/function/matrix/rotationMatrix.js b/src/function/matrix/rotationMatrix.js
index 55bebcbdeb..200b1ae4f9 100644
--- a/src/function/matrix/rotationMatrix.js
+++ b/src/function/matrix/rotationMatrix.js
@@ -56,9 +56,13 @@ export const createRotationMatrix = /* #__PURE__ */ factory(name, dependencies,
* @return {Array | Matrix} Rotation matrix
*/
+ function useMatrix (config) {
+ return config.compute.Matrix.defaultType === 'Matrix'
+ }
+
return typed(name, {
'': function () {
- return (config.matrix === 'Matrix') ? matrix([]) : []
+ return useMatrix(config) ? matrix([]) : []
},
string: function (format) {
@@ -66,7 +70,7 @@ export const createRotationMatrix = /* #__PURE__ */ factory(name, dependencies,
},
'number | BigNumber | Complex | Unit': function (theta) {
- return _rotationMatrix2x2(theta, config.matrix === 'Matrix' ? 'dense' : undefined)
+ return _rotationMatrix2x2(theta, useMatrix(config) ? 'dense' : undefined)
},
'number | BigNumber | Complex | Unit, string': function (theta, format) {
@@ -81,7 +85,8 @@ export const createRotationMatrix = /* #__PURE__ */ factory(name, dependencies,
'number | BigNumber | Complex | Unit, Matrix': function (theta, v) {
_validateVector(v)
- const storageType = v.storage() || (config.matrix === 'Matrix' ? 'dense' : undefined)
+ const storageType = v.storage() ||
+ (useMatrix(config) ? 'dense' : undefined)
return _rotationMatrix3x3(theta, v, storageType)
},
@@ -136,7 +141,7 @@ export const createRotationMatrix = /* #__PURE__ */ factory(name, dependencies,
if (format === 'dense') {
return new DenseMatrix(data)
}
- throw new TypeError(`Unknown matrix type "${format}"`)
+ throw new TypeError(`Unsupported matrix type "${format}"`)
}
return data
}
diff --git a/src/function/matrix/row.js b/src/function/matrix/row.js
index 5e99229404..9ba8f9afdc 100644
--- a/src/function/matrix/row.js
+++ b/src/function/matrix/row.js
@@ -53,9 +53,8 @@ export const createRow = /* #__PURE__ */ factory(name, dependencies, ({ typed, I
const columnRange = range(0, value.size()[1])
const index = new Index([row], columnRange)
const result = value.subset(index)
- // once config.legacySubset just return result
- return isMatrix(result)
- ? result
- : matrix([[result]])
+ // Once config.compatibility.subset is discontinued, we will be able
+ // just to return the result:
+ return isMatrix(result) ? result : matrix([[result]])
}
})
diff --git a/src/function/matrix/subset.js b/src/function/matrix/subset.js
index 8ca59e0523..3e44ece228 100644
--- a/src/function/matrix/subset.js
+++ b/src/function/matrix/subset.js
@@ -8,7 +8,9 @@ import { factory } from '../../utils/factory.js'
const name = 'subset'
const dependencies = ['typed', 'matrix', 'zeros', 'add']
-export const createSubset = /* #__PURE__ */ factory(name, dependencies, ({ typed, matrix, zeros, add }) => {
+export const createSubset = /* #__PURE__ */ factory(name, dependencies, ({
+ typed, matrix, zeros, add
+}) => {
/**
* Get or set a subset of a matrix or string.
*
diff --git a/src/function/matrix/zeros.js b/src/function/matrix/zeros.js
index 95f5d79129..62a43b1793 100644
--- a/src/function/matrix/zeros.js
+++ b/src/function/matrix/zeros.js
@@ -41,7 +41,7 @@ export const createZeros = /* #__PURE__ */ factory(name, dependencies, ({ typed,
*/
return typed(name, {
'': function () {
- return (config.matrix === 'Array')
+ return (config.compute.Matrix.defaultType === 'Array')
? _zeros([])
: _zeros([], 'default')
},
@@ -53,7 +53,7 @@ export const createZeros = /* #__PURE__ */ factory(name, dependencies, ({ typed,
if (typeof last === 'string') {
const format = size.pop()
return _zeros(size, format)
- } else if (config.matrix === 'Array') {
+ } else if (config.compute.Matrix.defaultType === 'Array') {
return _zeros(size)
} else {
return _zeros(size, 'default')
diff --git a/src/function/probability/bernoulli.js b/src/function/probability/bernoulli.js
index e591ee1fd0..5224ea78fc 100644
--- a/src/function/probability/bernoulli.js
+++ b/src/function/probability/bernoulli.js
@@ -48,9 +48,9 @@ export const createBernoulli = /* #__PURE__ */ factory(name, dependencies, ({
number(index), n => new Fraction(n), fractionCache,
(a, b) => a.add(b), (a, b) => a.mul(b), (a, b) => a.div(b)),
BigNumber: index => {
- if (config.precision !== cachedPrecision) {
+ if (config.compute.BigNumber.precision !== cachedPrecision) {
bigCache = [undefined]
- cachedPrecision = config.precision
+ cachedPrecision = config.compute.BigNumber.precision
}
return _bernoulli(
number(index), n => new BigNumber(n), bigCache,
diff --git a/src/function/probability/gamma.js b/src/function/probability/gamma.js
index 2fb37729b6..b9de1bd5fb 100644
--- a/src/function/probability/gamma.js
+++ b/src/function/probability/gamma.js
@@ -100,7 +100,8 @@ export const createGamma = /* #__PURE__ */ factory(name, dependencies, ({ typed,
return new BigNumber([1, 1, 2, 6, 24, 120, 720, 5040][n])
}
- const precision = config.precision + (Math.log(n.toNumber()) | 0)
+ const precision = config.compute.BigNumber.precision +
+ (Math.log(n.toNumber()) | 0)
const Big = BigNumber.clone({ precision })
if (n % 2 === 1) {
diff --git a/src/function/probability/pickRandom.js b/src/function/probability/pickRandom.js
index 3897ed72fc..a90f8a7391 100644
--- a/src/function/probability/pickRandom.js
+++ b/src/function/probability/pickRandom.js
@@ -8,12 +8,12 @@ const dependencies = ['typed', 'config', '?on']
export const createPickRandom = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, on }) => {
// seeded pseudo random number generator
- let rng = createRng(config.randomSeed)
+ let rng = createRng(config.compute.randomSeed)
if (on) {
on('config', function (curr, prev) {
- if (curr.randomSeed !== prev.randomSeed) {
- rng = createRng(curr.randomSeed)
+ if (curr.compute.randomSeed !== prev.compute.randomSeed) {
+ rng = createRng(curr.compute.randomSeed)
}
})
}
diff --git a/src/function/probability/random.js b/src/function/probability/random.js
index 8fbb69588a..6a9ba0cbd5 100644
--- a/src/function/probability/random.js
+++ b/src/function/probability/random.js
@@ -8,12 +8,12 @@ const dependencies = ['typed', 'config', '?on']
export const createRandom = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, on }) => {
// seeded pseudo random number generator
- let rng = createRng(config.randomSeed)
+ let rng = createRng(config.compute.randomSeed)
if (on) {
on('config', function (curr, prev) {
- if (curr.randomSeed !== prev.randomSeed) {
- rng = createRng(curr.randomSeed)
+ if (curr.compute.randomSeed !== prev.compute.randomSeed) {
+ rng = createRng(curr.compute.randomSeed)
}
})
}
@@ -71,12 +71,12 @@ export const createRandom = /* #__PURE__ */ factory(name, dependencies, ({ typed
// TODO: there is quite some duplicate code in both createRandom and createRandomNumber, can we improve that?
export const createRandomNumber = /* #__PURE__ */ factory(name, ['typed', 'config', '?on'], ({ typed, config, on, matrix }) => {
// seeded pseudo random number generator1
- let rng = createRng(config.randomSeed)
+ let rng = createRng(config.compute.randomSeed)
if (on) {
on('config', function (curr, prev) {
- if (curr.randomSeed !== prev.randomSeed) {
- rng = createRng(curr.randomSeed)
+ if (curr.compute.randomSeed !== prev.compute.randomSeed) {
+ rng = createRng(curr.compute.randomSeed)
}
})
}
diff --git a/src/function/probability/randomInt.js b/src/function/probability/randomInt.js
index 06cb95897e..b3740d0cde 100644
--- a/src/function/probability/randomInt.js
+++ b/src/function/probability/randomInt.js
@@ -8,12 +8,12 @@ const dependencies = ['typed', 'config', 'log2', '?on']
export const createRandomInt = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, log2, on }) => {
// seeded pseudo random number generator
- let rng = createRng(config.randomSeed)
+ let rng = createRng(config.compute.randomSeed)
if (on) {
on('config', function (curr, prev) {
- if (curr.randomSeed !== prev.randomSeed) {
- rng = createRng(curr.randomSeed)
+ if (curr.compute.randomSeed !== prev.compute.randomSeed) {
+ rng = createRng(curr.compute.randomSeed)
}
})
}
diff --git a/src/function/relational/compare.js b/src/function/relational/compare.js
index 39886c3920..84792a995d 100644
--- a/src/function/relational/compare.js
+++ b/src/function/relational/compare.js
@@ -15,25 +15,27 @@ const dependencies = [
'equalScalar',
'BigNumber',
'Fraction',
- 'DenseMatrix',
- 'concat'
+ 'DenseMatrix'
]
-export const createCompare = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, equalScalar, matrix, BigNumber, Fraction, DenseMatrix, concat }) => {
+export const createCompare = /* #__PURE__ */ factory(name, dependencies, ({
+ typed, config, equalScalar, matrix, BigNumber, Fraction, DenseMatrix, concat
+}) => {
const matAlgo03xDSf = createMatAlgo03xDSf({ typed })
const matAlgo05xSfSf = createMatAlgo05xSfSf({ typed, equalScalar })
const matAlgo12xSfs = createMatAlgo12xSfs({ typed, DenseMatrix })
- const matrixAlgorithmSuite = createMatrixAlgorithmSuite({ typed, matrix, concat })
+ const matrixAlgorithmSuite = createMatrixAlgorithmSuite({ typed, matrix })
const compareUnits = createCompareUnits({ typed })
/**
* Compare two values. Returns 1 when x > y, -1 when x < y, and 0 when x == y.
*
* x and y are considered equal when the relative difference between x and y
- * is smaller than the configured absTol and relTol. The function cannot be used to
- * compare values smaller than approximately 2.22e-16.
+ * is smaller than the configured absTol and relTol. With the default
+ * settings, this function cannot be used to compare values smaller than
+ * approximately 2.22e-16.
*
- * For matrices, the function is evaluated element wise.
+ * For matrices, the function is evaluated element-wise.
* Strings are compared by their numerical value.
*
* Syntax:
@@ -72,7 +74,8 @@ export const createCompare = /* #__PURE__ */ factory(name, dependencies, ({ type
},
'BigNumber, BigNumber': function (x, y) {
- return bigNearlyEqual(x, y, config.relTol, config.absTol)
+ const opts = config.compute
+ return bigNearlyEqual(x, y, opts.defaultRelTol, config.defaultAbsTol)
? new BigNumber(0)
: new BigNumber(x.cmp(y))
},
@@ -101,7 +104,8 @@ export const createCompare = /* #__PURE__ */ factory(name, dependencies, ({ type
export const createCompareNumber = /* #__PURE__ */ factory(name, ['typed', 'config'], ({ typed, config }) => {
return typed(name, {
'number, number': function (x, y) {
- return nearlyEqual(x, y, config.relTol, config.absTol)
+ const opts = config.compute
+ return nearlyEqual(x, y, opts.defaultRelTol, opts.defaultAbsTol)
? 0
: (x > y ? 1 : -1)
}
diff --git a/src/function/relational/equalScalar.js b/src/function/relational/equalScalar.js
index eea6881e4d..a0a24d45b8 100644
--- a/src/function/relational/equalScalar.js
+++ b/src/function/relational/equalScalar.js
@@ -25,11 +25,13 @@ export const createEqualScalar = /* #__PURE__ */ factory(name, dependencies, ({
},
'number, number': function (x, y) {
- return nearlyEqual(x, y, config.relTol, config.absTol)
+ return nearlyEqual(
+ x, y, config.compute.defaultRelTol, config.compute.defaultAbsTol)
},
'BigNumber, BigNumber': function (x, y) {
- return x.eq(y) || bigNearlyEqual(x, y, config.relTol, config.absTol)
+ return x.eq(y) || bigNearlyEqual(
+ x, y, config.compute.defaultRelTol, config.compute.defaultAbsTol)
},
'bigint, bigint': function (x, y) {
@@ -41,7 +43,8 @@ export const createEqualScalar = /* #__PURE__ */ factory(name, dependencies, ({
},
'Complex, Complex': function (x, y) {
- return complexEquals(x, y, config.relTol, config.absTol)
+ return complexEquals(
+ x, y, config.compute.defaultRelTol, config.compute.defaultAbsTol)
}
}, compareUnits)
})
@@ -49,7 +52,8 @@ export const createEqualScalar = /* #__PURE__ */ factory(name, dependencies, ({
export const createEqualScalarNumber = factory(name, ['typed', 'config'], ({ typed, config }) => {
return typed(name, {
'number, number': function (x, y) {
- return nearlyEqual(x, y, config.relTol, config.absTol)
+ return nearlyEqual(
+ x, y, config.compute.defaultRelTol, config.compute.defaultAbsTol)
}
})
})
diff --git a/src/function/relational/larger.js b/src/function/relational/larger.js
index 8507d21511..33e42760d3 100644
--- a/src/function/relational/larger.js
+++ b/src/function/relational/larger.js
@@ -57,7 +57,8 @@ export const createLarger = /* #__PURE__ */ factory(name, dependencies, ({ typed
* @return {boolean | Array | Matrix} Returns true when the x is larger than y, else returns false
*/
function bignumLarger (x, y) {
- return x.gt(y) && !bigNearlyEqual(x, y, config.relTol, config.absTol)
+ return x.gt(y) && !bigNearlyEqual(
+ x, y, config.compute.defaultRelTol, config.compute.defaultAbsTol)
}
return typed(
@@ -96,7 +97,8 @@ export const createLarger = /* #__PURE__ */ factory(name, dependencies, ({ typed
export const createLargerNumber = /* #__PURE__ */ factory(name, ['typed', 'config'], ({ typed, config }) => {
return typed(name, {
'number, number': function (x, y) {
- return x > y && !nearlyEqual(x, y, config.relTol, config.absTol)
+ return x > y && !nearlyEqual(
+ x, y, config.compute.defaultRelTol, config.compute.defaultAbsTol)
}
})
})
diff --git a/src/function/relational/largerEq.js b/src/function/relational/largerEq.js
index 6760df7f6c..2080465de3 100644
--- a/src/function/relational/largerEq.js
+++ b/src/function/relational/largerEq.js
@@ -58,7 +58,8 @@ export const createLargerEq = /* #__PURE__ */ factory(name, dependencies, ({ typ
'boolean, boolean': (x, y) => x >= y,
'BigNumber, BigNumber': function (x, y) {
- return x.gte(y) || bigNearlyEqual(x, y, config.relTol, config.absTol)
+ return x.gte(y) || bigNearlyEqual(
+ x, y, config.compute.defaultRelTol, config.compute.defaultAbsTol)
},
'bigint, bigint': function (x, y) {
@@ -83,7 +84,8 @@ export const createLargerEq = /* #__PURE__ */ factory(name, dependencies, ({ typ
export const createLargerEqNumber = /* #__PURE__ */ factory(name, ['typed', 'config'], ({ typed, config }) => {
return typed(name, {
'number, number': function (x, y) {
- return x >= y || nearlyEqual(x, y, config.relTol, config.absTol)
+ return x >= y || nearlyEqual(
+ x, y, config.compute.defaultRelTol, config.compute.defaultAbsTol)
}
})
})
diff --git a/src/function/relational/smaller.js b/src/function/relational/smaller.js
index 87807f0240..bfbf7a1b61 100644
--- a/src/function/relational/smaller.js
+++ b/src/function/relational/smaller.js
@@ -57,7 +57,8 @@ export const createSmaller = /* #__PURE__ */ factory(name, dependencies, ({ type
* @return {boolean | Array | Matrix} Returns true when the x is smaller than y, else returns false
*/
function bignumSmaller (x, y) {
- return x.lt(y) && !bigNearlyEqual(x, y, config.relTol, config.absTol)
+ return x.lt(y) && !bigNearlyEqual(
+ x, y, config.compute.defaultRelTol, config.compute.defaultAbsTol)
}
return typed(
@@ -96,7 +97,8 @@ export const createSmaller = /* #__PURE__ */ factory(name, dependencies, ({ type
export const createSmallerNumber = /* #__PURE__ */ factory(name, ['typed', 'config'], ({ typed, config }) => {
return typed(name, {
'number, number': function (x, y) {
- return x < y && !nearlyEqual(x, y, config.relTol, config.absTol)
+ return x < y && !nearlyEqual(
+ x, y, config.compute.defaultRelTol, config.compute.defaultAbsTol)
}
})
})
diff --git a/src/function/relational/smallerEq.js b/src/function/relational/smallerEq.js
index b314418a4c..dae2aa8f82 100644
--- a/src/function/relational/smallerEq.js
+++ b/src/function/relational/smallerEq.js
@@ -58,7 +58,8 @@ export const createSmallerEq = /* #__PURE__ */ factory(name, dependencies, ({ ty
'boolean, boolean': (x, y) => (x <= y),
'BigNumber, BigNumber': function (x, y) {
- return x.lte(y) || bigNearlyEqual(x, y, config.relTol, config.absTol)
+ return x.lte(y) || bigNearlyEqual(
+ x, y, config.compute.defaultRelTol, config.compute.defaultAbsTol)
},
'bigint, bigint': (x, y) => (x <= y),
@@ -81,7 +82,8 @@ export const createSmallerEq = /* #__PURE__ */ factory(name, dependencies, ({ ty
export const createSmallerEqNumber = /* #__PURE__ */ factory(name, ['typed', 'config'], ({ typed, config }) => {
return typed(name, {
'number, number': function (x, y) {
- return x <= y || nearlyEqual(x, y, config.relTol, config.absTol)
+ return x <= y || nearlyEqual(
+ x, y, config.compute.defaultRelTol, config.compute.defaultAbsTol)
}
})
})
diff --git a/src/function/special/zeta.js b/src/function/special/zeta.js
index 303026601d..c34b128923 100644
--- a/src/function/special/zeta.js
+++ b/src/function/special/zeta.js
@@ -38,7 +38,7 @@ export const createZeta = /* #__PURE__ */ factory(name, dependencies, ({ typed,
value => new BigNumber(value),
() => {
// relTol is for example 1e-12. Extract the positive exponent 12 from that
- return Math.abs(Math.log10(config.relTol))
+ return Math.abs(Math.log10(config.compute.defaultRelTol))
}
),
Complex: zetaComplex
diff --git a/src/function/statistics/max.js b/src/function/statistics/max.js
index bc1c1b988e..8b333b9e59 100644
--- a/src/function/statistics/max.js
+++ b/src/function/statistics/max.js
@@ -1,12 +1,15 @@
import { deepForEach, reduce, containsCollections } from '../../utils/collection.js'
import { factory } from '../../utils/factory.js'
-import { safeNumberType } from '../../utils/number.js'
import { improveErrorMessage } from './utils/improveErrorMessage.js'
+import { createNumericPassthru } from './utils/numericPassthru.js'
const name = 'max'
const dependencies = ['typed', 'config', 'numeric', 'larger', 'isNaN']
-export const createMax = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, numeric, larger, isNaN: mathIsNaN }) => {
+export const createMax = /* #__PURE__ */ factory(name, dependencies, ({
+ typed, config, numeric, larger, isNaN: mathIsNaN
+}) => {
+ const passthru = createNumericPassthru({ typed })
/**
* Compute the maximum value of a matrix or a list with values.
* In case of a multidimensional array, the maximum of the flattened array
@@ -38,7 +41,7 @@ export const createMax = /* #__PURE__ */ factory(name, dependencies, ({ typed, c
* @param {... *} args A single matrix or or multiple scalar values
* @return {*} The maximum value
*/
- return typed(name, {
+ return typed(name, passthru, {
// max([a, b, c, d, ...])
'Array | Matrix': _max,
@@ -94,14 +97,9 @@ export const createMax = /* #__PURE__ */ factory(name, dependencies, ({ typed, c
})
if (res === undefined) {
- throw new Error('Cannot calculate max of an empty array')
+ // Not all types have Infinity, so have to use numberApproximate:
+ return numeric(-Infinity, config.compute.numberApproximate)
}
-
- // make sure returning numeric value: parse a string into a numeric value
- if (typeof res === 'string') {
- res = numeric(res, safeNumberType(res, config))
- }
-
- return res
+ return passthru(res)
}
})
diff --git a/src/function/statistics/min.js b/src/function/statistics/min.js
index 962246a208..52c9a11ab6 100644
--- a/src/function/statistics/min.js
+++ b/src/function/statistics/min.js
@@ -1,12 +1,15 @@
import { containsCollections, deepForEach, reduce } from '../../utils/collection.js'
import { factory } from '../../utils/factory.js'
-import { safeNumberType } from '../../utils/number.js'
import { improveErrorMessage } from './utils/improveErrorMessage.js'
+import { createNumericPassthru } from './utils/numericPassthru.js'
const name = 'min'
const dependencies = ['typed', 'config', 'numeric', 'smaller', 'isNaN']
-export const createMin = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, numeric, smaller, isNaN: mathIsNaN }) => {
+export const createMin = /* #__PURE__ */ factory(name, dependencies, ({
+ typed, config, numeric, smaller, isNaN: mathIsNaN
+}) => {
+ const passthru = createNumericPassthru({ typed })
/**
* Compute the minimum value of a matrix or a list of values.
* In case of a multidimensional array, the minimum of the flattened array
@@ -38,7 +41,7 @@ export const createMin = /* #__PURE__ */ factory(name, dependencies, ({ typed, c
* @param {... *} args A single matrix or or multiple scalar values
* @return {*} The minimum value
*/
- return typed(name, {
+ return typed(name, passthru, {
// min([a, b, c, d, ...])
'Array | Matrix': _min,
@@ -94,14 +97,10 @@ export const createMin = /* #__PURE__ */ factory(name, dependencies, ({ typed, c
})
if (min === undefined) {
- throw new Error('Cannot calculate min of an empty array')
+ // Not all types have Infinity, so have to use numberApproximate:
+ return numeric(Infinity, config.compute.numberApproximate)
}
- // make sure returning numeric value: parse a string into a numeric value
- if (typeof min === 'string') {
- min = numeric(min, safeNumberType(min, config))
- }
-
- return min
+ return passthru(min)
}
})
diff --git a/src/function/statistics/prod.js b/src/function/statistics/prod.js
index 1a5ba84072..c87776df5b 100644
--- a/src/function/statistics/prod.js
+++ b/src/function/statistics/prod.js
@@ -1,12 +1,15 @@
import { deepForEach } from '../../utils/collection.js'
import { factory } from '../../utils/factory.js'
-import { safeNumberType } from '../../utils/number.js'
import { improveErrorMessage } from './utils/improveErrorMessage.js'
+import { createNumericPassthru } from './utils/numericPassthru.js'
const name = 'prod'
const dependencies = ['typed', 'config', 'multiplyScalar', 'numeric']
-export const createProd = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, multiplyScalar, numeric }) => {
+export const createProd = /* #__PURE__ */ factory(name, dependencies, ({
+ typed, config, multiplyScalar, numeric
+}) => {
+ const passthru = createNumericPassthru({ typed })
/**
* Compute the product of a matrix or a list with values.
* In case of a multidimensional array or matrix, the sum of all
@@ -32,7 +35,7 @@ export const createProd = /* #__PURE__ */ factory(name, dependencies, ({ typed,
* @param {... *} args A single matrix or or multiple scalar values
* @return {*} The product of all values
*/
- return typed(name, {
+ return typed(name, passthru, {
// prod([a, b, c, d, ...])
'Array | Matrix': _prod,
@@ -66,15 +69,11 @@ export const createProd = /* #__PURE__ */ factory(name, dependencies, ({ typed,
}
})
- // make sure returning numeric value: parse a string into a numeric value
- if (typeof prod === 'string') {
- prod = numeric(prod, safeNumberType(prod, config))
- }
-
if (prod === undefined) {
- throw new Error('Cannot calculate prod of an empty array')
+ // Note 1 can be expressed in any number type
+ return numeric(1, config.number)
}
- return prod
+ return passthru(prod)
}
})
diff --git a/src/function/statistics/sum.js b/src/function/statistics/sum.js
index 5973d19e74..6c44f84fbd 100644
--- a/src/function/statistics/sum.js
+++ b/src/function/statistics/sum.js
@@ -1,12 +1,15 @@
import { containsCollections, deepForEach, reduce } from '../../utils/collection.js'
import { factory } from '../../utils/factory.js'
-import { safeNumberType } from '../../utils/number.js'
import { improveErrorMessage } from './utils/improveErrorMessage.js'
+import { createNumericPassthru } from './utils/numericPassthru.js'
const name = 'sum'
const dependencies = ['typed', 'config', 'add', 'numeric']
-export const createSum = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, add, numeric }) => {
+export const createSum = /* #__PURE__ */ factory(name, dependencies, ({
+ typed, config, add, numeric
+}) => {
+ const passthru = createNumericPassthru({ typed })
/**
* Compute the sum of a matrix or a list with values.
* In case of a multidimensional array or matrix, the sum of all
@@ -31,7 +34,7 @@ export const createSum = /* #__PURE__ */ factory(name, dependencies, ({ typed, c
* @param {... *} args A single matrix or multiple scalar values
* @return {*} The sum of all values
*/
- return typed(name, {
+ return typed(name, passthru, {
// sum([a, b, c, d, ...])
'Array | Matrix': _sum,
@@ -65,15 +68,12 @@ export const createSum = /* #__PURE__ */ factory(name, dependencies, ({ typed, c
}
})
- // make sure returning numeric value: parse a string into a numeric value
if (sum === undefined) {
+ // Note any number type can represent zero
sum = numeric(0, config.number)
}
- if (typeof sum === 'string') {
- sum = numeric(sum, safeNumberType(sum, config))
- }
- return sum
+ return passthru(sum)
}
function _nsumDim (array, dim) {
diff --git a/src/function/statistics/utils/numericPassthru.js b/src/function/statistics/utils/numericPassthru.js
new file mode 100644
index 0000000000..b6d1995975
--- /dev/null
+++ b/src/function/statistics/utils/numericPassthru.js
@@ -0,0 +1,10 @@
+import { factory } from '../../../utils/factory.js'
+
+const name = 'numericPassthru'
+const dependencies = ['typed']
+
+export const createNumericPassthru = factory(name, dependencies, ({ typed }) => {
+ return typed(name, {
+ 'number|BigNumber|Complex|Fraction|bigint|Unit': x => x // did I miss any?
+ })
+})
diff --git a/src/function/trigonometry/acos.js b/src/function/trigonometry/acos.js
index 19b3f8ce5a..ce61b64117 100644
--- a/src/function/trigonometry/acos.js
+++ b/src/function/trigonometry/acos.js
@@ -30,7 +30,7 @@ export const createAcos = /* #__PURE__ */ factory(name, dependencies, ({ typed,
*/
return typed(name, {
number: function (x) {
- if ((x >= -1 && x <= 1) || config.predictable) {
+ if ((x >= -1 && x <= 1) || config.compute.uniformType) {
return Math.acos(x)
} else {
return new Complex(x, 0).acos()
@@ -42,6 +42,9 @@ export const createAcos = /* #__PURE__ */ factory(name, dependencies, ({ typed,
},
BigNumber: function (x) {
+ if ((x.lessThan(-1) || x.greaterThan(1)) && !config.compute.uniformType) {
+ return new Complex(x.toNumber(), 0).acos()
+ }
return x.acos()
}
})
diff --git a/src/function/trigonometry/acosh.js b/src/function/trigonometry/acosh.js
index 7340d911cd..fbaeed3300 100644
--- a/src/function/trigonometry/acosh.js
+++ b/src/function/trigonometry/acosh.js
@@ -28,7 +28,7 @@ export const createAcosh = /* #__PURE__ */ factory(name, dependencies, ({ typed,
*/
return typed(name, {
number: function (x) {
- if (x >= 1 || config.predictable) {
+ if (x >= 1 || config.compute.uniformType) {
return acoshNumber(x)
}
if (x <= -1) {
@@ -42,7 +42,14 @@ export const createAcosh = /* #__PURE__ */ factory(name, dependencies, ({ typed,
},
BigNumber: function (x) {
- return x.acosh()
+ if (x.gte(1) || config.compute.uniformType) {
+ return x.acosh()
+ }
+ x = x.toNumber()
+ if (x <= -1) {
+ return new Complex(Math.log(Math.sqrt(x * x - 1) - x), Math.PI)
+ }
+ return new Complex(x, 0).acosh()
}
})
})
diff --git a/src/function/trigonometry/acoth.js b/src/function/trigonometry/acoth.js
index 76727de813..142548b375 100644
--- a/src/function/trigonometry/acoth.js
+++ b/src/function/trigonometry/acoth.js
@@ -29,7 +29,7 @@ export const createAcoth = /* #__PURE__ */ factory(name, dependencies, ({ typed,
*/
return typed(name, {
number: function (x) {
- if (x >= 1 || x <= -1 || config.predictable) {
+ if (x >= 1 || x <= -1 || config.compute.uniformType) {
return acothNumber(x)
}
return new Complex(x, 0).acoth()
@@ -40,6 +40,9 @@ export const createAcoth = /* #__PURE__ */ factory(name, dependencies, ({ typed,
},
BigNumber: function (x) {
+ if (x.greaterThan(-1) && x.lessThan(1) && !config.compute.uniformType) {
+ return new Complex(x.toNumber(), 0).acoth()
+ }
return new BigNumber(1).div(x).atanh()
}
})
diff --git a/src/function/trigonometry/acsc.js b/src/function/trigonometry/acsc.js
index e0dbb4cae9..8b2ad404a7 100644
--- a/src/function/trigonometry/acsc.js
+++ b/src/function/trigonometry/acsc.js
@@ -30,7 +30,7 @@ export const createAcsc = /* #__PURE__ */ factory(name, dependencies, ({ typed,
*/
return typed(name, {
number: function (x) {
- if (x <= -1 || x >= 1 || config.predictable) {
+ if (x <= -1 || x >= 1 || config.compute.uniformType) {
return acscNumber(x)
}
return new Complex(x, 0).acsc()
@@ -41,6 +41,9 @@ export const createAcsc = /* #__PURE__ */ factory(name, dependencies, ({ typed,
},
BigNumber: function (x) {
+ if (x.greaterThan(-1) && x.lessThan(1) && !config.compute.uniformType) {
+ return new Complex(x.toNumber(), 0).acsc()
+ }
return new BigNumber(1).div(x).asin()
}
})
diff --git a/src/function/trigonometry/asec.js b/src/function/trigonometry/asec.js
index ec802409cb..7cadb34735 100644
--- a/src/function/trigonometry/asec.js
+++ b/src/function/trigonometry/asec.js
@@ -31,7 +31,7 @@ export const createAsec = /* #__PURE__ */ factory(name, dependencies, ({ typed,
*/
return typed(name, {
number: function (x) {
- if (x <= -1 || x >= 1 || config.predictable) {
+ if (x <= -1 || x >= 1 || config.compute.uniformType) {
return asecNumber(x)
}
return new Complex(x, 0).asec()
@@ -42,6 +42,9 @@ export const createAsec = /* #__PURE__ */ factory(name, dependencies, ({ typed,
},
BigNumber: function (x) {
+ if (x.greaterThan(-1) && x.lessThan(1) && !config.compute.uniformType) {
+ return new Complex(x.toNumber(), 0).asec()
+ }
return new BigNumber(1).div(x).acos()
}
})
diff --git a/src/function/trigonometry/asech.js b/src/function/trigonometry/asech.js
index 9688adf370..1cebb1fb88 100644
--- a/src/function/trigonometry/asech.js
+++ b/src/function/trigonometry/asech.js
@@ -29,9 +29,10 @@ export const createAsech = /* #__PURE__ */ factory(name, dependencies, ({ typed,
*/
return typed(name, {
number: function (x) {
- if ((x <= 1 && x >= -1) || config.predictable) {
+ const predictable = config.compute.uniformType
+ if ((x <= 1 && x >= -1) || predictable) {
const xInv = 1 / x
- if (xInv > 0 || config.predictable) {
+ if (xInv > 0 || predictable) {
return asechNumber(x)
}
@@ -47,6 +48,9 @@ export const createAsech = /* #__PURE__ */ factory(name, dependencies, ({ typed,
},
BigNumber: function (x) {
+ if ((x.lessThan(0) || x.greaterThan(1)) && !config.compute.uniformType) {
+ return new Complex(x, 0).asech()
+ }
return new BigNumber(1).div(x).acosh()
}
})
diff --git a/src/function/trigonometry/asin.js b/src/function/trigonometry/asin.js
index 07a596d4c5..f46633110b 100644
--- a/src/function/trigonometry/asin.js
+++ b/src/function/trigonometry/asin.js
@@ -30,11 +30,10 @@ export const createAsin = /* #__PURE__ */ factory(name, dependencies, ({ typed,
*/
return typed(name, {
number: function (x) {
- if ((x >= -1 && x <= 1) || config.predictable) {
+ if ((x >= -1 && x <= 1) || config.compute.uniformType) {
return Math.asin(x)
- } else {
- return new Complex(x, 0).asin()
}
+ return new Complex(x, 0).asin()
},
Complex: function (x) {
@@ -42,6 +41,9 @@ export const createAsin = /* #__PURE__ */ factory(name, dependencies, ({ typed,
},
BigNumber: function (x) {
+ if ((x.lessThan(-1) || x.greaterThan(1)) && !config.compute.uniformType) {
+ return new Complex(x.toNumber(), 0).asin()
+ }
return x.asin()
}
})
diff --git a/src/function/trigonometry/atanh.js b/src/function/trigonometry/atanh.js
index f9eda776f1..6767b7295f 100644
--- a/src/function/trigonometry/atanh.js
+++ b/src/function/trigonometry/atanh.js
@@ -29,7 +29,7 @@ export const createAtanh = /* #__PURE__ */ factory(name, dependencies, ({ typed,
*/
return typed(name, {
number: function (x) {
- if ((x <= 1 && x >= -1) || config.predictable) {
+ if ((x <= 1 && x >= -1) || config.compute.uniformType) {
return atanhNumber(x)
}
return new Complex(x, 0).atanh()
@@ -40,6 +40,9 @@ export const createAtanh = /* #__PURE__ */ factory(name, dependencies, ({ typed,
},
BigNumber: function (x) {
+ if ((x.lessThan(-1) || x.greaterThan(1)) && !config.compute.uniformType) {
+ return new Complex(x.toNumber(), 0).atanh()
+ }
return x.atanh()
}
})
diff --git a/src/function/utils/isFinite.js b/src/function/utils/isFinite.js
index 57dd2b10f0..2d754fece3 100644
--- a/src/function/utils/isFinite.js
+++ b/src/function/utils/isFinite.js
@@ -34,7 +34,7 @@ export const createIsFinite = /* #__PURE__ */ factory(name, dependencies, ({
* isBounded isNumeric, isPositive, isNegative, isNaN
*
* @param {number | BigNumber | bigint | Complex | Fraction | Unit | Array | Matrix} x Value to be tested
- * @return {boolean | Array | Matrix}
+ * @return {boolean | Array | Matrix} Result(s) of finiteness test
*/
return typed(name, {
'Array | Matrix': A => map(A, isBounded),
diff --git a/src/function/utils/isNegative.js b/src/function/utils/isNegative.js
index 6b647674f5..3461bf2b8c 100644
--- a/src/function/utils/isNegative.js
+++ b/src/function/utils/isNegative.js
@@ -1,16 +1,14 @@
-import { deepMap } from '../../utils/collection.js'
import { factory } from '../../utils/factory.js'
-import { isNegativeNumber } from '../../plain/number/index.js'
-import { nearlyEqual as bigNearlyEqual } from '../../utils/bignumber/nearlyEqual.js'
-import { nearlyEqual } from '../../utils/number.js'
const name = 'isNegative'
-const dependencies = ['typed', 'config']
+const dependencies = ['typed', 'smaller', 'zero']
-export const createIsNegative = /* #__PURE__ */ factory(name, dependencies, ({ typed, config }) => {
+export const createIsNegative = /* #__PURE__ */ factory(name, dependencies, ({
+ typed, smaller, zero
+}) => {
/**
* Test whether a value is negative: smaller than zero.
- * The function supports types `number`, `BigNumber`, `Fraction`, and `Unit`.
+ * The function supports any type mathjs can compare.
*
* The function is evaluated element-wise in case of Array or Matrix input.
*
@@ -37,20 +35,5 @@ export const createIsNegative = /* #__PURE__ */ factory(name, dependencies, ({ t
* @return {boolean} Returns true when `x` is larger than zero.
* Throws an error in case of an unknown data type.
*/
- return typed(name, {
- number: x => nearlyEqual(x, 0, config.relTol, config.absTol) ? false : isNegativeNumber(x),
-
- BigNumber: x => bigNearlyEqual(x, new x.constructor(0), config.relTol, config.absTol)
- ? false
- : x.isNeg() && !x.isZero() && !x.isNaN(),
-
- bigint: x => x < 0n,
-
- Fraction: x => x.s < 0n, // It's enough to decide on the sign
-
- Unit: typed.referToSelf(self =>
- x => typed.find(self, x.valueType())(x.value)),
-
- 'Array | Matrix': typed.referToSelf(self => x => deepMap(x, self))
- })
+ return typed(name, { any: x => smaller(x, zero(x)) })
})
diff --git a/src/function/utils/isPositive.js b/src/function/utils/isPositive.js
index 3d188f63ad..571488a622 100644
--- a/src/function/utils/isPositive.js
+++ b/src/function/utils/isPositive.js
@@ -1,16 +1,14 @@
-import { deepMap } from '../../utils/collection.js'
import { factory } from '../../utils/factory.js'
-import { isPositiveNumber } from '../../plain/number/index.js'
-import { nearlyEqual as bigNearlyEqual } from '../../utils/bignumber/nearlyEqual.js'
-import { nearlyEqual } from '../../utils/number.js'
const name = 'isPositive'
-const dependencies = ['typed', 'config']
+const dependencies = ['typed', 'zero', 'larger']
-export const createIsPositive = /* #__PURE__ */ factory(name, dependencies, ({ typed, config }) => {
+export const createIsPositive = /* #__PURE__ */ factory(name, dependencies, ({
+ typed, zero, larger
+}) => {
/**
* Test whether a value is positive: larger than zero.
- * The function supports types `number`, `BigNumber`, `Fraction`, and `Unit`.
+ * The function supports any type mathjs can compare.
*
* The function is evaluated element-wise in case of Array or Matrix input.
*
@@ -39,21 +37,5 @@ export const createIsPositive = /* #__PURE__ */ factory(name, dependencies, ({ t
* @return {boolean} Returns true when `x` is larger than zero.
* Throws an error in case of an unknown data type.
*/
- return typed(name, {
- number: x => nearlyEqual(x, 0, config.relTol, config.absTol) ? false : isPositiveNumber(x),
-
- BigNumber: x =>
- bigNearlyEqual(x, new x.constructor(0), config.relTol, config.absTol)
- ? false
- : !x.isNeg() && !x.isZero() && !x.isNaN(),
-
- bigint: x => x > 0n,
-
- Fraction: x => x.s > 0n && x.n > 0n,
-
- Unit: typed.referToSelf(self =>
- x => typed.find(self, x.valueType())(x.value)),
-
- 'Array | Matrix': typed.referToSelf(self => x => deepMap(x, self))
- })
+ return typed(name, { any: x => larger(x, zero(x)) })
})
diff --git a/src/type/bignumber/BigNumber.js b/src/type/bignumber/BigNumber.js
index 9b424f97ac..7d59cfdec5 100644
--- a/src/type/bignumber/BigNumber.js
+++ b/src/type/bignumber/BigNumber.js
@@ -5,7 +5,10 @@ const name = 'BigNumber'
const dependencies = ['?on', 'config']
export const createBigNumberClass = /* #__PURE__ */ factory(name, dependencies, ({ on, config }) => {
- const BigNumber = Decimal.clone({ precision: config.precision, modulo: Decimal.EUCLID })
+ const BigNumber = Decimal.clone({
+ precision: config.compute.BigNumber.precision,
+ modulo: Decimal.EUCLID
+ })
BigNumber.prototype = Object.create(BigNumber.prototype)
/**
@@ -40,8 +43,10 @@ export const createBigNumberClass = /* #__PURE__ */ factory(name, dependencies,
if (on) {
// listen for changed in the configuration, automatically apply changed precision
on('config', function (curr, prev) {
- if (curr.precision !== prev.precision) {
- BigNumber.config({ precision: curr.precision })
+ if (curr.compute.BigNumber.precision !==
+ prev.compute.BigNumber.precision
+ ) {
+ BigNumber.config({ precision: curr.compute.BigNumber.precision })
}
})
}
diff --git a/src/type/matrix/DenseMatrix.js b/src/type/matrix/DenseMatrix.js
index 112e0abc33..6f6b5a0ec9 100644
--- a/src/type/matrix/DenseMatrix.js
+++ b/src/type/matrix/DenseMatrix.js
@@ -219,7 +219,7 @@ export const createDenseMatrixClass = /* #__PURE__ */ factory(name, dependencies
throw new TypeError('Invalid index')
}
- const isScalar = config.legacySubset
+ const isScalar = config.compatibility.subset
? index.size().every(idx => idx === 1)
: index.isScalar()
if (isScalar) {
@@ -246,7 +246,7 @@ export const createDenseMatrixClass = /* #__PURE__ */ factory(name, dependencies
returnMatrix._size = submatrix.size
returnMatrix._datatype = matrix._datatype
returnMatrix._data = submatrix.data
- return config.legacySubset ? returnMatrix.reshape(index.size()) : returnMatrix
+ return config.compatibility.subset ? returnMatrix.reshape(index.size()) : returnMatrix
}
}
diff --git a/src/type/unit/Unit.js b/src/type/unit/Unit.js
index daebd92a87..8c5be792e9 100644
--- a/src/type/unit/Unit.js
+++ b/src/type/unit/Unit.js
@@ -242,8 +242,9 @@ export const createUnitClass = /* #__PURE__ */ factory(name, dependencies, ({
}
/**
- * Parse a string into a unit. The value of the unit is parsed as number,
- * BigNumber, or Fraction depending on the math.js config setting `number`.
+ * Parse a string into a unit. The data type of the value of the unit
+ * is determined by the math.js config settings, as for parsing numeric
+ * literals.
*
* Throws an exception if the provided string does not contain a valid unit or
* cannot be parsed.
@@ -287,10 +288,18 @@ export const createUnitClass = /* #__PURE__ */ factory(name, dependencies, ({
// Optional number at the start of the string
const valueStr = parseNumber()
let value = null
+ let parseType = config.number
if (valueStr) {
- if (config.number === 'BigNumber') {
+ if (parseType === 'bigint') {
+ try {
+ value = BigInt(valueStr)
+ } catch {
+ parseType = config.parse.numberFallback
+ }
+ }
+ if (parseType === 'BigNumber') {
value = new BigNumber(valueStr)
- } else if (config.number === 'Fraction') {
+ } else if (parseType === 'Fraction') {
try {
// not all numbers can be turned in Fractions, for example very small numbers not
value = new Fraction(valueStr)
@@ -764,12 +773,16 @@ export const createUnitClass = /* #__PURE__ */ factory(name, dependencies, ({
}
/**
- * Return the numeric value of this unit if it is dimensionless, has a value, and config.predictable == false; or the original unit otherwise
+ * Return the numeric value of this unit if it is dimensionless, has a value,
+ * and config.compute.uniformType == false; or the original unit otherwise
* @param {Unit} unit
* @returns {number | Fraction | BigNumber | Unit} The numeric value of the unit if conditions are met, or the original unit otherwise
*/
function getNumericIfUnitless (unit) {
- if (unit.equalBase(BASE_UNITS.NONE) && unit.value !== null && !config.predictable) {
+ if (unit.equalBase(BASE_UNITS.NONE) &&
+ unit.value !== null &&
+ !config.compute.uniformType
+ ) {
return unit.value
} else {
return unit
@@ -2919,7 +2932,7 @@ export const createUnitClass = /* #__PURE__ */ factory(name, dependencies, ({
* @param {{number: 'number' | 'BigNumber'}} config
*/
function calculateAngleValues (config) {
- if (config.number === 'BigNumber') {
+ if (config.compute.numberApproximate === 'BigNumber') {
const pi = createPi(BigNumber)
UNITS.rad.value = new BigNumber(1)
UNITS.deg.value = pi.div(180) // 2 * pi / 360
@@ -2948,7 +2961,7 @@ export const createUnitClass = /* #__PURE__ */ factory(name, dependencies, ({
if (on) {
// recalculate the values on change of configuration
on('config', function (curr, prev) {
- if (curr.number !== prev.number) {
+ if (curr.compute.numberApproximate !== prev.compute.numberApproximate) {
calculateAngleValues(curr)
}
})
diff --git a/src/type/unit/physicalConstants.js b/src/type/unit/physicalConstants.js
index 701aac13cb..b86d847c5e 100644
--- a/src/type/unit/physicalConstants.js
+++ b/src/type/unit/physicalConstants.js
@@ -75,9 +75,10 @@ function unitFactory (name, valueStr, unitStr) {
return factory(name, dependencies, ({ config, Unit, BigNumber }) => {
// Note that we can parse into number or BigNumber.
- // We do not parse into Fractions as that doesn't make sense: we would lose precision of the values
- // Therefore we dont use Unit.parse()
- const value = config.number === 'BigNumber'
+ // We do not parse into Fractions as that doesn't make sense:
+ // we would lose precision of the values
+ // Therefore we don't use Unit.parse()
+ const value = config.compute.numberApproximate === 'BigNumber'
? new BigNumber(valueStr)
: parseFloat(valueStr)
@@ -93,7 +94,7 @@ function numberFactory (name, value) {
const dependencies = ['config', 'BigNumber']
return factory(name, dependencies, ({ config, BigNumber }) => {
- return config.number === 'BigNumber'
+ return config.compute.numberApproximate === 'BigNumber'
? new BigNumber(value)
: value
})
diff --git a/src/utils/bigint.js b/src/utils/bigint.js
index 4a163cfdfa..4235b73f82 100644
--- a/src/utils/bigint.js
+++ b/src/utils/bigint.js
@@ -10,13 +10,13 @@
* implementation, it just downgrades to number and uses the complex result.
* @param {number} log16 the log of 16
* @param {(number) -> number} numberLog the logarithm function for numbers
- * @param {ConfigurationObject} config the mathjs configuration
+ * @param {boolean} uniformType whether the result should always be type mumber
* @param {(number) -> Complex} cplx the associated Complex log
* @returns {(bigint) -> number} the corresponding logarithm for bigints
*/
-export function promoteLogarithm (log16, numberLog, config, cplx) {
+export function promoteLogarithm (log16, numberLog, uniformType, cplx) {
return function (b) {
- if (b > 0 || config.predictable) {
+ if (b > 0 || uniformType) {
if (b <= 0) return NaN
const s = b.toString(16)
const s15 = s.substring(0, 15)
diff --git a/src/utils/number.js b/src/utils/number.js
index 78dd910a40..6fc1fb6b09 100644
--- a/src/utils/number.js
+++ b/src/utils/number.js
@@ -20,12 +20,15 @@ export function isInteger (value) {
}
/**
- * Ensure the number type is compatible with the provided value.
- * If not, return 'number' instead.
+ * Ensure the type specified by the `number` property is compatible with
+ * the provided string numeric representation.
+ * If not, return the type specified by the `parse.numberFallback` property
+ * instead.
*
* For example:
*
- * safeNumberType('2.3', { number: 'bigint', numberFallback: 'number' })
+ * safeNumberType(
+ * '2.3', { number: 'bigint', parse: { numberFallback: 'number' } })
*
* will return 'number' and not 'bigint' because trying to create a bigint with
* value 2.3 would throw an exception.
@@ -33,8 +36,10 @@ export function isInteger (value) {
* @param {string} numberStr
* @param {{
* number: 'number' | 'BigNumber' | 'bigint' | 'Fraction'
- * numberFallback: 'number' | 'BigNumber'
- * }} config
+ * parse: {
+ * numberFallback: 'number' | 'BigNumber'
+ * }
+ * }} parseConfig
* @returns {'number' | 'BigNumber' | 'bigint' | 'Fraction'}
*/
export function safeNumberType (numberStr, config) {
@@ -42,7 +47,7 @@ export function safeNumberType (numberStr, config) {
try {
BigInt(numberStr)
} catch {
- return config.numberFallback
+ return config.parse.numberFallback
}
}
diff --git a/src/utils/object.js b/src/utils/object.js
index fb62f6711d..5578ef081e 100644
--- a/src/utils/object.js
+++ b/src/utils/object.js
@@ -277,7 +277,7 @@ export function hasOwnProperty (object, property) {
}
/**
- * Test whether an object is a factory. a factory has fields:
+ * Test whether an object is a legacy factory. a factory has fields:
*
* - factory: function (type: Object, config: Object, load: function, typed: function [, math: Object]) (required)
* - name: string (optional)
diff --git a/test/generated-code-tests/dependencies.test.js b/test/generated-code-tests/dependencies.test.js
index 51bf0107e9..ad1a6f601b 100644
--- a/test/generated-code-tests/dependencies.test.js
+++ b/test/generated-code-tests/dependencies.test.js
@@ -16,7 +16,10 @@ describe('dependencies', function () {
})
it('should create functions with config', function () {
- const config = { number: 'BigNumber' }
+ const config = {
+ number: 'BigNumber',
+ compute: { numberApproximate: 'BigNumber' }
+ }
const { pi } = create({
piDependencies
}, config)
diff --git a/test/node-tests/defaultInstance.test.cjs b/test/node-tests/defaultInstance.test.cjs
index 0a8eb7a41a..eada798bd6 100644
--- a/test/node-tests/defaultInstance.test.cjs
+++ b/test/node-tests/defaultInstance.test.cjs
@@ -8,42 +8,55 @@ describe('defaultInstance', function () {
it('should get a default instance of mathjs', function () {
assert.strictEqual(typeof math, 'object')
assert.deepStrictEqual(math.config(), {
- matrix: 'Matrix',
+ compute: {
+ Matrix: { defaultType: 'Matrix' },
+ BigNumber: { precision: 64 },
+ uniformType: false,
+ defaultRelTol: 1e-12,
+ defaultAbsTol: 1e-15,
+ randomSeed: null,
+ numberApproximate: 'number'
+ },
+ parse: {
+ numberFallback: 'number'
+ },
number: 'number',
- numberFallback: 'number',
- precision: 64,
- predictable: false,
- relTol: 1e-12,
- absTol: 1e-15,
- legacySubset: false,
- randomSeed: null
+ compatibility: { subset: false }
})
})
it('should create an instance of math.js with custom configuration', function () {
const math1 = math.create({
- matrix: 'Array',
- number: 'BigNumber'
+ number: 'BigNumber',
+ compute: {
+ Matrix: { defaultType: 'Array' },
+ numberApproximate: 'BigNumber'
+ }
})
assert.strictEqual(typeof math1, 'object')
assert.deepStrictEqual(math1.config(), {
- matrix: 'Array',
- number: 'BigNumber',
- numberFallback: 'number',
- precision: 64,
- predictable: false,
- relTol: 1e-12,
- absTol: 1e-15,
- legacySubset: false,
- randomSeed: null
+ compute: {
+ Matrix: { defaultType: 'Array' },
+ BigNumber: { precision: 64 },
+ uniformType: false,
+ defaultRelTol: 1e-12,
+ defaultAbsTol: 1e-15,
+ randomSeed: null,
+ numberApproximate: 'BigNumber'
+ },
+ parse: {
+ numberFallback: 'number'
+ },
+ compatibility: { subset: false },
+ number: 'BigNumber'
})
})
it('two instances of math.js should be isolated from each other', function () {
const math1 = math.create()
const math2 = math.create({
- matrix: 'Array'
+ compute: { Matrix: { defaultType: 'Array' } }
})
assert.notStrictEqual(math, math1)
@@ -53,7 +66,7 @@ describe('defaultInstance', function () {
assert.notDeepStrictEqual(math.config(), math2.config())
// changing config should not affect the other
- math1.config({ number: 'BigNumber' })
+ math1.config({ number: 'BigNumber', compute: { numberApproximate: 'BigNumber' } })
assert.strictEqual(math.config().number, 'number')
assert.strictEqual(math1.config().number, 'BigNumber')
assert.strictEqual(math2.config().number, 'number')
@@ -69,20 +82,28 @@ describe('defaultInstance', function () {
const config = math1.config({
number: 'BigNumber',
- precision: 4,
- predictable: true
+ compute: {
+ BigNumber: { precision: 4 },
+ uniformType: true,
+ numberApproximate: 'BigNumber'
+ }
})
assert.deepStrictEqual(config, {
- matrix: 'Matrix',
- number: 'BigNumber',
- numberFallback: 'number',
- precision: 4,
- predictable: true,
- relTol: 1e-12,
- absTol: 1e-15,
- legacySubset: false,
- randomSeed: null
+ compute: {
+ Matrix: { defaultType: 'Matrix' },
+ BigNumber: { precision: 4 },
+ uniformType: true,
+ defaultRelTol: 1e-12,
+ defaultAbsTol: 1e-15,
+ randomSeed: null,
+ numberApproximate: 'BigNumber'
+ },
+ parse: {
+ numberFallback: 'number'
+ },
+ compatibility: { subset: false },
+ number: 'BigNumber'
})
assert.ok(math1.isNaN(math1.sqrt(-4)))
@@ -92,20 +113,28 @@ describe('defaultInstance', function () {
const config2 = math1.config({
number: 'number',
- precision: 64,
- predictable: false
+ compute: {
+ BigNumber: { precision: 64 },
+ uniformType: false,
+ numberApproximate: 'number'
+ }
})
assert.deepStrictEqual(config2, {
- matrix: 'Matrix',
- number: 'number',
- numberFallback: 'number',
- precision: 64,
- predictable: false,
- relTol: 1e-12,
- absTol: 1e-15,
- legacySubset: false,
- randomSeed: null
+ compute: {
+ Matrix: { defaultType: 'Matrix' },
+ BigNumber: { precision: 64 },
+ uniformType: false,
+ defaultRelTol: 1e-12,
+ defaultAbsTol: 1e-15,
+ randomSeed: null,
+ numberApproximate: 'number'
+ },
+ parse: {
+ numberFallback: 'number'
+ },
+ compatibility: { subset: false },
+ number: 'number'
})
assert.deepStrictEqual(math1.sqrt(-4), math1.complex(0, 2))
@@ -126,7 +155,7 @@ describe('defaultInstance', function () {
assert.strictEqual(math1.sqrt(4), 'foo(4)')
// changing config should not change the custom function sqrt
- math1.config({ number: 'BigNumber' })
+ math1.config({ number: 'BigNumber', compute: { numberApproximate: 'BigNumber' } })
assert.strictEqual(math1.sqrt(4), 'foo(4)')
})
diff --git a/test/typescript-tests/testTypes.ts b/test/typescript-tests/testTypes.ts
index 4b38e7710c..ec54f42ab8 100644
--- a/test/typescript-tests/testTypes.ts
+++ b/test/typescript-tests/testTypes.ts
@@ -85,6 +85,10 @@ Basic usage examples
math.sqrt(-4)
math.pow(m2by2, 2)
+ // @ts-expect-error: since zero(bigint) returns 0n, this comparison fails
+ if (math.zero(-23n) === 1n) {
+ console.error('Nor should this happen')
+ }
const angle = 0.2
math.add(math.pow(math.sin(angle), 2), math.pow(math.cos(angle), 2))
math.add(2, 3, 4)
@@ -185,7 +189,10 @@ Bignumbers examples
// configure the default type of numbers as BigNumbers
const math = create(all, {
number: 'BigNumber',
- precision: 20
+ compute: {
+ BigNumber: { precision: 20 },
+ numberApproximate: 'BigNumber'
+ }
})
{
@@ -1894,6 +1901,7 @@ Units examples
math.multiply(b, 2)
math.divide(math.unit('1 m'), math.unit('1 s'))
math.pow(math.unit('12 in'), 3)
+ math.zero(math.unit('22 m/secs^2'))
// units can be converted to a specific type, or to a number
b.to('cm')
diff --git a/test/unit-tests/configs.js b/test/unit-tests/configs.js
new file mode 100644
index 0000000000..5d52642b90
--- /dev/null
+++ b/test/unit-tests/configs.js
@@ -0,0 +1,16 @@
+import { deepExtend } from '../../src/utils/object.js'
+
+/**
+ * Returns a configuration options object that sets the default number type
+ * to BigNumber, and the type to use for approximate results on exact inputs
+ * to BigNumber, and optionally sets the BigNumber precision to the first argument,
+ * if any, and incorporates additional options given by the second argument, if any.
+ */
+export function bigConfig (precision, more) {
+ const options = { number: 'BigNumber', compute: { numberApproximate: 'BigNumber' } }
+ if (precision) {
+ options.compute.BigNumber = { precision }
+ }
+ if (more) deepExtend(options, more)
+ return options
+}
diff --git a/test/unit-tests/constants.test.js b/test/unit-tests/constants.test.js
index fab6704a95..12fe48a7be 100644
--- a/test/unit-tests/constants.test.js
+++ b/test/unit-tests/constants.test.js
@@ -23,7 +23,14 @@ import {
describe('constants', function () {
describe('number', function () {
- const config = { number: 'number', precision: 64, relTol: 1e-12 }
+ const config = {
+ number: 'number',
+ compute: {
+ BigNumber: { precision: 64 },
+ numberApproximate: 'number',
+ defaultRelTol: 1e-12
+ }
+ }
const BigNumber = createBigNumberClass({ config })
const Complex = createComplexClass({ config })
const dependencies = {
@@ -86,7 +93,14 @@ describe('constants', function () {
})
describe('bignumbers', function () {
- const config = { number: 'BigNumber', precision: 64, relTol: 1e-12 }
+ const config = {
+ number: 'BigNumber',
+ compute: {
+ BigNumber: { precision: 64 },
+ numberApproximate: 'BigNumber',
+ defaultRelTol: 1e-12
+ }
+ }
const BigNumber = createBigNumberClass({ config })
const Complex = createComplexClass({ config })
const dependencies = {
diff --git a/test/unit-tests/core/config.test.js b/test/unit-tests/core/config.test.js
index bfe730ced1..307bcb020d 100644
--- a/test/unit-tests/core/config.test.js
+++ b/test/unit-tests/core/config.test.js
@@ -12,33 +12,20 @@ describe('config', function () {
import: () => { throw new Error('Function import is disabled') }
}, { override: true })
- math2.config({ number: 'BigNumber' })
+ math2.config({ compute: { numberApproximate: 'BigNumber' } })
assert.strictEqual(math2.typeOf(math2.pi), 'BigNumber')
})
// TODO: test function config
- it('should work with config epsilon during deprecation', function () {
+ it('should throw on discontinued option epsilon', function () {
const math2 = math.create()
- // Add a spy to temporarily disable console.warn
- const warnStub = sinon.stub(console, 'warn')
-
- // Set epsilon to throw a warning and set relTol and absTol
- assert.doesNotThrow(function () { math2.config({ epsilon: 1e-5 }) })
-
- // Check if epsilon is set as relTol and absTol
- assert.strictEqual(math2.config().relTol, 1e-5)
- assert.strictEqual(math2.config().absTol, 1e-8)
-
- // Check if console.warn was called
- assert.strictEqual(warnStub.callCount, 1)
-
- // Restore console.warn
- warnStub.restore()
+ assert.throws(
+ () => math2.config({ epsilon: 1e-5 }), /discontinued.*epsilon/)
})
- it('should work with config legacySubset during deprecation', function () {
+ it('should work with compatibility subset during deprecation', function () {
const math2 = math.create()
// Add a spy to temporarily disable console.warn
const warnStub = sinon.stub(console, 'warn')
@@ -47,16 +34,13 @@ describe('config', function () {
assert.doesNotThrow(function () { math2.config({ legacySubset: true }) })
// Check if legacySubset is set
- assert.strictEqual(math2.config().legacySubset, true)
+ assert.strictEqual(math2.config().compatibility.subset, true)
// Check if console.warn was called
assert.strictEqual(warnStub.callCount, 1)
- // Set legacySubset to false, should not throw a warning
- assert.doesNotThrow(function () { math2.config({ legacySubset: false }) })
-
- // Validate that if console.warn was not called again
- assert.strictEqual(warnStub.callCount, 1)
+ // Ensure that legacy behavior of subset occurs
+ assert.deepStrictEqual(math2.subset([1, 2], math.index([1])), 2)
// Restore console.warn
warnStub.restore()
diff --git a/test/unit-tests/core/function/config.test.js b/test/unit-tests/core/function/config.test.js
new file mode 100644
index 0000000000..01f31ba7a7
--- /dev/null
+++ b/test/unit-tests/core/function/config.test.js
@@ -0,0 +1,66 @@
+import assert from 'assert'
+import { modernizeOptions } from '../../../../src/core/function/config.js'
+
+function accumulator (list) {
+ return item => list.push(item)
+}
+
+describe('config internals', function () {
+ it('should translate options without changing input', function () {
+ const opt = { a: 1, b: 2 }
+ assert.deepStrictEqual(
+ modernizeOptions(opt, { b: ['normal', ['c']] }), { a: 1, c: 2 })
+ assert.deepStrictEqual(opt, { a: 1, b: 2 })
+ assert.deepStrictEqual(
+ modernizeOptions(opt, { a: ['normal', ['c', 'd']] }),
+ { b: 2, c: { d: 1 } })
+ assert.deepStrictEqual(opt, { a: 1, b: 2 })
+ })
+
+ it('should warn about deprecated options', function () {
+ const opt = { a: 1, b: 2 }
+ const warns = []
+ modernizeOptions(opt, { b: 'deprecated' }, accumulator(warns))
+ assert.deepStrictEqual(opt, { a: 1, b: 2 })
+ assert.strictEqual(warns.length, 1)
+ assert.ok(/deprecated.*option.*b/.test(warns[0]))
+ })
+
+ it('should warn and translate at the same time', function () {
+ const opt = { a: 1, b: 2 }
+ let warns = []
+ assert.deepStrictEqual(
+ modernizeOptions(opt, { b: ['deprecated', ['c']] }, accumulator(warns)),
+ { a: 1, c: 2 })
+ assert.deepStrictEqual(opt, { a: 1, b: 2 })
+ assert.strictEqual(warns.length, 1)
+ assert.ok(/deprecated.*option.*'b'.*'c'/.test(warns[0]))
+ warns = []
+ assert.deepStrictEqual(
+ modernizeOptions(
+ opt, { a: ['deprecated', ['c', 'd']] }, accumulator(warns)),
+ { b: 2, c: { d: 1 } })
+ assert.deepStrictEqual(opt, { a: 1, b: 2 })
+ assert.strictEqual(warns.length, 1)
+ assert.ok(/deprecated.*option.*'a'.*'c[.]d'/.test(warns[0]))
+ })
+
+ it('should throw errors for deprecated options', function () {
+ const opt = { a: 1, b: 2 }
+ assert.throws(
+ () => modernizeOptions(opt, { b: ['discontinued', 'foo'] }),
+ /discontinued.*option.*'b'.*'foo'/)
+ })
+
+ it('should translate to two places at once', function () {
+ const opt = { a: 1, b: 2 }
+ const warns = []
+ assert.deepStrictEqual(
+ modernizeOptions(
+ opt, { b: ['deprecated', ['c'], ['d', 'e']] }, accumulator(warns)),
+ { a: 1, c: 2, d: { e: 2 } })
+ assert.deepStrictEqual(opt, { a: 1, b: 2 })
+ assert.strictEqual(warns.length, 1)
+ assert.ok(/deprecated.*option.*'b'.*'c' and 'd[.]e'/.test(warns[0]))
+ })
+})
diff --git a/test/unit-tests/expression/node/AccessorNode.test.js b/test/unit-tests/expression/node/AccessorNode.test.js
index 39b1b2c80c..7b6073c2f1 100644
--- a/test/unit-tests/expression/node/AccessorNode.test.js
+++ b/test/unit-tests/expression/node/AccessorNode.test.js
@@ -2,7 +2,9 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
-const bigmath = math.create({ number: 'BigNumber' })
+import { bigConfig } from '../../configs.js'
+
+const bigmath = math.create(bigConfig())
const Node = math.Node
const ConstantNode = math.ConstantNode
const OperatorNode = math.OperatorNode
diff --git a/test/unit-tests/expression/node/ArrayNode.test.js b/test/unit-tests/expression/node/ArrayNode.test.js
index 2d15e53c9e..887caccfb3 100644
--- a/test/unit-tests/expression/node/ArrayNode.test.js
+++ b/test/unit-tests/expression/node/ArrayNode.test.js
@@ -54,7 +54,7 @@ describe('ArrayNode', function () {
})
it('should compile an ArrayNode and evaluate as Array', function () {
- const mathArray = math.create({ matrix: 'Array' })
+ const mathArray = math.create({ compute: { Matrix: { defaultType: 'Array' } } })
const a = new mathArray.ConstantNode(1)
const b = new mathArray.ConstantNode(2)
const c = new mathArray.ConstantNode(3)
diff --git a/test/unit-tests/expression/node/AssignmentNode.test.js b/test/unit-tests/expression/node/AssignmentNode.test.js
index 2efa0ff140..b0821b105e 100644
--- a/test/unit-tests/expression/node/AssignmentNode.test.js
+++ b/test/unit-tests/expression/node/AssignmentNode.test.js
@@ -2,6 +2,8 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
+import { bigConfig } from '../../configs.js'
+
const Node = math.Node
const AccessorNode = math.AccessorNode
const ConstantNode = math.ConstantNode
@@ -145,7 +147,7 @@ describe('AssignmentNode', function () {
})
it('should compile an AssignmentNode with bignumber setting', function () {
- const bigmath = math.create({ number: 'BigNumber' })
+ const bigmath = math.create(bigConfig())
const object = new bigmath.SymbolNode('a')
const index = new bigmath.IndexNode([
diff --git a/test/unit-tests/expression/node/ConstantNode.test.js b/test/unit-tests/expression/node/ConstantNode.test.js
index 68d74020bf..913259da58 100644
--- a/test/unit-tests/expression/node/ConstantNode.test.js
+++ b/test/unit-tests/expression/node/ConstantNode.test.js
@@ -2,7 +2,9 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
-const bigmath = math.create({ number: 'BigNumber' })
+import { bigConfig } from '../../configs.js'
+
+const bigmath = math.create(bigConfig())
const Node = math.Node
const ConstantNode = math.ConstantNode
const SymbolNode = math.SymbolNode
diff --git a/test/unit-tests/expression/parse.test.js b/test/unit-tests/expression/parse.test.js
index 444247244f..5ee4a71924 100644
--- a/test/unit-tests/expression/parse.test.js
+++ b/test/unit-tests/expression/parse.test.js
@@ -5,6 +5,7 @@ import { isMap, isObjectWrappingMap, isPartitionedMap } from '../../../src/utils
import { PartitionedMap } from '../../../src/utils/map.js'
import { approxDeepEqual, approxEqual } from '../../../tools/approx.js'
+import { bigConfig } from '../configs.js'
const parse = math.parse
const ConditionalNode = math.ConditionalNode
@@ -363,9 +364,7 @@ describe('parse', function () {
})
it('should output bignumbers if default number type is bignumber', function () {
- const bigmath = math.create({
- number: 'BigNumber'
- })
+ const bigmath = math.create(bigConfig())
assert.deepStrictEqual(bigmath.parse('0.1').compile().evaluate(), bigmath.bignumber(0.1))
assert.deepStrictEqual(bigmath.parse('1.2e5000').compile().evaluate(), bigmath.bignumber('1.2e5000'))
@@ -390,9 +389,7 @@ describe('parse', function () {
describe('fraction', function () {
it('should output fractions if default number type is fraction', function () {
- const fmath = math.create({
- number: 'Fraction'
- })
+ const fmath = math.create({ number: 'Fraction' })
assert(fmath.parse('0.1').compile().evaluate() instanceof math.Fraction)
assert.strictEqual(fmath.parse('1/3').compile().evaluate().toString(), '0.(3)')
@@ -2490,9 +2487,7 @@ describe('parse', function () {
})
describe('bignumber', function () {
- const bigmath = math.create({
- number: 'BigNumber'
- })
+ const bigmath = math.create(bigConfig())
const BigNumber = bigmath.BigNumber
it('should parse numbers as bignumber', function () {
@@ -2566,9 +2561,7 @@ describe('parse', function () {
})
describe('bigint', function () {
- const bigmath = math.create({
- number: 'bigint'
- })
+ const bigmath = math.create({ number: 'bigint' })
it('should parse integer numbers as bigint', function () {
assert.strictEqual(bigmath.evaluate('123123123123123123123'), 123123123123123123123n)
@@ -2586,12 +2579,14 @@ describe('parse', function () {
it('should fallback on the configured numberFallback when parsing as bigint', function () {
const bigmathFallback = math.create({
number: 'bigint',
- numberFallback: 'BigNumber'
+ parse: { numberFallback: 'BigNumber' }
})
assert.strictEqual(bigmathFallback.evaluate('42'), 42n)
- assert.deepStrictEqual(bigmathFallback.evaluate('2.3'), bigmathFallback.bignumber('2.3'))
- assert.deepStrictEqual(bigmathFallback.evaluate('-2.3'), bigmathFallback.bignumber('-2.3'))
+ assert.deepStrictEqual(
+ bigmathFallback.evaluate('2.3'), bigmathFallback.bignumber('2.3'))
+ assert.deepStrictEqual(
+ bigmathFallback.evaluate('-2.3'), bigmathFallback.bignumber('-2.3'))
})
it('should evaluate units with bigint values (falling back to number)', function () {
diff --git a/test/unit-tests/function/algebra/simplify.test.js b/test/unit-tests/function/algebra/simplify.test.js
index 6a34e0fc06..c71f6fe93d 100644
--- a/test/unit-tests/function/algebra/simplify.test.js
+++ b/test/unit-tests/function/algebra/simplify.test.js
@@ -2,6 +2,7 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
+import { bigConfig } from '../../configs.js'
const expLibrary = []
// eslint-disable-next-line mocha/no-exports
@@ -271,7 +272,7 @@ describe('simplify', function () {
})
it('should preserve the value of BigNumbers', function () {
- const bigmath = math.create({ number: 'BigNumber', precision: 64 })
+ const bigmath = math.create(bigConfig(64))
assert.deepStrictEqual(bigmath.simplify('111111111111111111 + 111111111111111111').evaluate(), bigmath.evaluate('222222222222222222'))
assert.deepStrictEqual(bigmath.simplify('1 + 111111111111111111').evaluate(), bigmath.evaluate('111111111111111112'))
assert.deepStrictEqual(bigmath.simplify('1/2 + 11111111111111111111').evaluate(), bigmath.evaluate('11111111111111111111.5'))
diff --git a/test/unit-tests/function/algebra/simplifyConstant.test.js b/test/unit-tests/function/algebra/simplifyConstant.test.js
index 9fb7b02f6e..6fbc284202 100644
--- a/test/unit-tests/function/algebra/simplifyConstant.test.js
+++ b/test/unit-tests/function/algebra/simplifyConstant.test.js
@@ -12,7 +12,10 @@ describe('simplifyConstant', function () {
}
it('should evaluate constant subexpressions', function () {
+ testSimplifyConstant('100.8', '504 / 5')
+ testSimplifyConstant('504 * (5 ^ (-1))', '504 / 5')
testSimplifyConstant('2+2', '4')
+ testSimplifyConstant('fraction(2) + fraction(2)', '4/1')
testSimplifyConstant('x+3*5', 'x + 15')
testSimplifyConstant('f(sin(0))', 'f(0)')
testSimplifyConstant('[10/2, y, 8-4]', '[5, y, 4]')
diff --git a/test/unit-tests/function/algebra/sylvester.test.js b/test/unit-tests/function/algebra/sylvester.test.js
index 72bb42aa55..64c57545e2 100644
--- a/test/unit-tests/function/algebra/sylvester.test.js
+++ b/test/unit-tests/function/algebra/sylvester.test.js
@@ -62,7 +62,8 @@ describe('sylvester', function () {
math2.config({ legacySubset: true })
// Test legacy syntax with sylvester
- // This is not strictly necessary and shoudl be removed after the deprecation period
+ // This is not strictly necessary and should be removed,
+ // after the deprecation period
const sylvesterA = [[-5.3, -1.4, -0.2, 0.7],
[-0.4, -1.0, -0.1, -1.2],
[0.3, 0.7, -2.5, 0.7],
diff --git a/test/unit-tests/function/arithmetic/cbrt.test.js b/test/unit-tests/function/arithmetic/cbrt.test.js
index e0075cfd5a..010d116885 100644
--- a/test/unit-tests/function/arithmetic/cbrt.test.js
+++ b/test/unit-tests/function/arithmetic/cbrt.test.js
@@ -83,7 +83,7 @@ describe('cbrt', function () {
complex('-2i')
]))
- const math2 = math.create({ matrix: 'Array' })
+ const math2 = math.create({ compute: { Matrix: { defaultType: 'Array' } } })
approxDeepEqual(math2.cbrt(complex('8i'), true), [
complex(' 1.7321 + i'),
diff --git a/test/unit-tests/function/arithmetic/divide.test.js b/test/unit-tests/function/arithmetic/divide.test.js
index d14353d03e..58d0c0dff4 100644
--- a/test/unit-tests/function/arithmetic/divide.test.js
+++ b/test/unit-tests/function/arithmetic/divide.test.js
@@ -3,6 +3,8 @@ import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const divide = math.divide
const bignumber = math.bignumber
const complex = math.complex
@@ -175,7 +177,10 @@ describe('divide', function () {
assert.strictEqual(divide(math.unit('day'), bignumber(81)).format({ precision: 50 }), '0.012345679012345679012345679012345679012345679012346 day')
assert.strictEqual(divide(math.unit('1 day'), bignumber(81)).format({ precision: 50 }), '0.012345679012345679012345679012345679012345679012346 day')
- assert.strictEqual(math.create({ number: 'BigNumber' }).evaluate('round(80 / day * 5 days, 30)').toString(), '400')
+ assert.strictEqual(
+ math.create(bigConfig()).evaluate('round(80 / day * 5 days, 30)').toString(),
+ '400'
+ )
})
it('should divide each elements in a matrix by a number', function () {
diff --git a/test/unit-tests/function/arithmetic/exp.test.js b/test/unit-tests/function/arithmetic/exp.test.js
index 3c69c4fec7..6b1a4c7dcd 100644
--- a/test/unit-tests/function/arithmetic/exp.test.js
+++ b/test/unit-tests/function/arithmetic/exp.test.js
@@ -27,7 +27,7 @@ describe('exp', function () {
})
it('should exponentiate a bignumber', function () {
- const bigmath = math.create({ precision: 100 })
+ const bigmath = math.create({ compute: { BigNumber: { precision: 100 } } })
assert.deepStrictEqual(bigmath.exp(bigmath.bignumber(1)), bigmath.bignumber('2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427'))
})
diff --git a/test/unit-tests/function/arithmetic/expm1.test.js b/test/unit-tests/function/arithmetic/expm1.test.js
index c67f8915ae..0f3cdee28d 100644
--- a/test/unit-tests/function/arithmetic/expm1.test.js
+++ b/test/unit-tests/function/arithmetic/expm1.test.js
@@ -34,7 +34,7 @@ describe('expm1', function () {
})
it('should exponentiate a bignumber', function () {
- const bigmath = math.create({ precision: 100 })
+ const bigmath = math.create({ compute: { BigNumber: { precision: 100 } } })
assert.deepStrictEqual(bigmath.expm1(bigmath.bignumber(1)), bigmath.bignumber('1.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427'))
})
diff --git a/test/unit-tests/function/arithmetic/log.test.js b/test/unit-tests/function/arithmetic/log.test.js
index 3ad86017b2..a5070a1745 100644
--- a/test/unit-tests/function/arithmetic/log.test.js
+++ b/test/unit-tests/function/arithmetic/log.test.js
@@ -3,7 +3,8 @@ import assert from 'assert'
import { approxDeepEqual } from '../../../../tools/approx.js'
import math from '../../../../src/defaultInstance.js'
-const mathPredictable = math.create({ predictable: true })
+const bigmath = math.create({ compute: { BigNumber: { precision: 100 } } })
+const mathPredictable = math.create({ compute: { uniformType: true } })
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
@@ -56,8 +57,6 @@ describe('log', function () {
})
it('should return the log of positive bignumbers', function () {
- const bigmath = math.create({ precision: 100 })
-
assert.deepStrictEqual(bigmath.log(bigmath.bignumber(1)), bigmath.bignumber('0'))
assert.deepStrictEqual(bigmath.log(bigmath.bignumber(2)), bigmath.bignumber('0.6931471805599453094172321214581765680755001343602552541206800094933936219696947156058633269964186875'))
assert.deepStrictEqual(bigmath.log(bigmath.bignumber(3)), bigmath.bignumber('1.098612288668109691395245236922525704647490557822749451734694333637494293218608966873615754813732089'))
@@ -67,8 +66,6 @@ describe('log', function () {
})
it('should return the log of negative bignumbers', function () {
- const bigmath = math.create({ precision: 100 })
-
approxDeepEqual(bigmath.log(bigmath.bignumber(-1)), complex('0.000000000000000 + 3.141592653589793i'))
approxDeepEqual(bigmath.log(bigmath.bignumber(-2)), complex('0.693147180559945 + 3.141592653589793i'))
approxDeepEqual(bigmath.log(bigmath.bignumber(-3)), complex('1.098612288668110 + 3.141592653589793i'))
@@ -79,8 +76,6 @@ describe('log', function () {
})
it('should return the log of a bignumber with value zero', function () {
- const bigmath = math.create({ precision: 100 })
-
assert.deepStrictEqual(bigmath.log(bigmath.bignumber(0)).toString(), '-Infinity')
})
diff --git a/test/unit-tests/function/arithmetic/log10.test.js b/test/unit-tests/function/arithmetic/log10.test.js
index e8e7682a4a..c326bfab3e 100644
--- a/test/unit-tests/function/arithmetic/log10.test.js
+++ b/test/unit-tests/function/arithmetic/log10.test.js
@@ -3,7 +3,8 @@ import assert from 'assert'
import { approxDeepEqual } from '../../../../tools/approx.js'
import math from '../../../../src/defaultInstance.js'
-const mathPredictable = math.create({ predictable: true })
+const mathPredictable = math.create({ compute: { uniformType: true } })
+const bigmath = math.create({ compute: { BigNumber: { precision: 100 } } })
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
@@ -44,8 +45,6 @@ describe('log10', function () {
})
it('should return the log of positive bignumbers', function () {
- const bigmath = math.create({ precision: 100 })
-
assert.deepStrictEqual(bigmath.log10(bigmath.bignumber(1)), bigmath.bignumber(0))
assert.deepStrictEqual(bigmath.log10(bigmath.bignumber(10)), bigmath.bignumber(1))
assert.deepStrictEqual(bigmath.log10(bigmath.bignumber(100)), bigmath.bignumber(2))
@@ -55,16 +54,12 @@ describe('log10', function () {
})
it('should return the log of negative bignumbers', function () {
- const bigmath = math.create({ precision: 100 })
-
approxDeepEqual(bigmath.log10(bigmath.bignumber(-1)), bigmath.complex('0.000000000000000 + 1.364376353841841i'))
approxDeepEqual(bigmath.log10(bigmath.bignumber(-2)), bigmath.complex('0.301029995663981 + 1.364376353841841i'))
approxDeepEqual(bigmath.log10(bigmath.bignumber(-3)), bigmath.complex('0.477121254719662 + 1.364376353841841i'))
})
it('should return the log of a bignumber with value zero', function () {
- const bigmath = math.create({ precision: 100 })
-
assert.deepStrictEqual(bigmath.log10(bigmath.bignumber(0)).toString(), '-Infinity')
})
diff --git a/test/unit-tests/function/arithmetic/log1p.test.js b/test/unit-tests/function/arithmetic/log1p.test.js
index 552d37a1df..f307d28836 100644
--- a/test/unit-tests/function/arithmetic/log1p.test.js
+++ b/test/unit-tests/function/arithmetic/log1p.test.js
@@ -3,7 +3,8 @@ import assert from 'assert'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
import math from '../../../../src/defaultInstance.js'
-const mathPredictable = math.create({ predictable: true })
+const mathPredictable = math.create({ compute: { uniformType: true } })
+const bigmath = math.create({ compute: { BigNumber: { precision: 100 } } })
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
@@ -49,8 +50,6 @@ describe('log1p', function () {
})
it('should return the log1p of positive bignumbers', function () {
- const bigmath = math.create({ precision: 100 })
-
assert.deepStrictEqual(bigmath.log1p(bigmath.bignumber(-1)).toString(), '-Infinity')
assert.deepStrictEqual(bigmath.log1p(bigmath.bignumber(0)), bigmath.bignumber('0'))
assert.deepStrictEqual(bigmath.log1p(bigmath.bignumber(1)), bigmath.bignumber('0.6931471805599453094172321214581765680755001343602552541206800094933936219696947156058633269964186875'))
@@ -61,8 +60,6 @@ describe('log1p', function () {
})
it('should return the log1p of negative bignumbers', function () {
- const bigmath = math.create({ precision: 100 })
-
approxDeepEqual(bigmath.log1p(bigmath.bignumber(-2)), complex('0.000000000000000 + 3.141592653589793i'))
approxDeepEqual(bigmath.log1p(bigmath.bignumber(-3)), complex('0.693147180559945 + 3.141592653589793i'))
approxDeepEqual(bigmath.log1p(bigmath.bignumber(-4)), complex('1.098612288668110 + 3.141592653589793i'))
diff --git a/test/unit-tests/function/arithmetic/log2.test.js b/test/unit-tests/function/arithmetic/log2.test.js
index 332636dded..7e7bdfd501 100644
--- a/test/unit-tests/function/arithmetic/log2.test.js
+++ b/test/unit-tests/function/arithmetic/log2.test.js
@@ -3,7 +3,8 @@ import assert from 'assert'
import { approxDeepEqual } from '../../../../tools/approx.js'
import math from '../../../../src/defaultInstance.js'
-const mathPredictable = math.create({ predictable: true })
+const mathPredictable = math.create({ compute: { uniformType: true } })
+const bigmath = math.create({ compute: { BigNumber: { precision: 100 } } })
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
@@ -42,8 +43,6 @@ describe('log2', function () {
})
it('should return the log of positive bignumbers', function () {
- const bigmath = math.create({ precision: 100 })
-
assert.deepStrictEqual(bigmath.log2(bigmath.bignumber(1)), bigmath.bignumber(0))
assert.deepStrictEqual(bigmath.log2(bigmath.bignumber(2)), bigmath.bignumber(1))
assert.deepStrictEqual(bigmath.log2(bigmath.bignumber(4)), bigmath.bignumber(2))
@@ -53,16 +52,12 @@ describe('log2', function () {
})
it('should return the log of negative bignumbers', function () {
- const bigmath = math.create({ precision: 100 })
-
approxDeepEqual(bigmath.log2(bigmath.bignumber(-1)), bigmath.complex('0.000000000000000 + 4.532360141827194i'))
approxDeepEqual(bigmath.log2(bigmath.bignumber(-2)), bigmath.complex('1 + 4.532360141827194i'))
approxDeepEqual(bigmath.log2(bigmath.bignumber(-3)), bigmath.complex('1.584962500721156 + 4.532360141827194i'))
})
it('should return the log of a bignumber with value zero', function () {
- const bigmath = math.create({ precision: 100 })
-
assert.deepStrictEqual(bigmath.log2(bigmath.bignumber(0)).toString(), '-Infinity')
})
diff --git a/test/unit-tests/function/arithmetic/pow.test.js b/test/unit-tests/function/arithmetic/pow.test.js
index df0d80ceb6..2c494134b9 100644
--- a/test/unit-tests/function/arithmetic/pow.test.js
+++ b/test/unit-tests/function/arithmetic/pow.test.js
@@ -3,7 +3,8 @@ import assert from 'assert'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
import math from '../../../../src/defaultInstance.js'
-const mathPredictable = math.create({ predictable: true })
+
+const mathPredictable = math.create({ compute: { uniformType: true } })
const bignumber = math.bignumber
const fraction = math.fraction
const complex = math.complex
diff --git a/test/unit-tests/function/arithmetic/round.test.js b/test/unit-tests/function/arithmetic/round.test.js
index 30b03ee21a..49d3febeec 100644
--- a/test/unit-tests/function/arithmetic/round.test.js
+++ b/test/unit-tests/function/arithmetic/round.test.js
@@ -186,7 +186,7 @@ describe('round', function () {
})
it('uses updated config.relTol value', function () {
- math2.config({ relTol: 1e-13 })
+ math2.config({ compute: { defaultRelTol: 1e-13 } })
assert.strictEqual(math2.round((0.000000000001459), 12), 1e-12)
assert.deepStrictEqual(math2.round(bignumber(1.49e-12), bignumber(12)), bignumber(1e-12))
})
diff --git a/test/unit-tests/function/arithmetic/sqrt.test.js b/test/unit-tests/function/arithmetic/sqrt.test.js
index c6e3ba0e18..12f8feac76 100644
--- a/test/unit-tests/function/arithmetic/sqrt.test.js
+++ b/test/unit-tests/function/arithmetic/sqrt.test.js
@@ -2,7 +2,7 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
-const mathPredictable = math.create({ predictable: true })
+const mathPredictable = math.create({ compute: { uniformType: true } })
const sqrt = math.sqrt
const bignumber = math.bignumber
@@ -41,7 +41,7 @@ describe('sqrt', function () {
assert.deepStrictEqual(sqrt(bignumber(25)), bignumber(5))
// validate whether we are really working at high precision
- const bigmath = math.create({ precision: 100 })
+ const bigmath = math.create({ compute: { BigNumber: { precision: 100 } } })
assert.deepStrictEqual(bigmath.sqrt(bigmath.bignumber(2)), bigmath.bignumber('1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641573'))
})
diff --git a/test/unit-tests/function/arithmetic/unaryMinus.test.js b/test/unit-tests/function/arithmetic/unaryMinus.test.js
index 895091e290..afa3ed7237 100644
--- a/test/unit-tests/function/arithmetic/unaryMinus.test.js
+++ b/test/unit-tests/function/arithmetic/unaryMinus.test.js
@@ -2,6 +2,8 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
+import { bigConfig } from '../../configs.js'
+
const bignumber = math.bignumber
const fraction = math.fraction
const complex = math.complex
@@ -12,10 +14,8 @@ describe('unaryMinus', function () {
assert.strictEqual(math.unaryMinus(false), -0)
})
- // TODO: unary minus should return bignumber on boolean input when configured for bignumber
- // eslint-disable-next-line mocha/no-skipped-tests
- it.skip('should return bignumber unary minus of a boolean', function () {
- const bigmath = math.create({ number: 'BigNumber' })
+ it('should return bignumber unary minus of a boolean', function () {
+ const bigmath = math.create(bigConfig())
assert.deepStrictEqual(bigmath.unaryMinus(true), bigmath.bignumber(-1))
assert.deepStrictEqual(bigmath.unaryMinus(false), bigmath.bignumber(0))
})
diff --git a/test/unit-tests/function/arithmetic/unaryPlus.test.js b/test/unit-tests/function/arithmetic/unaryPlus.test.js
index c020308998..d24606395c 100644
--- a/test/unit-tests/function/arithmetic/unaryPlus.test.js
+++ b/test/unit-tests/function/arithmetic/unaryPlus.test.js
@@ -2,6 +2,8 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
+import { bigConfig } from '../../configs.js'
+
const bignumber = math.bignumber
const fraction = math.fraction
@@ -12,7 +14,7 @@ describe('unaryPlus', function () {
})
it('should return bignumber unary plus of a boolean', function () {
- const bigmath = math.create({ number: 'BigNumber' })
+ const bigmath = math.create(bigConfig())
assert.deepStrictEqual(bigmath.unaryPlus(true), bigmath.bignumber(1))
assert.deepStrictEqual(bigmath.unaryPlus(false), bigmath.bignumber(0))
})
@@ -23,7 +25,7 @@ describe('unaryPlus', function () {
})
it('should return bignumber unary plus on a string', function () {
- const bigmath = math.create({ number: 'BigNumber' })
+ const bigmath = math.create(bigConfig())
assert.deepStrictEqual(bigmath.unaryPlus('20000000000000000000001'), bigmath.bignumber('20000000000000000000001'))
assert.deepStrictEqual(bigmath.unaryPlus('-20000000000000000000001'), bigmath.bignumber('-20000000000000000000001'))
})
@@ -39,7 +41,7 @@ describe('unaryPlus', function () {
// TODO: this is temporary until the test above works again
it('should return bignumber unary plus on a string', function () {
- const bigmath = math.create({ number: 'BigNumber' })
+ const bigmath = math.create(bigConfig())
const a = bigmath.unaryPlus('2')
assert(a instanceof bigmath.BigNumber)
assert.deepStrictEqual(a.toString(), '2')
diff --git a/test/unit-tests/function/arithmetic/xgcd.test.js b/test/unit-tests/function/arithmetic/xgcd.test.js
index 57a6d6663b..dc0d016c0c 100644
--- a/test/unit-tests/function/arithmetic/xgcd.test.js
+++ b/test/unit-tests/function/arithmetic/xgcd.test.js
@@ -2,7 +2,7 @@
import assert from 'assert'
import defaultMath from '../../../../src/defaultInstance.js'
-const math = defaultMath.create({ matrix: 'Array' })
+const math = defaultMath.create({ compute: { Matrix: { defaultType: 'Array' } } })
const gcd = math.gcd
const xgcd = math.xgcd
@@ -80,10 +80,10 @@ describe('xgcd', function () {
})
it('should return a matrix when configured to use matrices', function () {
- const math1 = math.create({ matrix: 'Matrix' })
+ const math1 = math.create({ compute: { Matrix: { defaultType: 'Matrix' } } })
assert.deepStrictEqual(math1.xgcd(65, 40), math1.matrix([5, -3, 5]))
- const math2 = math.create({ matrix: 'Array' })
+ const math2 = math.create({ compute: { Matrix: { defaultType: 'Array' } } })
assert.deepStrictEqual(math2.xgcd(65, 40), [5, -3, 5])
})
diff --git a/test/unit-tests/function/arithmetic/zero.test.js b/test/unit-tests/function/arithmetic/zero.test.js
new file mode 100644
index 0000000000..9e6917d78f
--- /dev/null
+++ b/test/unit-tests/function/arithmetic/zero.test.js
@@ -0,0 +1,23 @@
+// test zero
+import assert from 'assert'
+
+import math from '../../../../src/defaultInstance.js'
+const zero = math.zero
+
+describe('zero', function () {
+ it('should return additive identity', function () {
+ assert.strictEqual(zero(-Infinity), 0)
+ assert.deepStrictEqual(zero(math.bignumber(7)), math.bignumber(0))
+ assert.strictEqual(zero(117n), 0n)
+ assert.deepStrictEqual(zero(math.complex(0, 1)), math.complex(0))
+ assert.strictEqual(zero(false), false)
+ assert.deepStrictEqual(zero(math.fraction(3, 10)), math.fraction(0))
+ assert.deepStrictEqual(zero(math.identity(3, 3)), math.zeros([3, 3]))
+ assert.deepStrictEqual(zero([1, 2, 3]), math.zeros([3]))
+ })
+
+ it('should zero the value of units', function () {
+ assert.deepStrictEqual(zero(math.unit(5, 'm')), math.unit(0, 'm'))
+ assert.deepStrictEqual(zero(math.evaluate('m')), math.unit(0, 'm'))
+ })
+})
diff --git a/test/unit-tests/function/geometry/distance.test.js b/test/unit-tests/function/geometry/distance.test.js
index f5cdbd6069..f47c3d9ebf 100644
--- a/test/unit-tests/function/geometry/distance.test.js
+++ b/test/unit-tests/function/geometry/distance.test.js
@@ -1,5 +1,6 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
+import { bigConfig } from '../../configs.js'
describe('distance', function () {
it('should calculate the distance of two 1D points', function () {
@@ -126,7 +127,7 @@ describe('distance', function () {
})
it('should calculate the distance if coordinates are bignumbers', function () {
- const bigmath = math.create({ number: 'BigNumber', precision: 32 })
+ const bigmath = math.create(bigConfig(32))
const bigdistance = bigmath.distance
const bignumber = bigmath.bignumber
diff --git a/test/unit-tests/function/geometry/intersect.test.js b/test/unit-tests/function/geometry/intersect.test.js
index 65768ef957..26fe30a09b 100644
--- a/test/unit-tests/function/geometry/intersect.test.js
+++ b/test/unit-tests/function/geometry/intersect.test.js
@@ -1,5 +1,6 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
+import { bigConfig } from '../../configs.js'
const fraction = math.fraction
@@ -52,7 +53,7 @@ describe('intersect', function () {
})
it('should calculate the intersection point if coordinates are bignumbers', function () {
- const bigmath = math.create({ number: 'BigNumber', precision: 32 })
+ const bigmath = math.create(bigConfig(32))
const bigintersect = bigmath.intersect
const bignumber = bigmath.bignumber
diff --git a/test/unit-tests/function/matrix/column.test.js b/test/unit-tests/function/matrix/column.test.js
index 6c6e3fed57..f707aa1c6b 100644
--- a/test/unit-tests/function/matrix/column.test.js
+++ b/test/unit-tests/function/matrix/column.test.js
@@ -124,7 +124,8 @@ describe('column', function () {
[0, 0, 0, 6, 0]
]
// Test column with legacySubset syntax
- // This is not strictly necessary and shoudl be removed after the deprecation period
+ // This is not strictly necessary and should be removed,
+ // after the deprecation period
assert.deepStrictEqual(
math2.column(a, 4).valueOf(), [[0], [4], [0], [0], [0]]
diff --git a/test/unit-tests/function/matrix/eigs.test.js b/test/unit-tests/function/matrix/eigs.test.js
index 03fc5b8b5d..95c95bbe4b 100644
--- a/test/unit-tests/function/matrix/eigs.test.js
+++ b/test/unit-tests/function/matrix/eigs.test.js
@@ -214,7 +214,7 @@ describe('eigs', function () {
approxEqual(ev[1].value, 2)
approxEqual(ev[0].vector[0], 0)
approxEqual(ev[0].vector[1], 0)
- assert.ok(abs(ev[0].vector[2]) > math.config.relTol)
+ assert.ok(abs(ev[0].vector[2]) > math.config.compute.defaultRelTol)
approxEqual(ev[1].vector[0], -ev[1].vector[2])
approxEqual(ev[1].vector[1], 0)
const web2 = eigs([[1, 1, 0], [0, 1, 2], [0, 0, 3]]) // https://www2.math.upenn.edu/~moose/240S2013/slides7-31.pdf
@@ -224,7 +224,7 @@ describe('eigs', function () {
assert.strictEqual(ev2[1].value, 3)
assert.strictEqual(ev2[0].vector[1], 0)
assert.strictEqual(ev2[0].vector[2], 0)
- assert.ok(abs(ev2[0].vector[0]) > math.config.relTol)
+ assert.ok(abs(ev2[0].vector[0]) > math.config.compute.defaultRelTol)
assert.strictEqual(ev2[1].vector[1], ev2[1].vector[2])
approxEqual(ev2[1].vector[1], 2 * ev2[1].vector[0])
})
diff --git a/test/unit-tests/function/matrix/identity.test.js b/test/unit-tests/function/matrix/identity.test.js
index 0604c81a8c..9bcfd354e2 100644
--- a/test/unit-tests/function/matrix/identity.test.js
+++ b/test/unit-tests/function/matrix/identity.test.js
@@ -46,7 +46,7 @@ describe('identity', function () {
})
it('should return an array when setting matrix=="array"', function () {
- const math2 = math.create({ matrix: 'Array' })
+ const math2 = math.create({ compute: { Matrix: { defaultType: 'Array' } } })
assert.deepStrictEqual(math2.identity(2), [[1, 0], [0, 1]])
})
diff --git a/test/unit-tests/function/matrix/range.test.js b/test/unit-tests/function/matrix/range.test.js
index ac9eff92e5..27f6d879d6 100644
--- a/test/unit-tests/function/matrix/range.test.js
+++ b/test/unit-tests/function/matrix/range.test.js
@@ -1,5 +1,7 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
+import { bigConfig } from '../../configs.js'
+
const range = math.range
const matrix = math.matrix
const bignumber = math.bignumber
@@ -59,9 +61,7 @@ describe('range', function () {
})
it('should output an array when setting matrix==="array"', function () {
- const math2 = math.create({
- matrix: 'Array'
- })
+ const math2 = math.create({ compute: { Matrix: { defaultType: 'Array' } } })
assert.deepStrictEqual(math2.range(0, 10, 2), [0, 2, 4, 6, 8])
assert.deepStrictEqual(math2.range(5, 0, -1), [5, 4, 3, 2, 1])
@@ -109,7 +109,7 @@ describe('range', function () {
})
it('should parse a range with bignumbers', function () {
- const bigmath = math.create({ number: 'BigNumber' })
+ const bigmath = math.create(bigConfig())
const bignumber = bigmath.bignumber
const matrix = bigmath.matrix
assert.deepStrictEqual(bigmath.range('1:3'), matrix([bignumber(1), bignumber(2)]))
@@ -117,7 +117,7 @@ describe('range', function () {
})
it('should throw an error when parsing a an invalid string to a bignumber range', function () {
- const bigmath = math.create({ number: 'BigNumber' })
+ const bigmath = math.create(bigConfig())
assert.throws(function () { bigmath.range('1:a') }, /is no valid range/)
})
diff --git a/test/unit-tests/function/matrix/reshape.test.js b/test/unit-tests/function/matrix/reshape.test.js
index 13e187781d..fdb6d901d3 100644
--- a/test/unit-tests/function/matrix/reshape.test.js
+++ b/test/unit-tests/function/matrix/reshape.test.js
@@ -2,6 +2,8 @@ import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { DimensionError } from '../../../../src/error/DimensionError.js'
+const math2 = math.create({ compute: { Matrix: { defaultType: 'Array' } } })
+
describe('reshape', function () {
it('should reshape an array', function () {
const array = [[0, 1, 2], [3, 4, 5]]
@@ -38,12 +40,10 @@ describe('reshape', function () {
})
it('should reshape a vector into a 2d matrix', function () {
- const math2 = math.create({ matrix: 'Array' })
assert.deepStrictEqual(math2.reshape([1, 2, 3, 4, 5, 6], [3, 2]), [[1, 2], [3, 4], [5, 6]])
})
it('should reshape 2d matrix into a vector', function () {
- const math2 = math.create({ matrix: 'Array' })
assert.deepStrictEqual(math2.reshape([[1, 2], [3, 4], [5, 6]], [6]), [1, 2, 3, 4, 5, 6])
})
diff --git a/test/unit-tests/function/matrix/resize.test.js b/test/unit-tests/function/matrix/resize.test.js
index 5f586c8c49..aa03d44a02 100644
--- a/test/unit-tests/function/matrix/resize.test.js
+++ b/test/unit-tests/function/matrix/resize.test.js
@@ -2,6 +2,7 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
+const math2 = math.create({ compute: { Matrix: { defaultType: 'Array' } } })
describe('resize', function () {
it('should resize an array', function () {
@@ -63,21 +64,15 @@ describe('resize', function () {
})
it('should resize a scalar into an array when array is specified in settings', function () {
- const math2 = math.create({ matrix: 'Array' })
-
assert.deepStrictEqual(math2.resize(2, [3], 4), [2, 4, 4])
assert.deepStrictEqual(math2.resize(2, [2, 2], 4), [[2, 4], [4, 4]])
})
it('should resize a vector into a 2d matrix', function () {
- const math2 = math.create({ matrix: 'Array' })
-
assert.deepStrictEqual(math2.resize([1, 2, 3], [3, 2], 0), [[1, 0], [2, 0], [3, 0]])
})
it('should resize 2d matrix into a vector', function () {
- const math2 = math.create({ matrix: 'Array' })
-
assert.deepStrictEqual(math2.resize([[1, 2], [3, 4], [5, 6]], [3], 0), [1, 3, 5])
})
diff --git a/test/unit-tests/function/matrix/rotate.test.js b/test/unit-tests/function/matrix/rotate.test.js
index be364b5736..2ffed7051b 100644
--- a/test/unit-tests/function/matrix/rotate.test.js
+++ b/test/unit-tests/function/matrix/rotate.test.js
@@ -1,6 +1,7 @@
import assert from 'assert'
import { approxDeepEqual } from '../../../../tools/approx.js'
import math from '../../../../src/defaultInstance.js'
+import { bigConfig } from '../../configs.js'
const unit = math.unit
const complex = math.complex
@@ -55,7 +56,7 @@ describe('rotate', function () {
})
it('should return a rotated 1x2 bignumber vector', function () {
- const bigmath = math.create({ number: 'BigNumber' })
+ const bigmath = math.create(bigConfig())
const minusOne = bigmath.bignumber(-1)
const cos1 = bigmath.cos(bigmath.bignumber(1))
const sin1 = bigmath.sin(bigmath.bignumber(1))
@@ -121,7 +122,7 @@ describe('rotate', function () {
})
it('should return a rotated 1x3 bignumber vector', function () {
- const bigmath = math.create({ number: 'BigNumber' })
+ const bigmath = math.create(bigConfig())
const minusOne = bigmath.bignumber(-1)
const cos1 = bigmath.cos(bigmath.bignumber(1))
const sin1 = bigmath.sin(bigmath.bignumber(1))
diff --git a/test/unit-tests/function/matrix/rotationMatrix.test.js b/test/unit-tests/function/matrix/rotationMatrix.test.js
index 4355e11c52..c2b5d69cdc 100644
--- a/test/unit-tests/function/matrix/rotationMatrix.test.js
+++ b/test/unit-tests/function/matrix/rotationMatrix.test.js
@@ -1,6 +1,7 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
const bignumber = math.bignumber
const complex = math.complex
@@ -20,7 +21,7 @@ describe('rotationMatrix', function () {
assert.deepStrictEqual(rotationMatrix('sparse'), matrix('sparse'))
assert.deepStrictEqual(rotationMatrix('dense'), matrix('dense'))
- const mathArray = math.create({ matrix: 'Array' })
+ const mathArray = math.create({ compute: { Matrix: { defaultType: 'Array' } } })
assert.deepStrictEqual(mathArray.rotationMatrix(), [])
})
@@ -32,7 +33,7 @@ describe('rotationMatrix', function () {
})
it('should return a 2D rotation array if requesting results as array', function () {
- const mathArray = math.create({ matrix: 'Array' })
+ const mathArray = math.create({ compute: { Matrix: { defaultType: 'Array' } } })
approxDeepEqual(mathArray.rotationMatrix(0.0), [[1, 0.0], [0.0, 1]])
approxDeepEqual(mathArray.rotationMatrix(mathArray.pi / 2), [[0.0, -1], [1, 0.0]])
approxDeepEqual(mathArray.rotationMatrix(1), [[cos(1), -sin(1)], [sin(1), cos(1)]])
@@ -42,7 +43,7 @@ describe('rotationMatrix', function () {
it('should create a 2D rotation matrix of given bignumber angle', function () {
approxDeepEqual(rotationMatrix(bignumber(0.0)), matrix([[1, 0.0], [0.0, 1]]))
- const bigmath = math.create({ number: 'BigNumber' })
+ const bigmath = math.create(bigConfig())
const minusOne = bigmath.bignumber(-1)
const cos1 = bigmath.cos(bigmath.bignumber(1))
const sin1 = bigmath.sin(bigmath.bignumber(1))
@@ -233,7 +234,7 @@ describe('rotationMatrix', function () {
})
it('should return an array when mathjs is configured for this', function () {
- const mathArray = math.create({ matrix: 'Array' })
+ const mathArray = math.create({ compute: { Matrix: { defaultType: 'Array' } } })
approxDeepEqual(mathArray.rotationMatrix(mathArray.pi / 4),
[[sqrtTwoInv, minusSqrtTwoInv], [sqrtTwoInv, sqrtTwoInv]])
approxDeepEqual(mathArray.rotationMatrix(mathArray.pi / 2, [0, 0, 1]),
@@ -248,7 +249,7 @@ describe('rotationMatrix', function () {
assert.throws(function () { rotationMatrix(0, []) }, /RangeError: Vector must be of dimensions 1x3/)
assert.throws(function () { rotationMatrix(0, [1]) }, /RangeError: Vector must be of dimensions 1x3/)
assert.throws(function () { rotationMatrix(0, [0, 1]) }, /RangeError: Vector must be of dimensions 1x3/)
- assert.throws(function () { rotationMatrix(0, [0, 1, 0], 'something') }, /TypeError: Unknown matrix type/)
+ assert.throws(function () { rotationMatrix(0, [0, 1, 0], 'something') }, /TypeError:.*matrix type/)
assert.throws(function () { rotationMatrix(0, [0, 1, 0], 'sparse', 4) }, /TypeError: Too many arguments/)
assert.throws(function () { rotationMatrix(1, [0.0, 0.0, 0.0]) }, /Rotation around zero vector/)
})
diff --git a/test/unit-tests/function/matrix/size.test.js b/test/unit-tests/function/matrix/size.test.js
index a01f6eaef7..75517a1221 100644
--- a/test/unit-tests/function/matrix/size.test.js
+++ b/test/unit-tests/function/matrix/size.test.js
@@ -45,7 +45,7 @@ describe('size', function () {
})
it('should calculate the size of a scalar with setting matrix=="array"', function () {
- const math2 = math.create({ matrix: 'Array' })
+ const math2 = math.create({ compute: { Matrix: { defaultType: 'Array' } } })
assert.deepStrictEqual(math2.size(2), [])
assert.deepStrictEqual(math2.size(math2.bignumber(2)), [])
assert.deepStrictEqual(math2.size(math2.complex(2, 3)), [])
diff --git a/test/unit-tests/function/matrix/subset.test.js b/test/unit-tests/function/matrix/subset.test.js
index a99fcfcac4..f46778b66f 100644
--- a/test/unit-tests/function/matrix/subset.test.js
+++ b/test/unit-tests/function/matrix/subset.test.js
@@ -268,12 +268,12 @@ describe('subset', function () {
assert.strictEqual(expression.toTex(), '\\mathrm{subset}\\left(\\begin{bmatrix}1\\end{bmatrix},\\mathrm{index}\\left(0,0\\right)\\right)')
})
- it('should work with config legacySubset during deprecation', function () {
+ it('should work with compatibility config subset during deprecation', function () {
const math2 = math.create()
// Add a spy to temporarily disable console.warn
const warnStub = sinon.stub(console, 'warn')
- math2.config({ legacySubset: true })
+ math2.config({ compatibility: { subset: true } })
// Test legacy syntax for getting a subset of a matrix
const A = math2.matrix([[1, 2, 3], [4, 5, 6]])
@@ -285,7 +285,7 @@ describe('subset', function () {
assert.deepStrictEqual(math2.subset(A, index(1, [1, 2])).toArray(), [[5, 6]])
assert.deepStrictEqual(math2.subset(A, index([0, 1], 1)).toArray(), [[2], [5]])
- math2.config({ legacySubset: false })
+ math2.config({ compatibility: { subset: false } })
// Test without legacy syntax
assert.deepStrictEqual(math2.subset(A, index(1, 2)), 6)
assert.deepStrictEqual(math2.subset(A, index([1], 2)).toArray(), [6])
diff --git a/test/unit-tests/function/probability/factorial.test.js b/test/unit-tests/function/probability/factorial.test.js
index dde6bf970c..8f25457077 100644
--- a/test/unit-tests/function/probability/factorial.test.js
+++ b/test/unit-tests/function/probability/factorial.test.js
@@ -1,6 +1,8 @@
import assert from 'assert'
import { approxEqual } from '../../../../tools/approx.js'
import math from '../../../../src/defaultInstance.js'
+import { bigConfig } from '../../configs.js'
+
const factorial = math.factorial
describe('factorial', function () {
@@ -16,7 +18,7 @@ describe('factorial', function () {
})
it('should calculate the factorial of a bignumber', function () {
- const bigmath = math.create({ number: 'BigNumber', precision: 5 })
+ const bigmath = math.create(bigConfig(5))
assert.deepStrictEqual(bigmath.factorial(bigmath.bignumber(0)), bigmath.bignumber(1))
assert.deepStrictEqual(bigmath.factorial(bigmath.bignumber(Infinity)).toString(), 'Infinity')
assert.deepStrictEqual(bigmath.factorial(bigmath.bignumber(11)), bigmath.bignumber(39917000))
@@ -24,7 +26,7 @@ describe('factorial', function () {
assert.deepStrictEqual(bigmath.factorial(bigmath.bignumber(24)), bigmath.bignumber(6.2045e+23))
assert.deepStrictEqual(bigmath.factorial(bigmath.bignumber(26)), bigmath.bignumber(4.0329e+26))
- const bigmath20 = bigmath.create({ precision: 20 })
+ const bigmath20 = bigmath.create(bigConfig(20))
assert.deepStrictEqual(bigmath20.factorial(bigmath20.bignumber(5)), bigmath20.bignumber(120))
assert.deepStrictEqual(bigmath20.factorial(bigmath20.bignumber(19)), bigmath20.bignumber(121645100408832000))
assert.deepStrictEqual(bigmath20.factorial(bigmath20.bignumber(20)), bigmath20.bignumber(2432902008176640000))
diff --git a/test/unit-tests/function/probability/gamma.test.js b/test/unit-tests/function/probability/gamma.test.js
index b200ead627..09c1595767 100644
--- a/test/unit-tests/function/probability/gamma.test.js
+++ b/test/unit-tests/function/probability/gamma.test.js
@@ -76,10 +76,10 @@ describe('gamma', function () {
assert.deepStrictEqual(gamma(bignumber(1.5)), bignumber('0.886226925452758'))
assert.deepStrictEqual(gamma(bignumber(2.5)), bignumber('1.32934038817914'))
- const bigmath = math.create({ precision: 15 })
+ const bigmath = math.create({ compute: { BigNumber: { precision: 15 } } })
assert.deepStrictEqual(bigmath.gamma(bignumber(30.5)), '4.82269693349091e+31')
- bigmath.config({ precision: 13 })
+ bigmath.config({ compute: { BigNumber: { precision: 13 } } })
assert.deepStrictEqual(bigmath.gamma(bignumber(-1.5)), bigmath.bignumber('2.363271801207'))
assert.deepStrictEqual(gamma(bignumber(-2.5)), bignumber('-0.9453087205'))
})
diff --git a/test/unit-tests/function/probability/pickRandom.test.js b/test/unit-tests/function/probability/pickRandom.test.js
index 8b4581a98e..379243fd27 100644
--- a/test/unit-tests/function/probability/pickRandom.test.js
+++ b/test/unit-tests/function/probability/pickRandom.test.js
@@ -2,7 +2,7 @@ import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { flatten } from '../../../../src/utils/array.js'
-const math2 = math.create({ randomSeed: 'test2' })
+const math2 = math.create({ compute: { randomSeed: 'test2' } })
const pickRandom = math2.pickRandom
const matrix = math2.matrix
diff --git a/test/unit-tests/function/probability/random.test.js b/test/unit-tests/function/probability/random.test.js
index 201d87639a..f91ef0414d 100644
--- a/test/unit-tests/function/probability/random.test.js
+++ b/test/unit-tests/function/probability/random.test.js
@@ -1,7 +1,7 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
-const math2 = math.create({ randomSeed: 'test' })
+const math2 = math.create({ compute: { randomSeed: 'test2' } })
const random = math2.random
const Matrix = math2.Matrix
diff --git a/test/unit-tests/function/probability/randomInt.test.js b/test/unit-tests/function/probability/randomInt.test.js
index b9cb07ebec..36956c144b 100644
--- a/test/unit-tests/function/probability/randomInt.test.js
+++ b/test/unit-tests/function/probability/randomInt.test.js
@@ -1,7 +1,7 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
-const math2 = math.create({ randomSeed: 'test' })
+const math2 = math.create({ compute: { randomSeed: 'test' } })
const randomInt = math2.randomInt
describe('randomInt', function () {
diff --git a/test/unit-tests/function/probability/seededrandom.test.js b/test/unit-tests/function/probability/seededrandom.test.js
index b150682343..4dd54bd3ca 100644
--- a/test/unit-tests/function/probability/seededrandom.test.js
+++ b/test/unit-tests/function/probability/seededrandom.test.js
@@ -1,44 +1,48 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
+function seed (x) {
+ return { compute: { randomSeed: x } }
+}
+
describe('seed', function () {
it('should generate same number with seed', function () {
- const math1 = math.create({ randomSeed: 'a' })
+ const math1 = math.create(seed('a'))
const first = math1.random()
- const math2 = math.create({ randomSeed: 'a' })
+ const math2 = math.create(seed('a'))
const second = math2.random()
assert.strictEqual(first, second)
})
it('should generate different number subsequent calls to seeded random', function () {
- const math2 = math.create({ randomSeed: 'a' })
+ const math2 = math.create(seed('a'))
const first = math2.random()
const second = math2.random()
assert.notStrictEqual(first, second)
})
it('calling with no parameters should unseed rng', function () {
- const math1 = math.create({ randomSeed: 'a' })
+ const math1 = math.create(seed('a'))
const firstA = math1.random()
const secondA = math1.random()
- const math2 = math.create({ randomSeed: 'a' })
+ const math2 = math.create(seed('a'))
const firstB = math2.random()
- const math3 = math.create({ randomSeed: null })
+ const math3 = math.create(seed(null))
const secondB = math3.random()
assert.strictEqual(firstA, firstB)
assert.notStrictEqual(secondA, secondB)
})
it('should generate same matrix with seed', function () {
- const math1 = math.create({ randomSeed: 'a' })
+ const math1 = math.create(seed('a'))
const first = math1.random([5, 5])
- const math2 = math.create({ randomSeed: 'a' })
+ const math2 = math.create(seed('a'))
const second = math2.random([5, 5])
assert.strictEqual(math.deepEqual(first, second), true)
})
it('should generate different matrices subsequent calls to seeded random', function () {
- const math2 = math.create({ randomSeed: 'a' })
+ const math2 = math.create(seed('a'))
const first = math2.random([5, 5])
const second = math2.random([5, 5])
assert.strictEqual(math.deepEqual(first, second), false)
@@ -46,9 +50,9 @@ describe('seed', function () {
it('should pick same number with seed', function () {
const range = math.range(1, 1000)
- const math1 = math.create({ randomSeed: 'a' })
+ const math1 = math.create(seed('a'))
const first = math1.pickRandom(range)
- const math2 = math.create({ randomSeed: 'a' })
+ const math2 = math.create(seed('a'))
const second = math2.pickRandom(range)
assert.strictEqual(first, second)
})
@@ -56,39 +60,39 @@ describe('seed', function () {
it('should pick different number subsequent calls to seeded random', function () {
// In theory these might be the same but with 'a' as seed they are different and always will be
const range = math.range(1, 1000)
- const math2 = math.create({ randomSeed: 'a' })
+ const math2 = math.create(seed('a'))
const first = math2.pickRandom(range)
const second = math2.pickRandom(range)
assert.notStrictEqual(first, second)
})
it('should pick same int with seed', function () {
- const math1 = math.create({ randomSeed: 'a' })
+ const math1 = math.create(seed('a'))
const first = math1.randomInt(1, 100)
- const math2 = math.create({ randomSeed: 'a' })
+ const math2 = math.create(seed('a'))
const second = math2.randomInt(1, 100)
assert.strictEqual(first, second)
})
it('should pick different int subsequent calls to seeded random', function () {
- const math2 = math.create({ randomSeed: 'a' })
+ const math2 = math.create(seed('a'))
const first = math2.randomInt(1, 100)
const second = math2.randomInt(1, 100)
assert.notStrictEqual(first, second)
})
it('should work for number seeds', function () {
- const math1 = math.create({ randomSeed: 1 })
+ const math1 = math.create(seed(1))
const first = math1.random()
- const math2 = math.create({ randomSeed: 1 })
+ const math2 = math.create(seed(1))
const second = math2.random()
assert.strictEqual(first, second)
})
it('should work for object seeds', function () {
- const math1 = math.create({ randomSeed: { a: 1 } })
+ const math1 = math.create(seed({ a: 1 }))
const first = math1.random()
- const math2 = math.create({ randomSeed: { a: 1 } })
+ const math2 = math.create(seed({ a: 1 }))
const second = math2.random()
assert.strictEqual(first, second)
})
diff --git a/test/unit-tests/function/relational/compare.test.js b/test/unit-tests/function/relational/compare.test.js
index 9439a6f849..38c34f24c6 100644
--- a/test/unit-tests/function/relational/compare.test.js
+++ b/test/unit-tests/function/relational/compare.test.js
@@ -203,7 +203,7 @@ describe('compare', function () {
assert.strictEqual(mymath.compare(1, 0.991), 1)
assert.strictEqual(mymath.compare(mymath.bignumber(1), mymath.bignumber(0.991)).valueOf(), '1')
- mymath.config({ relTol: 1e-2 })
+ mymath.config({ compute: { defaultRelTol: 1e-2 } })
assert.strictEqual(mymath.compare(1, 0.991), 0)
assert.strictEqual(mymath.compare(mymath.bignumber(1), mymath.bignumber(0.991)).valueOf(), '0')
})
diff --git a/test/unit-tests/function/relational/compareNatural.test.js b/test/unit-tests/function/relational/compareNatural.test.js
index cbe82244c1..47ffd2322a 100644
--- a/test/unit-tests/function/relational/compareNatural.test.js
+++ b/test/unit-tests/function/relational/compareNatural.test.js
@@ -225,7 +225,7 @@ describe('compareNatural', function () {
assert.strictEqual(mymath.compareNatural(1, 0.991), 1)
assert.strictEqual(mymath.compareNatural(mymath.bignumber(1), mymath.bignumber(0.991)).valueOf(), 1)
- mymath.config({ relTol: 1e-2 })
+ mymath.config({ compute: { defaultRelTol: 1e-2 } })
assert.strictEqual(mymath.compareNatural(1, 0.991), 0)
assert.strictEqual(mymath.compareNatural(mymath.bignumber(1), mymath.bignumber(0.991)), 0)
})
diff --git a/test/unit-tests/function/relational/equal.test.js b/test/unit-tests/function/relational/equal.test.js
index 018e7a3951..93685e4520 100644
--- a/test/unit-tests/function/relational/equal.test.js
+++ b/test/unit-tests/function/relational/equal.test.js
@@ -167,7 +167,7 @@ describe('equal', function () {
assert.strictEqual(mymath.equal(mymath.bignumber(1), mymath.bignumber(0.991)), false)
assert.strictEqual(mymath.equal(mymath.complex(1, 0), mymath.complex(0.991, 0)), false)
- mymath.config({ relTol: 1e-2 })
+ mymath.config({ compute: { defaultRelTol: 1e-2 } })
assert.strictEqual(mymath.equal(1, 0.991), true)
assert.strictEqual(mymath.equal(mymath.bignumber(1), mymath.bignumber(0.991)), true)
assert.strictEqual(mymath.equal(mymath.complex(1, 0), mymath.complex(0.991, 0)), true)
diff --git a/test/unit-tests/function/relational/larger.test.js b/test/unit-tests/function/relational/larger.test.js
index 07f663c586..dfaca3e095 100644
--- a/test/unit-tests/function/relational/larger.test.js
+++ b/test/unit-tests/function/relational/larger.test.js
@@ -127,7 +127,7 @@ describe('larger', function () {
assert.strictEqual(mymath.larger(1, 0.991), true)
assert.strictEqual(mymath.larger(mymath.bignumber(1), mymath.bignumber(0.991)), true)
- mymath.config({ relTol: 1e-2 })
+ mymath.config({ compute: { defaultRelTol: 1e-2 } })
assert.strictEqual(mymath.larger(1, 0.991), false)
assert.strictEqual(mymath.larger(mymath.bignumber(1), mymath.bignumber(0.991)), false)
})
diff --git a/test/unit-tests/function/relational/largerEq.test.js b/test/unit-tests/function/relational/largerEq.test.js
index e2d7af0ceb..12b4ac43b5 100644
--- a/test/unit-tests/function/relational/largerEq.test.js
+++ b/test/unit-tests/function/relational/largerEq.test.js
@@ -120,7 +120,7 @@ describe('largerEq', function () {
assert.strictEqual(mymath.largerEq(1, 1.01), false)
assert.strictEqual(mymath.largerEq(mymath.bignumber(1), mymath.bignumber(1.01)), false)
- mymath.config({ relTol: 1e-2 })
+ mymath.config({ compute: { defaultRelTol: 1e-2 } })
assert.strictEqual(mymath.largerEq(1, 1.01), true)
assert.strictEqual(mymath.largerEq(mymath.bignumber(1), mymath.bignumber(1.01)), true)
})
diff --git a/test/unit-tests/function/relational/smaller.test.js b/test/unit-tests/function/relational/smaller.test.js
index bdeedf268c..fcc7faaa91 100644
--- a/test/unit-tests/function/relational/smaller.test.js
+++ b/test/unit-tests/function/relational/smaller.test.js
@@ -131,7 +131,7 @@ describe('smaller', function () {
assert.strictEqual(mymath.smaller(0.991, 1), true)
assert.strictEqual(mymath.smaller(mymath.bignumber(0.991), mymath.bignumber(1)), true)
- mymath.config({ relTol: 1e-2 })
+ mymath.config({ compute: { defaultRelTol: 1e-2 } })
assert.strictEqual(mymath.smaller(0.991, 1), false)
assert.strictEqual(mymath.smaller(mymath.bignumber(0.991), mymath.bignumber(1)), false)
})
diff --git a/test/unit-tests/function/relational/smallerEq.test.js b/test/unit-tests/function/relational/smallerEq.test.js
index be6d5fa0dc..d22ac4eba9 100644
--- a/test/unit-tests/function/relational/smallerEq.test.js
+++ b/test/unit-tests/function/relational/smallerEq.test.js
@@ -124,7 +124,7 @@ describe('smallerEq', function () {
assert.strictEqual(mymath.smallerEq(1.01, 1), false)
assert.strictEqual(mymath.smallerEq(mymath.bignumber(1.01), mymath.bignumber(1)), false)
- mymath.config({ relTol: 1e-2 })
+ mymath.config({ compute: { defaultRelTol: 1e-2 } })
assert.strictEqual(mymath.smallerEq(1.01, 1), true)
assert.strictEqual(mymath.smallerEq(mymath.bignumber(1.01), mymath.bignumber(1)), true)
})
diff --git a/test/unit-tests/function/relational/unequal.test.js b/test/unit-tests/function/relational/unequal.test.js
index 1bb5b360f8..ad5bf6fa59 100644
--- a/test/unit-tests/function/relational/unequal.test.js
+++ b/test/unit-tests/function/relational/unequal.test.js
@@ -154,7 +154,7 @@ describe('unequal', function () {
assert.strictEqual(mymath.unequal(mymath.bignumber(1), mymath.bignumber(0.991)), true)
assert.strictEqual(mymath.unequal(mymath.complex(1, 0), mymath.complex(0.991, 0)), true)
- mymath.config({ relTol: 1e-2 })
+ mymath.config({ compute: { defaultRelTol: 1e-2 } })
assert.strictEqual(mymath.unequal(1, 0.991), false)
assert.strictEqual(mymath.unequal(mymath.bignumber(1), mymath.bignumber(0.991)), false)
assert.strictEqual(mymath.unequal(mymath.complex(1, 0), mymath.complex(0.991, 0)), false)
diff --git a/test/unit-tests/function/special/zeta.test.js b/test/unit-tests/function/special/zeta.test.js
index ad1200edad..a82fab85b3 100644
--- a/test/unit-tests/function/special/zeta.test.js
+++ b/test/unit-tests/function/special/zeta.test.js
@@ -35,7 +35,9 @@ describe('Riemann Zeta', function () {
const digits = Math.abs(Math.log10(bigEpsilon))
const math2 = math.create()
- math2.config({ relTol: bigEpsilon, absTol: bigEpsilon * 1e-3 })
+ math2.config({
+ compute: { defaultRelTol: bigEpsilon, defaultAbsTol: bigEpsilon * 1e-3 }
+ })
function bigApproxEqual (a, b) {
assert.strictEqual(
diff --git a/test/unit-tests/function/statistics/max.test.js b/test/unit-tests/function/statistics/max.test.js
index 162a2317f1..0f9cd772b8 100644
--- a/test/unit-tests/function/statistics/max.test.js
+++ b/test/unit-tests/function/statistics/max.test.js
@@ -1,5 +1,7 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
+import { bigConfig } from '../../configs.js'
+
const BigNumber = math.BigNumber
const Complex = math.Complex
const DenseMatrix = math.DenseMatrix
@@ -21,23 +23,23 @@ describe('max', function () {
new BigNumber(5))
})
- it('should return the max of strings by their numerical value', function () {
+ it('should return the max of strings by conversion to numeric argument I', function () {
assert.strictEqual(max('10', '3', '4', '2'), 10)
assert.strictEqual(max('10'), 10)
})
- it('should return the max of strings by their numerical value (with BigNumber config)', function () {
- const bigmath = math.create({ number: 'BigNumber' })
- assert.deepStrictEqual(bigmath.max('10', '3', '4', '2'), bigmath.bignumber(10))
- assert.deepStrictEqual(bigmath.max('10'), bigmath.bignumber(10))
+ it('should return the max of strings by conversion to numeric argument II', function () {
+ const bigmath = math.create(bigConfig())
+ assert.deepStrictEqual(bigmath.max('10', '3', '4', '2'), 10)
+ assert.deepStrictEqual(bigmath.max('10'), 10)
})
- it('should return the max of strings by their numerical value (with bigint config)', function () {
+ it('should return the max of strings by conversion to numeric argument III', function () {
const bigmath = math.create({ number: 'bigint' })
- assert.strictEqual(bigmath.max('10', '3', '4', '2'), 10n)
- assert.strictEqual(bigmath.max('10'), 10n)
- assert.strictEqual(bigmath.max('2.5'), 2.5) // fallback to number
- assert.strictEqual(bigmath.max('2.5', '4'), 4n) // fallback to number
+ assert.strictEqual(bigmath.max('10', '3', '4', '2'), 10)
+ assert.strictEqual(bigmath.max('10'), 10)
+ assert.strictEqual(bigmath.max('2.5'), 2.5)
+ assert.strictEqual(bigmath.max('2.5', '4'), 4)
})
it('should return the max element from a vector', function () {
@@ -130,12 +132,12 @@ describe('max', function () {
assert.throws(function () { max([[2, new Date(), 4]]) }, /TypeError: Cannot calculate max, unexpected type of argument/)
assert.throws(function () { max([2, null, 4]) }, /TypeError: Cannot calculate max, unexpected type of argument/)
assert.throws(function () { max([[2, 5], [4, null], [1, 7]], 0) }, /TypeError: Cannot calculate max, unexpected type of argument/)
- assert.throws(function () { max('a', 'b') }, /Error: Cannot convert "a" to a number/)
- assert.throws(function () { max('a') }, /Error: Cannot convert "a" to a number/)
+ assert.throws(function () { max('a', 'b') }, /Error: Cannot convert "a"/)
+ assert.throws(function () { max('a') }, /Error: Cannot convert "a"/)
})
- it('should return undefined if called with an empty array', function () {
- assert.throws(function () { max([]) })
+ it('should return -Infinity if called with an empty array', function () {
+ assert.strictEqual(max([]), -Infinity)
})
it('should LaTeX max', function () {
diff --git a/test/unit-tests/function/statistics/min.test.js b/test/unit-tests/function/statistics/min.test.js
index 0beb31babc..04cf0f9306 100644
--- a/test/unit-tests/function/statistics/min.test.js
+++ b/test/unit-tests/function/statistics/min.test.js
@@ -1,5 +1,7 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
+import { bigConfig } from '../../configs.js'
+
const BigNumber = math.BigNumber
const Complex = math.Complex
const DenseMatrix = math.DenseMatrix
@@ -16,23 +18,23 @@ describe('min', function () {
assert.strictEqual(min(0, 0, 0, 0), 0)
})
- it('should return the min of strings by their numerical value', function () {
+ it('should return the min of strings by conversion to numeric argument I', function () {
assert.strictEqual(min('10', '3', '4', '2'), 2)
assert.strictEqual(min('10'), 10)
})
- it('should return the max of strings by their numerical value (with BigNumber config)', function () {
- const bigmath = math.create({ number: 'BigNumber' })
- assert.deepStrictEqual(bigmath.min('10', '3', '4', '2'), bigmath.bignumber(2))
- assert.deepStrictEqual(bigmath.min('10'), bigmath.bignumber(10))
+ it('should return the max of strings by conversion to numeric argument II', function () {
+ const bigmath = math.create(bigConfig())
+ assert.deepStrictEqual(bigmath.min('10', '3', '4', '2'), 2)
+ assert.deepStrictEqual(bigmath.min('10'), 10)
})
- it('should return the max of strings by their numerical value (with bigint config)', function () {
+ it('should return the min of strings by conversion to numeric argument III', function () {
const bigmath = math.create({ number: 'bigint' })
- assert.strictEqual(bigmath.min('10', '3', '4', '2'), 2n)
- assert.strictEqual(bigmath.min('10'), 10n)
- assert.strictEqual(bigmath.min('2.5'), 2.5) // fallback to number
- assert.strictEqual(bigmath.min('2.5', '4'), 2.5) // fallback to number
+ assert.strictEqual(bigmath.min('10', '3', '4', '2'), 2)
+ assert.strictEqual(bigmath.min('10'), 10)
+ assert.strictEqual(bigmath.min('2.5'), 2.5)
+ assert.strictEqual(bigmath.min('2.5', '4'), 2.5)
})
it('should return the min element from a vector', function () {
@@ -131,8 +133,8 @@ describe('min', function () {
assert.throws(function () { min([], 2, 3) })
})
- it('should throw an error if called with an empty array', function () {
- assert.throws(function () { min([]) })
+ it('should return infinity if called with an empty array', function () {
+ assert.strictEqual(min([]), Infinity)
})
it('should throw an error if called with invalid type of arguments', function () {
@@ -143,8 +145,8 @@ describe('min', function () {
assert.throws(function () { min([[2, new Date(), 4]]) }, /TypeError: Cannot calculate min, unexpected type of argument/)
assert.throws(function () { min([2, null, 4]) }, /TypeError: Cannot calculate min, unexpected type of argument/)
assert.throws(function () { min([[2, 5], [4, null], [1, 7]], 0) }, /TypeError: Cannot calculate min, unexpected type of argument/)
- assert.throws(function () { min('a', 'b') }, /Error: Cannot convert "a" to a number/)
- assert.throws(function () { min('a') }, /Error: Cannot convert "a" to a number/)
+ assert.throws(function () { min('a', 'b') }, /Error: Cannot convert "a"/)
+ assert.throws(function () { min('a') }, /Error: Cannot convert "a"/)
})
it('should LaTeX min', function () {
diff --git a/test/unit-tests/function/statistics/prod.test.js b/test/unit-tests/function/statistics/prod.test.js
index 87d43d5aa7..79946f385b 100644
--- a/test/unit-tests/function/statistics/prod.test.js
+++ b/test/unit-tests/function/statistics/prod.test.js
@@ -1,5 +1,7 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
+import { bigConfig } from '../../configs.js'
+
const BigNumber = math.BigNumber
const Complex = math.Complex
const DenseMatrix = math.DenseMatrix
@@ -23,12 +25,13 @@ describe('prod', function () {
assert.strictEqual(prod('2', '3'), 6)
assert.strictEqual(prod('2'), 2)
assert.strictEqual(prod([['1', '3'], ['5', '2']]), 30)
+ assert.strictEqual(prod(['3']), 3)
})
// eslint-disable-next-line mocha/no-skipped-tests
it.skip('should return the product of strings (with BigNumber config)', function () {
// TODO: requires math.add to recon with config.number when parsing strings
- const bigmath = math.create({ number: 'BigNumber' })
+ const bigmath = math.create(bigConfig())
assert.deepStrictEqual(bigmath.prod('10', '3', '4', '2'), bigmath.bignumber('240'))
assert.deepStrictEqual(bigmath.prod('10'), bigmath.bignumber(10))
})
@@ -90,16 +93,16 @@ describe('prod', function () {
assert.throws(function () { prod([], 2) }, /not yet supported/)
})
- it('should throw an error if called with an empty array', function () {
- assert.throws(function () { prod([]) })
+ it('should return 1 if called with an empty array', function () {
+ assert.strictEqual(prod([]), 1)
})
it('should throw an error if called with invalid type of arguments', function () {
assert.throws(function () { prod([[2, undefined, 4]]) }, /TypeError: Cannot calculate prod, unexpected type of argument/)
assert.throws(function () { prod([[2, new Date(), 4]]) }, /TypeError: Cannot calculate prod, unexpected type of argument/)
assert.throws(function () { prod([2, null, 4]) }, /TypeError: Cannot calculate prod, unexpected type of argument/)
- assert.throws(function () { prod('a', 'b') }, /Error: Cannot convert "a" to a number/)
- assert.throws(function () { prod('a') }, /SyntaxError: String "a" is not a valid number/)
+ assert.throws(function () { prod('a', 'b') }, /Error: Cannot convert "a"/)
+ assert.throws(function () { prod('a') }, /Error: Cannot convert "a"/)
})
it('should LaTeX prod', function () {
diff --git a/test/unit-tests/function/statistics/sum.test.js b/test/unit-tests/function/statistics/sum.test.js
index f802d4829b..1556eaa417 100644
--- a/test/unit-tests/function/statistics/sum.test.js
+++ b/test/unit-tests/function/statistics/sum.test.js
@@ -1,5 +1,6 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
+import { bigConfig } from '../../configs.js'
const BigNumber = math.BigNumber
const Complex = math.Complex
@@ -30,7 +31,7 @@ describe('sum', function () {
// eslint-disable-next-line mocha/no-skipped-tests
it.skip('should return the max of strings by their numerical value (with BigNumber config)', function () {
// TODO: requires math.add to recon with config.number when parsing strings
- const bigmath = math.create({ number: 'BigNumber' })
+ const bigmath = math.create(bigConfig())
assert.deepStrictEqual(bigmath.sum('10', '3', '4', '2'), bigmath.bignumber('19'))
assert.deepStrictEqual(bigmath.sum('10'), bigmath.bignumber(10))
})
@@ -117,7 +118,7 @@ describe('sum', function () {
})
it('should return zero if called with an empty array', function () {
- const bigMath = math.create({ number: 'BigNumber' })
+ const bigMath = math.create(bigConfig())
const fracMath = math.create({ number: 'Fraction' })
const big = bigMath.sum([])
@@ -134,8 +135,8 @@ describe('sum', function () {
assert.throws(function () { sum(new Date(), 2) }, /Cannot calculate sum, unexpected type of argument/)
assert.throws(function () { sum(2, 3, null) }, /Cannot calculate sum, unexpected type of argument/)
assert.throws(function () { sum([2, 3, null]) }, /Cannot calculate sum, unexpected type of argument/)
- assert.throws(function () { sum('a', 'b') }, /Error: Cannot convert "a" to a number/)
- assert.throws(function () { sum('a') }, /SyntaxError: String "a" is not a valid number/)
+ assert.throws(function () { sum('a', 'b') }, /Error: Cannot convert "a"/)
+ assert.throws(function () { sum('a') }, /Error: Cannot convert "a"/)
})
it('should LaTeX sum', function () {
diff --git a/test/unit-tests/function/string/format.test.js b/test/unit-tests/function/string/format.test.js
index 8469a571d6..408fb0726d 100644
--- a/test/unit-tests/function/string/format.test.js
+++ b/test/unit-tests/function/string/format.test.js
@@ -3,6 +3,7 @@ import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { format } from '../../../../src/utils/number.js'
+import { bigConfig } from '../../configs.js'
describe('format', function () {
it('should format numbers', function () {
@@ -225,7 +226,7 @@ describe('format', function () {
})
describe('bignumber', function () {
- const bigmath = math.create({ precision: 20 }) // ensure the precision is 20 digits
+ const bigmath = math.create({ compute: { BigNumber: { precision: 20 } } })
it('should format big numbers', function () {
assert.strictEqual(math.format(bigmath.bignumber(2).dividedBy(7)), '0.28571428571428571429')
@@ -454,7 +455,7 @@ describe('format', function () {
assert.strictEqual(math.format(math.parse('0.3333'), { precision: 1 }), '0.3')
assert.strictEqual(math.format(math.parse('0.3333 + [0.4444]'), { precision: 1 }), '0.3 + [0.4]')
- const bigmath = math.create({ number: 'BigNumber' })
+ const bigmath = math.create(bigConfig())
assert.strictEqual(bigmath.format(bigmath.parse('0.3333 + [0.4444]'), { precision: 1 }), '0.3 + [0.4]')
})
diff --git a/test/unit-tests/function/trigonometry/acos.test.js b/test/unit-tests/function/trigonometry/acos.test.js
index 52f259b613..8d8843d0ca 100644
--- a/test/unit-tests/function/trigonometry/acos.test.js
+++ b/test/unit-tests/function/trigonometry/acos.test.js
@@ -1,14 +1,21 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const acos = math.acos
const cos = math.cos
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
-const mathPredictable = math.create({ predictable: true })
+const bigmath = math.create({
+ compute: {
+ numberApproximate: 'BigNumber',
+ BigNumber: { precision: 20 }
+ }
+})
+const mathPredictable = math.create({ compute: { uniformType: true } })
const acosBig = bigmath.acos
const cosBig = bigmath.cos
const Big = bigmath.bignumber
@@ -44,7 +51,7 @@ describe('acos', function () {
assert.deepStrictEqual(acosBig(Big(1)), Big(0))
// Hit Newton's method case
- const bigmath61 = math.create({ number: 'BigNumber', precision: 61 })
+ const bigmath61 = math.create(bigConfig(61))
assert.deepStrictEqual(bigmath61.acos(bigmath61.bignumber(0.00000001)),
bigmath61.bignumber('1.570796316794896619231321524973084775431910533020886243820359'))
// Wolfram: 1.5707963167948966192313215249730847754319105330208862438203592009158129650174844596314777278941600852176250962802
@@ -61,7 +68,7 @@ describe('acos', function () {
})
it('should be the inverse function of bignumber cos', function () {
- bigmath.config({ precision: 20 })
+ bigmath.config({ compute: { BigNumber: { precision: 20 } } })
assert.deepStrictEqual(acosBig(cosBig(Big(-1))), Big(1))
assert.deepStrictEqual(acosBig(cosBig(Big(0))), Big('0'))
assert.deepStrictEqual(acosBig(cosBig(Big(0.1))), Big('0.099999999999999999956'))
@@ -70,8 +77,9 @@ describe('acos', function () {
})
it('should return for bignumber cos for x > 1', function () {
- assert.ok(acos(Big(1.1)).isNaN())
- assert.ok(acos(Big(-1.1)).isNaN())
+ assert.deepStrictEqual(acos(Big(1.1)), math.complex(0, 0.4435682543851154))
+ assert.deepStrictEqual(
+ acos(Big(-1.1)), math.complex(Math.PI, -0.44356825438511527))
})
it('should return the arccos of a complex number', function () {
diff --git a/test/unit-tests/function/trigonometry/acosh.test.js b/test/unit-tests/function/trigonometry/acosh.test.js
index fe1218e367..43cfe7a51e 100644
--- a/test/unit-tests/function/trigonometry/acosh.test.js
+++ b/test/unit-tests/function/trigonometry/acosh.test.js
@@ -9,9 +9,14 @@ const cosh = math.cosh
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
-const biggermath = math.create({ precision: 22 })
-const predmath = math.create({ predictable: true })
+const bigmath = math.create({
+ compute: {
+ numberApproximate: 'BigNumber',
+ BigNumber: { precision: 20 }
+ }
+})
+const biggermath = math.create({ compute: { BigNumber: { precision: 22 } } })
+const predmath = math.create({ compute: { uniformType: true } })
const acoshBig = bigmath.acosh
const Big = bigmath.bignumber
@@ -44,8 +49,8 @@ describe('acosh', function () {
assert.deepStrictEqual(acosh(arg), Big(0))
assert.deepStrictEqual(acoshBig(Big(2)), Big('1.3169578969248167086'))
assert.deepStrictEqual(acoshBig(Big(3)), Big('1.7627471740390860505'))
- assert.deepStrictEqual(acoshBig(bigmath.pi).toString(), '1.811526272460853107')
-
+ assert.strictEqual(acoshBig(bigmath.pi).toString(), '1.811526272460853107')
+ assert.deepStrictEqual(acoshBig(Big(-1)), bigmath.complex(0, Math.PI))
// Make sure arg was not changed
assert.deepStrictEqual(arg, Big(1))
})
diff --git a/test/unit-tests/function/trigonometry/acot.test.js b/test/unit-tests/function/trigonometry/acot.test.js
index 69a22fe1fb..590863fb5d 100644
--- a/test/unit-tests/function/trigonometry/acot.test.js
+++ b/test/unit-tests/function/trigonometry/acot.test.js
@@ -1,13 +1,15 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
const acot = math.acot
const cot = math.cot
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
+const bigmath = math.create(bigConfig(20))
const acotBig = bigmath.acot
const cotBig = bigmath.cot
const Big = bigmath.bignumber
@@ -52,7 +54,7 @@ describe('acot', function () {
assert.deepStrictEqual(arg8.toString(), 'Infinity')
// Hit Newton's method case
- const bigmath61 = bigmath.create({ number: 'BigNumber', precision: 61 })
+ const bigmath61 = bigmath.create(bigConfig(61))
assert.deepStrictEqual(bigmath61.acot(bigmath61.bignumber(1.1)),
bigmath61.bignumber('0.7378150601204649138136281298033902035827333552504444896340492'))
})
@@ -66,7 +68,7 @@ describe('acot', function () {
})
it('should be the inverse function of bignumber cot', function () {
- bigmath.config({ precision: 20 })
+ bigmath.config({ compute: { BigNumber: { precision: 20 } } })
assert.deepStrictEqual(acotBig(cotBig(Big(-1))), Big(-1))
assert.deepStrictEqual(acotBig(cotBig(Big(0))), Big(0))
assert.deepStrictEqual(acotBig(cotBig(Big(0.1))), Big(0.1))
diff --git a/test/unit-tests/function/trigonometry/acoth.test.js b/test/unit-tests/function/trigonometry/acoth.test.js
index b03714f078..7f6207303a 100644
--- a/test/unit-tests/function/trigonometry/acoth.test.js
+++ b/test/unit-tests/function/trigonometry/acoth.test.js
@@ -3,15 +3,17 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const acoth = math.acoth
const coth = math.coth
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
-const biggermath = math.create({ precision: 21 })
-const predmath = math.create({ predictable: true })
+const bigmath = math.create(bigConfig(20))
+const biggermath = math.create({ compute: { BigNumber: { precision: 21 } } })
+const predmath = math.create({ compute: { uniformType: true } })
const acothBig = bigmath.acoth
const Big = bigmath.bignumber
@@ -55,8 +57,10 @@ describe('acoth', function () {
assert.deepStrictEqual(arg3, Big(-1))
// out of range
- assert.ok(acothBig(Big(-0.5)).isNaN())
- assert.ok(acothBig(Big(0.5)).isNaN())
+ assert.ok(
+ acothBig(Big(-0.5)), bigmath.complex(-0.5493061443340548, Math.PI / 2))
+ assert.ok(
+ acothBig(Big(0.5)), bigmath.complex(0.5493061443340548, -Math.PI / 2))
})
it('should be the inverse function of hyperbolic cot', function () {
diff --git a/test/unit-tests/function/trigonometry/acsc.test.js b/test/unit-tests/function/trigonometry/acsc.test.js
index 851c66b84b..da89ec92f3 100644
--- a/test/unit-tests/function/trigonometry/acsc.test.js
+++ b/test/unit-tests/function/trigonometry/acsc.test.js
@@ -3,15 +3,17 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
const acsc = math.acsc
const csc = math.csc
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
-const biggermath = math.create({ precision: 21 })
-const predmath = math.create({ predictable: true })
+const bigmath = math.create(bigConfig(20))
+const biggermath = math.create({ compute: { BigNumber: { precision: 21 } } })
+const predmath = math.create({ compute: { uniformType: true } })
const acscBig = bigmath.acsc
const Big = bigmath.bignumber
@@ -55,7 +57,7 @@ describe('acsc', function () {
assert.deepStrictEqual(arg3, Big(-1))
// Hit Newton's method case
- const bigmath61 = bigmath.create({ number: 'BigNumber', precision: 61 })
+ const bigmath61 = bigmath.create(bigConfig(61))
const arg4 = bigmath61.bignumber(1.00000001)
assert.deepStrictEqual(bigmath61.acsc(arg4),
@@ -63,8 +65,10 @@ describe('acsc', function () {
// wolfram 1.5706549054392485653736296134500571807391258840905540266235145245693842219005187990359787187421573662444504948773
assert.deepStrictEqual(arg4, bigmath61.bignumber(1.00000001))
- assert.ok(acscBig(Big(0.5)).isNaN())
- assert.ok(acscBig(Big(-0.5)).isNaN())
+ assert.deepStrictEqual(
+ acscBig(Big(0.5)), math.complex(Math.PI / 2, -1.3169578969248166))
+ assert.deepStrictEqual(
+ acscBig(Big(-0.5)), math.complex(-Math.PI / 2, 1.3169578969248164))
})
it('should be the inverse function of csc', function () {
@@ -76,7 +80,7 @@ describe('acsc', function () {
})
it('should be the inverse function of bignumber csc', function () {
- const bigmath61 = bigmath.create({ number: 'BigNumber', precision: 61 })
+ const bigmath61 = bigmath.create(bigConfig(61))
assert.deepStrictEqual(bigmath61.acsc(bigmath61.csc(bigmath61.bignumber(-2))),
bigmath61.bignumber('-1.141592653589793238462643383279502884197169399375105820974946'))
// wolfram: -1.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132
diff --git a/test/unit-tests/function/trigonometry/acsch.test.js b/test/unit-tests/function/trigonometry/acsch.test.js
index 7d404682fa..ec5d3d03f5 100644
--- a/test/unit-tests/function/trigonometry/acsch.test.js
+++ b/test/unit-tests/function/trigonometry/acsch.test.js
@@ -3,13 +3,15 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const acsch = math.acsch
const csch = math.csch
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
+const bigmath = math.create(bigConfig(20))
const acschBig = bigmath.acsch
const Big = bigmath.bignumber
diff --git a/test/unit-tests/function/trigonometry/asec.test.js b/test/unit-tests/function/trigonometry/asec.test.js
index d92463d75b..f5f7ace167 100644
--- a/test/unit-tests/function/trigonometry/asec.test.js
+++ b/test/unit-tests/function/trigonometry/asec.test.js
@@ -3,14 +3,16 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const asec = math.asec
const sec = math.sec
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
-const predmath = math.create({ predictable: true })
+const bigmath = math.create(bigConfig(20))
+const predmath = math.create({ compute: { uniformType: true } })
const asecBig = bigmath.asec
const Big = bigmath.bignumber
@@ -49,7 +51,7 @@ describe('asec', function () {
assert.deepStrictEqual(arg2, Big(-1))
// Hit Newton's method case
- const bigmath64 = bigmath.create({ number: 'BigNumber', precision: 64 })
+ const bigmath64 = bigmath.create(bigConfig(64))
const arg = bigmath64.bignumber('3.00000001')
assert.deepStrictEqual(bigmath64.asec(bigmath64.bignumber(3)),
bigmath64.bignumber('1.230959417340774682134929178247987375710340009355094839055548334'))
@@ -60,9 +62,10 @@ describe('asec', function () {
assert.deepStrictEqual(arg, bigmath64.bignumber(3.00000001))
// out of range
- assert.ok(asec(Big(0.5)).isNaN())
- assert.ok(asec(Big(0)).isNaN())
- assert.ok(asec(Big(-0.5)).isNaN())
+ assert.deepStrictEqual(asec(Big(0.5)), math.complex(0, 1.3169578969248166))
+ assert.ok(!math.isFinite(asec(Big(0))))
+ assert.deepStrictEqual(
+ asec(Big(-0.5)), math.complex(Math.PI, -1.3169578969248164))
})
it('should be the inverse function of sec', function () {
@@ -74,7 +77,7 @@ describe('asec', function () {
})
it('should be the inverse function of bignumber sec', function () {
- bigmath.config({ precision: 20 })
+ bigmath.config({ compute: { BigNumber: { precision: 20 } } })
assert.deepStrictEqual(asecBig(bigmath.sec(Big(-1))), Big(1))
assert.deepStrictEqual(asecBig(bigmath.sec(Big(0))), Big(0))
assert.deepStrictEqual(asecBig(bigmath.sec(Big(0.5))), Big('0.49999999999999999997'))
diff --git a/test/unit-tests/function/trigonometry/asech.test.js b/test/unit-tests/function/trigonometry/asech.test.js
index 054787fea2..87077e2603 100644
--- a/test/unit-tests/function/trigonometry/asech.test.js
+++ b/test/unit-tests/function/trigonometry/asech.test.js
@@ -9,9 +9,14 @@ const sech = math.sech
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
-const biggermath = math.create({ precision: 22 })
-const predmath = math.create({ predictable: true })
+const bigmath = math.create({
+ compute: {
+ numberApproximate: 'BigNumber',
+ BigNumber: { precision: 20 }
+ }
+})
+const biggermath = math.create({ compute: { BigNumber: { precision: 22 } } })
+const predmath = math.create({ compute: { uniformType: true } })
const asechBig = bigmath.asech
const Big = bigmath.bignumber
@@ -53,8 +58,8 @@ describe('asech', function () {
assert.deepStrictEqual(arg2, Big(0.25))
/* out of range */
- assert.ok(asech(Big(-1)).isNaN())
- assert.ok(asech(Big(2)).isNaN())
+ assert.deepStrictEqual(asech(Big(-1)), math.complex(-0, Math.PI))
+ assert.ok(asech(Big(2)), math.complex(0, Math.PI / 3))
})
it('should be the inverse function of hyperbolic sec', function () {
diff --git a/test/unit-tests/function/trigonometry/asin.test.js b/test/unit-tests/function/trigonometry/asin.test.js
index fb0fc9582c..6afacb66f3 100644
--- a/test/unit-tests/function/trigonometry/asin.test.js
+++ b/test/unit-tests/function/trigonometry/asin.test.js
@@ -1,15 +1,17 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
const asin = math.asin
const sin = math.sin
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
-const biggermath = math.create({ precision: 21 })
-const predmath = math.create({ predictable: true })
+const bigmath = math.create(bigConfig(20))
+const biggermath = math.create({ compute: { BigNumber: { precision: 21 } } })
+const predmath = math.create({ compute: { uniformType: true } })
const asinBig = bigmath.asin
const Big = bigmath.bignumber
@@ -54,7 +56,7 @@ describe('asin', function () {
assert.deepStrictEqual(arg3, Big(-0.5))
// Hit Newton's method case
- const bigmath61 = bigmath.create({ number: 'BigNumber', precision: 61 })
+ const bigmath61 = bigmath.create(bigConfig(61))
const arg4 = bigmath61.bignumber(0.00000001)
assert.deepStrictEqual(bigmath61.asin(arg4),
@@ -72,7 +74,7 @@ describe('asin', function () {
it('should be the inverse function of bignumber sin', function () {
// More Newton's method test cases
- const bigmath61 = bigmath.create({ number: 'BigNumber', precision: 61 })
+ const bigmath61 = bigmath.create(bigConfig(61))
assert.deepStrictEqual(asinBig(bigmath61.sin(bigmath61.bignumber(-2))),
bigmath61.bignumber('-1.141592653589793238462643383279502884197169399375105820974945'))
// Wolfram: -1.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132
@@ -92,7 +94,8 @@ describe('asin', function () {
assert.deepStrictEqual(asinBig(biggermath.sin(Big(-1))), Big('-1'))
// outside of real range
- assert.ok(asin(Big(1.1)).isNaN())
+ assert.deepStrictEqual(
+ asin(Big(1.1)), math.complex(1.5707963267948966, -0.4435682543851154))
})
it('should return the arcsin of a complex number', function () {
diff --git a/test/unit-tests/function/trigonometry/asinh.test.js b/test/unit-tests/function/trigonometry/asinh.test.js
index c0d1134636..109d81eed5 100644
--- a/test/unit-tests/function/trigonometry/asinh.test.js
+++ b/test/unit-tests/function/trigonometry/asinh.test.js
@@ -3,14 +3,16 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const asinh = math.asinh
const sinh = math.sinh
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
-const biggermath = math.create({ precision: 21 })
+const bigmath = math.create(bigConfig(20))
+const biggermath = math.create({ compute: { BigNumber: { precision: 21 } } })
const asinhBig = bigmath.asinh
const Big = bigmath.bignumber
diff --git a/test/unit-tests/function/trigonometry/atan.test.js b/test/unit-tests/function/trigonometry/atan.test.js
index c9917a7cec..6eee3f80e8 100644
--- a/test/unit-tests/function/trigonometry/atan.test.js
+++ b/test/unit-tests/function/trigonometry/atan.test.js
@@ -1,13 +1,15 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
const atan = math.atan
const tan = math.tan
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
+const bigmath = math.create(bigConfig(20))
const atanBig = bigmath.atan
const Big = bigmath.bignumber
@@ -47,7 +49,7 @@ describe('atan', function () {
assert.deepStrictEqual(arg7.toString(), 'Infinity')
// Hit Newton's method case
- const bigmath61 = bigmath.create({ number: 'BigNumber', precision: 61 })
+ const bigmath61 = bigmath.create(bigConfig(61))
assert.deepStrictEqual(bigmath61.atan(bigmath61.bignumber(0.9)),
bigmath61.bignumber('0.7328151017865065916407920727342802519857556793582560863105069'))
})
@@ -61,7 +63,7 @@ describe('atan', function () {
})
it('should be the inverse function of bignumber tan', function () {
- bigmath.config({ precision: 20 })
+ bigmath.config({ compute: { BigNumber: { precision: 20 } } })
assert.deepStrictEqual(atanBig(bigmath.tan(Big(-1))), Big(-1))
assert.deepStrictEqual(atanBig(bigmath.tan(Big(0))), Big(0))
assert.deepStrictEqual(atanBig(bigmath.tan(Big(0.1))), Big(0.1))
diff --git a/test/unit-tests/function/trigonometry/atan2.test.js b/test/unit-tests/function/trigonometry/atan2.test.js
index e292d69311..efb3ed574e 100644
--- a/test/unit-tests/function/trigonometry/atan2.test.js
+++ b/test/unit-tests/function/trigonometry/atan2.test.js
@@ -10,7 +10,7 @@ const sparse = math.sparse
const unit = math.unit
const divide = math.divide
const atan2 = math.atan2
-const bigmath = math.create({ precision: 20 })
+const bigmath = math.create({ compute: { BigNumber: { precision: 20 } } })
const Big = bigmath.bignumber
const atan2Big = bigmath.atan2
diff --git a/test/unit-tests/function/trigonometry/atanh.test.js b/test/unit-tests/function/trigonometry/atanh.test.js
index e61c8158e8..a228a2a7ff 100644
--- a/test/unit-tests/function/trigonometry/atanh.test.js
+++ b/test/unit-tests/function/trigonometry/atanh.test.js
@@ -3,15 +3,17 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const atanh = math.atanh
const tanh = math.tanh
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
-const biggermath = math.create({ precision: 21 })
-const predmath = math.create({ predictable: true })
+const bigmath = math.create(bigConfig(20))
+const biggermath = math.create({ compute: { BigNumber: { precision: 21 } } })
+const predmath = math.create({ compute: { uniformType: true } })
const atanhBig = bigmath.atanh
const Big = bigmath.bignumber
@@ -70,8 +72,8 @@ describe('atanh', function () {
assert.deepStrictEqual(atanhBig(biggermath.tanh(arg)), Big(-1))
assert.deepStrictEqual(atanhBig(biggermath.tanh(Big(0.1))), Big(0.1))
assert.deepStrictEqual(arg, Big(-1))
-
- assert.ok(atanh(Big(1.1)).isNaN())
+ assert.deepStrictEqual(
+ atanh(Big(1.1)), math.complex(1.522261218861711, -1.5707963267948966))
})
it('should return the arctanh of a complex number', function () {
diff --git a/test/unit-tests/function/trigonometry/cos.test.js b/test/unit-tests/function/trigonometry/cos.test.js
index 28b24c62b4..e8fe522898 100644
--- a/test/unit-tests/function/trigonometry/cos.test.js
+++ b/test/unit-tests/function/trigonometry/cos.test.js
@@ -1,13 +1,15 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
const cos = math.cos
-const bigmath = math.create({ number: 'BigNumber', precision: 15 })
-const biggermath = math.create({ number: 'BigNumber', precision: 238 })
+const bigmath = math.create(bigConfig(15))
+const biggermath = math.create(bigConfig(238))
describe('cos', function () {
it('should return the cosine of a boolean', function () {
@@ -47,7 +49,7 @@ describe('cos', function () {
assert.strictEqual(cosVal.constructor.precision, 238)
assert.deepStrictEqual(cosVal.toString(), resultVal)
- const biggermath2 = math.create({ number: 'BigNumber', precision: 16 })
+ const biggermath2 = math.create(bigConfig(16))
const bigPi = biggermath2.pi
// we've had a bug in reducing the period, affecting integer values around multiples of tau
diff --git a/test/unit-tests/function/trigonometry/cosh.test.js b/test/unit-tests/function/trigonometry/cosh.test.js
index 117eae682d..80ad6752d9 100644
--- a/test/unit-tests/function/trigonometry/cosh.test.js
+++ b/test/unit-tests/function/trigonometry/cosh.test.js
@@ -1,12 +1,14 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
const cosh = math.cosh
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
+const bigmath = math.create(bigConfig(20))
describe('cosh', function () {
it('should return the cosh of a boolean', function () {
diff --git a/test/unit-tests/function/trigonometry/cot.test.js b/test/unit-tests/function/trigonometry/cot.test.js
index 36e4518411..b602fe6252 100644
--- a/test/unit-tests/function/trigonometry/cot.test.js
+++ b/test/unit-tests/function/trigonometry/cot.test.js
@@ -1,12 +1,14 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
const cot = math.cot
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
+const bigmath = math.create(bigConfig(20))
describe('cot', function () {
it('should return the cotan of a boolean', function () {
diff --git a/test/unit-tests/function/trigonometry/coth.test.js b/test/unit-tests/function/trigonometry/coth.test.js
index 99dc0d357b..82f0a8f04f 100644
--- a/test/unit-tests/function/trigonometry/coth.test.js
+++ b/test/unit-tests/function/trigonometry/coth.test.js
@@ -1,13 +1,15 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
const coth = math.coth
-const bigmath = math.create({ precision: 20 })
-const biggermath = math.create({ number: 'BigNumber', precision: 21 })
+const bigmath = math.create({ compute: { BigNumber: { precision: 20 } } })
+const biggermath = math.create(bigConfig(21))
describe('coth', function () {
it('should return the coth of a boolean', function () {
diff --git a/test/unit-tests/function/trigonometry/csc.test.js b/test/unit-tests/function/trigonometry/csc.test.js
index 5693149eca..0c65cc58e4 100644
--- a/test/unit-tests/function/trigonometry/csc.test.js
+++ b/test/unit-tests/function/trigonometry/csc.test.js
@@ -1,12 +1,14 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
const csc = math.csc
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
+const bigmath = math.create(bigConfig(20))
describe('csc', function () {
it('should return the cosecant of a boolean', function () {
diff --git a/test/unit-tests/function/trigonometry/csch.test.js b/test/unit-tests/function/trigonometry/csch.test.js
index 25eca916ab..c88e1119b8 100644
--- a/test/unit-tests/function/trigonometry/csch.test.js
+++ b/test/unit-tests/function/trigonometry/csch.test.js
@@ -1,13 +1,15 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
const csch = math.csch
-const bigmath = math.create({ precision: 20 })
-const biggermath = math.create({ number: 'BigNumber', precision: 22 })
+const bigmath = math.create({ compute: { BigNumber: { precision: 20 } } })
+const biggermath = math.create(bigConfig(22))
describe('csch', function () {
it('should return the csch of a boolean', function () {
diff --git a/test/unit-tests/function/trigonometry/sec.test.js b/test/unit-tests/function/trigonometry/sec.test.js
index 755f2ceb73..9ff218cda4 100644
--- a/test/unit-tests/function/trigonometry/sec.test.js
+++ b/test/unit-tests/function/trigonometry/sec.test.js
@@ -1,13 +1,15 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
const sec = math.sec
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
-const biggermath = math.create({ number: 'BigNumber', precision: 21 })
+const bigmath = math.create(bigConfig(20))
+const biggermath = math.create(bigConfig(21))
describe('sec', function () {
it('should return the secant of a boolean', function () {
diff --git a/test/unit-tests/function/trigonometry/sech.test.js b/test/unit-tests/function/trigonometry/sech.test.js
index 994a614efa..3d01b6c0de 100644
--- a/test/unit-tests/function/trigonometry/sech.test.js
+++ b/test/unit-tests/function/trigonometry/sech.test.js
@@ -1,13 +1,15 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
const sech = math.sech
-const bigmath = math.create({ precision: 20 })
-const biggermath = math.create({ number: 'BigNumber', precision: 21 })
+const bigmath = math.create({ compute: { BigNumber: { precision: 20 } } })
+const biggermath = math.create(bigConfig(21))
describe('sech', function () {
it('should return the sech of a boolean', function () {
diff --git a/test/unit-tests/function/trigonometry/sin.test.js b/test/unit-tests/function/trigonometry/sin.test.js
index 231149b97b..052dd71ec8 100644
--- a/test/unit-tests/function/trigonometry/sin.test.js
+++ b/test/unit-tests/function/trigonometry/sin.test.js
@@ -1,13 +1,15 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const EPSILON = 1e-13
const pi = math.pi
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
const sin = math.sin
-const bigmath = math.create({ precision: 242 })
+const bigmath = math.create({ compute: { BigNumber: { precision: 242 } } })
describe('sin', function () {
it('should return the sine of a boolean', function () {
@@ -46,7 +48,7 @@ describe('sin', function () {
'3071480438329880550139583951234188873226108092477936610585549' +
'3575835362891900420559398509489530577719840860106717522689249' +
'60612126026291341865833521451170868744460464214033460336158'))
- const bigmath2 = bigmath.create({ number: 'BigNumber', precision: 15 })
+ const bigmath2 = bigmath.create(bigConfig(15))
// we've had a bug in reducing the period, affecting integer values around multiples of tau (like 6, 7)
for (let x = -20; x < 20; x += 1) {
@@ -66,7 +68,7 @@ describe('sin', function () {
assert.ok(bigmath2.sin(bigmath2.tau).lt(1e-14))
assert.ok(bigmath2.sin(bigmath2.tau.times(2)).lt(1e-13))
- const bigmath61 = bigmath.create({ number: 'BigNumber', precision: 61 })
+ const bigmath61 = bigmath.create(bigConfig(61))
assert.deepStrictEqual(bigmath61.sin(bigmath61.bignumber(-2)).toString(), '-0.909297426825681695396019865911744842702254971447890268378973')
})
diff --git a/test/unit-tests/function/trigonometry/sinh.test.js b/test/unit-tests/function/trigonometry/sinh.test.js
index 508109bdd9..fd56368ae9 100644
--- a/test/unit-tests/function/trigonometry/sinh.test.js
+++ b/test/unit-tests/function/trigonometry/sinh.test.js
@@ -3,11 +3,13 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
const sinh = math.sinh
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
+const bigmath = math.create(bigConfig(20))
const EPSILON = 1e-14
@@ -66,7 +68,7 @@ describe('sinh', function () {
assert.deepStrictEqual(arg2, Big(-1))
assert.deepStrictEqual(arg7.toString(), 'Infinity')
- bigmath.config({ precision: 50 })
+ bigmath.config({ compute: { BigNumber: { precision: 50 } } })
assert.deepStrictEqual(sinhBig(Big(1e-50)), Big(1e-50))
})
diff --git a/test/unit-tests/function/trigonometry/tan.test.js b/test/unit-tests/function/trigonometry/tan.test.js
index 90b6e6c13a..8f42f775cc 100644
--- a/test/unit-tests/function/trigonometry/tan.test.js
+++ b/test/unit-tests/function/trigonometry/tan.test.js
@@ -1,13 +1,15 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
const tan = math.tan
-const piBigmath = math.create({ number: 'BigNumber', precision: 21 })
-const bigmath = math.create({ precision: 20 })
+const piBigmath = math.create(bigConfig(21))
+const bigmath = math.create({ compute: { BigNumber: { precision: 20 } } })
const Big = bigmath.bignumber
const bigTan = bigmath.tan
diff --git a/test/unit-tests/function/trigonometry/tanh.test.js b/test/unit-tests/function/trigonometry/tanh.test.js
index edbe637404..7528b98e58 100644
--- a/test/unit-tests/function/trigonometry/tanh.test.js
+++ b/test/unit-tests/function/trigonometry/tanh.test.js
@@ -1,12 +1,14 @@
import assert from 'assert'
import math from '../../../../src/defaultInstance.js'
import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
+import { bigConfig } from '../../configs.js'
+
const pi = math.pi
const complex = math.complex
const matrix = math.matrix
const unit = math.unit
const tanh = math.tanh
-const bigmath = math.create({ number: 'BigNumber', precision: 20 })
+const bigmath = math.create(bigConfig(20))
describe('tanh', function () {
it('should return the tanh of a boolean', function () {
diff --git a/test/unit-tests/function/utils/isNegative.test.js b/test/unit-tests/function/utils/isNegative.test.js
index 7477221285..1d8c0fa61c 100644
--- a/test/unit-tests/function/utils/isNegative.test.js
+++ b/test/unit-tests/function/utils/isNegative.test.js
@@ -75,7 +75,7 @@ describe('isNegative', function () {
})
it('should throw an error in case of unsupported data types', function () {
- assert.throws(function () { isNegative(complex(2, 3)) }, /TypeError: Unexpected type of argument/)
+ assert.throws(function () { isNegative(complex(2, 3)) }, TypeError)
assert.throws(function () { isNegative(new Date()) }, /TypeError: Unexpected type of argument/)
assert.throws(function () { isNegative({}) }, /TypeError: Unexpected type of argument/)
})
diff --git a/test/unit-tests/function/utils/isPositive.test.js b/test/unit-tests/function/utils/isPositive.test.js
index c9be9f3d6d..8ca3cb5b94 100644
--- a/test/unit-tests/function/utils/isPositive.test.js
+++ b/test/unit-tests/function/utils/isPositive.test.js
@@ -75,7 +75,7 @@ describe('isPositive', function () {
})
it('should throw an error in case of unsupported data types', function () {
- assert.throws(function () { isPositive(complex(2, 3)) }, /TypeError: Unexpected type of argument/)
+ assert.throws(function () { isPositive(complex(2, 3)) }, TypeError)
assert.throws(function () { isPositive(new Date()) }, /TypeError: Unexpected type of argument/)
assert.throws(function () { isPositive({}) }, /TypeError: Unexpected type of argument/)
})
diff --git a/test/unit-tests/type/bignumber/function/bignumber.test.js b/test/unit-tests/type/bignumber/function/bignumber.test.js
index 3e02143c57..4f9b6a55ea 100644
--- a/test/unit-tests/type/bignumber/function/bignumber.test.js
+++ b/test/unit-tests/type/bignumber/function/bignumber.test.js
@@ -90,18 +90,14 @@ describe('bignumber', function () {
})
it('should apply precision setting to bignumbers', function () {
- const mymath = math.create({
- precision: 32
- })
+ const mymath = math.create({ compute: { BigNumber: { precision: 32 } } })
const a = mymath.bignumber(1).dividedBy(3)
assert.strictEqual(a.toString(), '0.33333333333333333333333333333333')
})
it('should support very high precisions', function () {
- const mymath = math.create({
- precision: 2000
- })
+ const mymath = math.create({ compute: { BigNumber: { precision: 2000 } } })
const a = mymath.bignumber(1).dividedBy(3)
diff --git a/test/unit-tests/type/unit/Unit.test.js b/test/unit-tests/type/unit/Unit.test.js
index 2803daf984..ad3006f1d3 100644
--- a/test/unit-tests/type/unit/Unit.test.js
+++ b/test/unit-tests/type/unit/Unit.test.js
@@ -3,6 +3,7 @@ import { approxEqual, approxDeepEqual } from '../../../../tools/approx.js'
import math from '../../../../src/defaultInstance.js'
import { isBigNumber, isFraction } from '../../../../src/utils/is.js'
import { hasOwnProperty } from '../../../../src/utils/object.js'
+import { bigConfig } from '../../configs.js'
const Unit = math.Unit
@@ -557,7 +558,7 @@ describe('Unit', function () {
})
it('should simplify units when they cancel out with {predictable: true}', function () {
- const math2 = math.create({ predictable: true })
+ const math2 = math.create({ compute: { uniformType: true } })
const unit1 = new math2.Unit(2, 'Hz')
const unit2 = new math2.Unit(2, 's')
const unit3 = math2.multiply(unit1, unit2)
@@ -582,7 +583,7 @@ describe('Unit', function () {
it('should convert units to appropriate _numeric_ values when they cancel out with {predictable: false}', function () {
const origConfig = math.config()
- math.config({ predictable: false })
+ math.config({ compute: { uniformType: false } })
assert.strictEqual(typeof (math.evaluate('40 m * 40 N / (40 J)')), 'number')
@@ -979,7 +980,7 @@ describe('Unit', function () {
const unit2 = math2.Unit.parse('5kg')
assert(isFraction(unit2.value))
- const math3 = math.create({ number: 'BigNumber' })
+ const math3 = math.create(bigConfig())
const unit3 = math3.Unit.parse('5kg')
assert(isBigNumber(unit3.value))
})
diff --git a/test/unit-tests/type/unit/physicalConstants.test.js b/test/unit-tests/type/unit/physicalConstants.test.js
index 7946657305..aebf2741f5 100644
--- a/test/unit-tests/type/unit/physicalConstants.test.js
+++ b/test/unit-tests/type/unit/physicalConstants.test.js
@@ -61,7 +61,12 @@ const { BigNumber, Unit } = math
describe('physical constants', function () {
it('should return the correct value and unit for physical constants', function () {
// Note: to keep these unit tests readable and compact, the toString() of the units is compared
- const config = { number: 'number', precision: 64, relTol: 1e-12 }
+ const config = {
+ compute: {
+ numberApproximate: 'number',
+ defaultRelTol: 1e-12
+ }
+ }
const dependencies = { config, BigNumber, Unit }
// Universal constants
@@ -140,7 +145,13 @@ describe('physical constants', function () {
})
it('should create BigNumber unit values if configured', function () {
- const config = { number: 'BigNumber', precision: 64, relTol: 1e-12 }
+ const config = {
+ compute: {
+ defaultRelTol: 1e-12,
+ numberApproximate: 'BigNumber',
+ BigNumber: { precision: 64 }
+ }
+ }
const dependencies = { config, BigNumber, Unit }
const molarMass = createMolarMass(dependencies)
diff --git a/tools/docgenerator.js b/tools/docgenerator.js
index 2731fbda33..75c5dfe876 100644
--- a/tools/docgenerator.js
+++ b/tools/docgenerator.js
@@ -62,9 +62,10 @@ const IGNORE_WARNINGS = {
* @param {String} name Function name
* @param {String} code javascript code containing a block comment
* describing a math.js function
+ * @param {Path} location Where the source files are, to handle references
* @return {Object} doc json document
*/
-export function generateDoc (name, code) {
+export function generateDoc (name, code, location) {
// get block comment from code
const commentRegex = /\/\*\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\//g
// const match = commentRegex.exec(code)
@@ -180,7 +181,20 @@ export function generateDoc (name, code) {
skipEmptyLines()
while (exists() && !empty()) {
- doc.where.push(line)
+ const interpolate = line.match(
+ /^\s*[<]Insert\s+(.*)\s+(.*)\s+from\s+(.*)\s+here[>]/)
+ if (interpolate) {
+ const fromFileSpec = interpolate[3]
+ const packageRoot = location.split('/src/')[0]
+ const fromFile = packageRoot + "/" + fromFileSpec
+ const fileStr = String(fs.readFileSync(fromFile))
+ const extractor = new RegExp(
+ `${interpolate[1]}.*${interpolate[2]}.*[\\n]{2}` +
+ '([\\s\\S]*)[\\n][#][#]\\s+Examples',
+ 'm')
+ const content = fileStr.match(extractor)
+ if (content) doc.where.push(content[1])
+ } else doc.where.push(line)
next()
}
@@ -606,7 +620,7 @@ export function collectDocs (functionNames, inputPath) {
const code = String(fs.readFileSync(fn.fullPath))
const isFunction = (functionNames.includes(name)) && !IGNORE_FUNCTIONS[name]
- const doc = isFunction ? generateDoc(name, code) : null
+ const doc = isFunction ? generateDoc(name, code, fn.fullPath) : null
if (isFunction && doc) {
fn.doc = doc
diff --git a/types/index.d.ts b/types/index.d.ts
index 05b2711423..2200ce99c8 100644
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -1634,6 +1634,21 @@ export interface MathJsInstance extends MathJsFactory {
*/
xgcd(a: number | BigNumber, b: number | BigNumber): MathArray
+ /**
+ * Returns the multiplicative identity of the same type as x
+ *
+ * @param x Any math entity
+ * @return Multiplicative identity of the type of x
+ */
+ zero(x: number): 0
+ zero(x: BigNumber): BigNumber
+ zero(x: Complex): Complex
+ zero(x: bigint): 0n
+ zero(x: Fraction): Fraction
+ zero(x: boolean): true
+ zero(x: Unit): Unit
+ zero(x: MathCollection): MathCollection
+
/*************************************************************************
* Bitwise functions
************************************************************************/
@@ -4064,6 +4079,7 @@ export const {
unaryMinusDependencies,
unaryPlusDependencies,
xgcdDependencies,
+ zeroDependencies,
// bitwise dependencies
bitAndDependencies,
@@ -4863,18 +4879,34 @@ export interface Help {
}
export interface ConfigOptions {
- relTol?: number
- absTol?: number
- /**
- * @deprecated Use `relTol` and `absTol` instead
- */
- epsilon?: number
- matrix?: 'Matrix' | 'Array'
+ relTol?: number // Deprecated: use compute.defaultRelTol
+ absTol?: number // Deprecated: use compute.defaultAbsTol
+ // epsilon?: number // discontinued
+ matrix?: 'Matrix' | 'Array' // Deprecated: use compute.Matrix.defaultType
number?: 'number' | 'BigNumber' | 'bigint' | 'Fraction'
- numberFallback?: 'number' | 'BigNumber'
- precision?: number
- predictable?: boolean
- randomSeed?: string | null
+ numberFallback?: 'number' | 'BigNumber' // Deprecated: use parse.numberFallback
+ precision?: number // Deprecated: use compute.BigNumber.precision
+ predictable?: boolean // Deprecated: use compute.uniformType
+ randomSeed?: string | null // Deprecated: use compute.randomSeed
+ legacySubset?: boolean // Deprecated: use compatibility.subset
+ compatibility?: {
+ subset: boolean // Deprecated
+ }
+ compute?: {
+ defaultAbsTol?: number
+ defaultRelTol?: number
+ numberApproximate?: 'number' | 'BigNumber'
+ uniformType?: boolean
+ BigNumber?: {
+ precision?: number
+ }
+ Matrix?: {
+ defaultType?: 'Array' | 'Matrix'
+ }
+ parse?: {
+ numberFallback?: 'BigNumber' | 'Fraction' | 'number'
+ }
+ }
}
export interface MathJsChain {
@@ -5754,6 +5786,16 @@ export interface MathJsChain {
b: number | BigNumber
): MathJsChain
+ /**
+ * Generate the additive identity of the current type
+ */
+ zero(this: MathJsChain): MathJsChain<0>
+ zero(this: MathJsChain): MathJsChain
+ zero(this: MathJsChain): MathJsChain<0n>
+ zero(this: MathJsChain): MathJsChain
+ zero(this: MathJsChain): MathJsChain
+ zero(this: MathJsChain): MathJsChain
+
/**
* Count the number of elements of a matrix, array or string.
*/
@@ -7604,6 +7646,7 @@ export const {
unaryMinus,
unaryPlus,
xgcd,
+ zero,
// bitwise
bitAnd,