Merge pull request #4 from josdejong/master

0.20
This commit is contained in:
Rogelio J. Baucells 2014-04-16 17:07:03 -04:00
commit e8b6bb94fa
242 changed files with 15546 additions and 8223 deletions

View File

@ -2,9 +2,34 @@
https://github.com/josdejong/mathjs
## 2014-04-16, version 0.20.0
- Switched to module `decimal.js` for BigNumber support, instead of
`bignumber.js`.
- Implemented support for polar coordinates to the `Complex` datatype.
Thanks Finn Pauls (@finnp).
- Implemented BigNumber support for functions `exp`, `log`, and `log10`.
- Implemented conditional operator `a ? b : c` in expression parser.
- Improved floating point comparison: the functions now check whether values
are nearly equal, against a configured maximum relative difference `epsilon`.
Thanks Rogelio J. Baucells (@rjbaucells).
- Implemented function `norm`. Thanks Rogelio J. Baucells (@rjbaucells).
- Improved function `ifElse`, is now specified for special data types too.
- Improved function `det`. Thanks Bryan Cuccioli (@bcuccioli).
- Implemented `BigNumber` support for functions `det` and `diag`.
- Added unit alias `lbs` (pound mass).
- Changed configuration option `decimals` to `precision` (applies to BigNumbers
only).
- Fixed support for element-wise comparisons between a string and a matrix.
- Fixed: expression parser now trows IndexErrors with one-based indices instead
of zero-based.
- Minor bug fixes.
## 2014-03-30, version 0.19.0
- Implemented functions `compare`, `sum`, `prod`, `var`, `std`, `median`.
- Implemented function `ifElse` Thanks @mtraynham.
- Minor bug fixes.
@ -12,7 +37,7 @@ https://github.com/josdejong/mathjs
- Added unit `feet`.
- Implemented function `compile` (shortcut for parsing and then compiling).
- Improved performance of function `pow` for matrices. Thanks hamadu.
- Improved performance of function `pow` for matrices. Thanks @hamadu.
- Fixed broken auto completion in the command line interface.
- Fixed an error in function `combinations` for large numbers, and
improved performance of both functions `combinations` and `permutations`.
@ -28,12 +53,12 @@ https://github.com/josdejong/mathjs
compiled into JavaScript, giving much better performance (easily 10x as fast).
- Renamed unit conversion function and operator `in` to `to`. Operator `in` is
still available in the expression parser as an alias for `to`. Added unit
`in`, an abbreviation for `inch`. Thanks Elijah Insua (tmpvar).
`in`, an abbreviation for `inch`. Thanks Elijah Insua (@tmpvar).
- Added plurals and aliases for units.
- Implemented an argument `includeEnd` for function `range` (false by default).
- Ranges in the expression parser now support big numbers.
- Implemented functions `permutations` and `combinations`.
Thanks Daniel Levin (daniel-levin).
Thanks Daniel Levin (@daniel-levin).
- Added lower case abbreviation `l` for unit litre.
@ -105,11 +130,11 @@ https://github.com/josdejong/mathjs
use `math.format(value [, precision])` instead.
- Fixed formatting numbers as scientific notation in some cases returning
a zero digit left from the decimal point. (like "0.33333e8" rather than
"3.3333e7"). Thanks husayt.
"3.3333e7"). Thanks @husayt.
- Implemented a function `print` to interpolate values in a template string,
this functionality was moved from the function `format`.
- Implemented statistics function `mean`. Thanks Guillermo Indalecio Fernandez
(guillermobox).
(@guillermobox).
- Extended and changed `max` and `min` for multi dimensional matrices: they now
return the maximum and minimum of the flattened array. An optional second
argument `dim` allows to calculate the `max` or `min` for specified dimension.
@ -139,7 +164,7 @@ https://github.com/josdejong/mathjs
## 2013-09-03, version 0.13.0
- Implemented support for booleans in all relevant functions.
- Implemented functions `map` and `forEach`. Thanks Sebastien Piquemal (sebpic).
- Implemented functions `map` and `forEach`. Thanks Sebastien Piquemal (@sebpic).
- All construction functions can be used to convert the type of variables,
also element-wise for all elements in an Array or Matrix.
- Changed matrix indexes of the expression parser to one-based with the
@ -168,7 +193,7 @@ https://github.com/josdejong/mathjs
## 2013-08-22, version 0.12.0
- Implemented functions `random([min, max])`, `randomInt([min, max])`,
`pickRandom(array)`. Thanks Sebastien Piquemal (sebpic).
`pickRandom(array)`. Thanks Sebastien Piquemal (@sebpic).
- Implemented function `distribution(name)`, generating a distribution object
with functions `random`, `randomInt`, `pickRandom` for different
distributions. Currently supporting `uniform` and `normal`.
@ -186,7 +211,7 @@ https://github.com/josdejong/mathjs
for example `A[0, 0:3]`.
- Removed the feature introduced in v0.10.0 to automatically convert a complex
value with an imaginary part equal to zero to a number.
- Fixed zeros being formatted as null. Thanks TimKraft.
- Fixed zeros being formatted as null. Thanks @TimKraft.
## 2013-07-23, version 0.11.1
@ -203,7 +228,7 @@ https://github.com/josdejong/mathjs
- Added constants `true` and `false`.
- Added constructor function `boolean`.
- Fixed function `select` not accepting `0` as input.
Thanks Elijah Manor (elijahmanor).
Thanks Elijah Manor (@elijahmanor).
- Parser now supports multiple unary minus operators after each other.
- Fixed not accepting empty matrices like `[[], []]`.
- Some fixes in the end user documentation.
@ -219,7 +244,7 @@ https://github.com/josdejong/mathjs
- Implemented end user documentation and a new `help` function.
- Functions `size` and `squeeze` now return a Matrix instead of an Array as
output on Matrix input.
- Added a constant tau (2 * pi). Thanks Zak Zibrat (palimpsests).
- Added a constant tau (2 * pi). Thanks Zak Zibrat (@palimpsests).
- Renamed function `unaryminus` to `unary`.
- Fixed a bug in determining node dependencies in function assignments.
@ -246,7 +271,7 @@ https://github.com/josdejong/mathjs
or other data types.
- Implemented construction functions number and string (mainly useful inside
the parser).
- Improved function `det`. Thanks Bryan Cuccioli (bcuccioli).
- Improved function `det`. Thanks Bryan Cuccioli (@bcuccioli).
- Moved the parse code from prototype math.expr.Parser to function math.parse,
simplified Parser a little bit.
- Strongly simplified the code of Scope and Workspace.
@ -286,7 +311,7 @@ https://github.com/josdejong/mathjs
## 2013-05-04, version 0.7.2
- Fixed method unequal, which was checking for equality instead of inequality.
Thanks FJS2.
Thanks @FJS2.
## 2013-04-27, version 0.7.1
@ -310,7 +335,7 @@ https://github.com/josdejong/mathjs
- Implemented method `math.eval`, which uses a readonly parser to evaluate
expressions.
- Implemented method `xgcd` (extended eucledian algorithm). Thanks Bart Kiers
(bkiers).
(@bkiers).
- Improved math.format, which now rounds values to a maximum number of digits
instead of decimals (default is 5 digits, for example `math.format(math.pi)`
returns `3.1416`).

View File

@ -1,6 +1,6 @@
{
"name": "mathjs",
"version": "0.19.0",
"version": "0.20.0",
"main": "./dist/math.js",
"ignore": [
"coverage",

17973
dist/math.js vendored

File diff suppressed because it is too large Load Diff

2
dist/math.map vendored

File diff suppressed because one or more lines are too long

17
dist/math.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,12 @@
# Configuration
Math.js contains a number of configuration settings. Configuration can be set
Math.js contains a number of configuration options. Configuration can be set
when creating a math.js instance, or later on using the function `config`.
Available configuration settings are:
Available configuration options are:
- `epsilon`. The minimum relative difference used to test equality between two
compared values. This value is used by all comparison functions.
Default value is `1e-14`.
- `matrix`. The default type of matrix output for functions.
Available values are: `'matrix'` (default) or `'array'`.
@ -16,18 +20,13 @@ Available configuration settings are:
like `eval `which cannot determine the correct type of output from the
functions input. For most functions though, the type of output is determined
from the the input: a number as input will return a number as output,
a bignumber as input returns a bignumber as output.
a BigNumber as input returns a BigNumber as output.
Available values are: `'number'` (default) or `'bignumber'`.
Big numbers have higher precision than the default numbers of JavaScript.
BigNumbers have higher precision than the default numbers of JavaScript.
- `decimals`. The maximum number of decimal places behind the decimal
point (not the number of significant digits). Only applies to big numbers,
not to numbers. Default value is 20.
*Important: This setting is applied application wide to all BigNumbers.
Behind the scenes, this setting is applied as the global `DECIMAL_PLACES`
setting of the [bignumber.js](https://github.com/MikeMcl/bignumber.js)
library used by math.js.*
- `precision`. The maximum number of significant digits for bigNumbers.
This setting only applies to BigNumbers, not to numbers.
Default value is `20`.
## Examples
@ -35,7 +34,7 @@ Available configuration settings are:
This section shows a number of configuration examples.
### Default settings
### Default configuration
```js
// load the library
@ -54,11 +53,11 @@ math1.range(0, 4); // Matrix [0, 1, 2, 3]
// load the library
var mathjs = require('mathjs');
// create an instance of math.js with configuration settings
var settings = {
// create an instance of math.js with configuration options
var config = {
matrix: 'array'
};
var math2 = mathjs(settings);
var math2 = mathjs(config);
// range will output an Array
math2.range(0, 4); // Array [0, 1, 2, 3]
@ -72,16 +71,16 @@ math2.config({
math2.range(0, 4); // Matrix [0, 1, 2, 3]
```
### Configuration for big numbers
### Configuration for BigNumbers
```js
// load the library
var mathjs = require('mathjs');
// use big numbers by default
// use BigNumbers by default
var math3 = mathjs({
number: 'bignumber',
decimals: 32
precision: 32
});
// parser will parse numbers as BigNumber now:

View File

@ -1,36 +1,39 @@
# Big Numbers
# BigNumbers
For calculations with an arbitrary precision, math.js supports BigNumber.
BigNumber is powered by the the library
[bignumber.js](https://github.com/MikeMcl/bignumber.js/).
For calculations with an arbitrary precision, math.js supports a `BigNumber`
data type. BigNumber support is powered by
[decimal.js](https://github.com/MikeMcl/decimal.js/).
A big number can be created using the function `bignumber`:
A BigNumber can be created using the function `bignumber`:
```js
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
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.eval`) use the default number type `number`,
which can be configured when instantiating math.js. To configure the use of big
numbers instead of [numbers](numbers.md) by default, configure math.js like:
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
var mathjs = require('mathjs'),
math = mathjs({
number: 'bignumber', // Default type of number: 'number' (default) or 'bignumber'
decimals: 20 // Number decimal places behind the dot for big numbers
precision: 20 // Number of significant digits for BigNumbers
});
// use math
math.eval('0.1 + 0.2'); // BigNumber, 0.3
```
The default precision for BigNumber is 20 digits, and can be configured with
the option `precision`.
*Important:
BigNumber is not supported by the following functions:
exp, gcd, lcm, log, log10, xgcd,
gcd, lcm, xgcd,
arg,
random,
acos, asin, atan, atan2, cos, cot, csc, sec, sin, tan.
@ -45,29 +48,18 @@ precision, it is less likely that round-off errors occur:
math.add(0.1, 0.2); // Number, 0.30000000000000004
math.divide(0.3, 0.2); // Number, 1.4999999999999998
// no round-off errors with big numbers :)
// no round-off errors with BigNumbers :)
math.add(math.bignumber(0.1), math.bignumber(0.2)); // BigNumber, 0.3
math.divide(math.bignumber(0.3), math.bignumber(0.2)); // BigNumber, 1.5
```
The default precision for BigNumber is 20 digits. This is a global setting
in the [underlying BigNumber library](https://github.com/MikeMcl/bignumber.js/),
which can be changed by configuring BigNumber:
```js
BigNumber.config({DECIMAL_PLACES: 32});
```
*Important: To work with small numbers, `DECIMAL_PLACES` must be configured
sufficiently large.*
Big numbers can be converted to numbers and vice versa using the functions
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`.
```js
// converting numbers and bignumbers
// converting numbers and BigNumbers
var a = math.number(0.3); // Number, 0.3
var b = math.bignumber(a); // BigNumber, 0.3
var c = math.number(b); // Number, 0.3

View File

@ -14,9 +14,14 @@ signal analysis, fluid dynamics and other fields.
## API
A complex number is created using the function `math.complex`. This function
accepts two numbers representing the real and imaginary part of the value,
or a single string containing a complex value in the form `a + bi` where `a`
and `b` respectively represent the real and imaginary part of the complex number.
accepts:
- two numbers representing the real and imaginary part of the value,
- a single string containing a complex value in the form `a + bi` where `a`
and `b` respectively represent the real and imaginary part of the complex number.
- an object with either properties `re` and `im` for the real and imaginary
part of the value, or two properties `r` and `phi` containing the polar
coordinates of a complex value.
The function returns a `Complex` object.
Syntax:
@ -25,6 +30,8 @@ Syntax:
math.complex(re: number) : Complex
math.complex(re: number, im: number) : Complex
math.complex(complex: Complex) : Complex
math.complex({re: Number, im: Number}) : Complex
math.complex({r: number, phi: number}) : Complex
math.complex(str: string) : Complex
```
@ -53,7 +60,13 @@ A `Complex` object has the following functions:
- `equals(other)`. Test whether a complex number equals an other complex value.
Two complex numbers are equal when both their real and imaginary parts are
equal.
- `format([precision])`. Get a string representation of the complex number,
- `fromPolar(r: number, phi: number)`. Create a complex number from polar
coordinates.
- `fromPolar({r: number, phi: number})`. Create a complex number from polar
coordinates.
- `toPolar()`. Get the polar coordinates of the complex number, returns
an object with properties `r` and `phi`.
- `format([precision: number])`. Get a string representation of the complex number,
formatted as `a + bi` where `a` is the real part and `b` the imaginary part.
If precision is defined, the units value will be rounded to the provided
number of digits.

View File

@ -24,7 +24,7 @@ math.subtract(7.1, 2.3); // 4.8
math.round(math.pi, 3); // 3.142
math.sqrt(4.41e2); // 21
// use big numbers
// use BigNumbers
math.add(math.bignumber(0.1), math.bignumber(0.2)); // BigNumber, 0.3
// use strings

View File

@ -4,11 +4,13 @@ Math.js supports two types of numbers:
- Number for fast floating point arithmetic, described on this page.
- BigNumber for arbitrary precision arithmetic, describe on the page
[Big Numbers](bignumbers.md).
[BigNumbers](bignumbers.md).
## Configuration
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
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.eval`) use the default number type, which
can be configured when instantiating math.js:
@ -19,6 +21,8 @@ var mathjs = require('mathjs'),
});
```
## Round-off errors
Math.js uses the built-in JavaScript Number type. A Number is a floating point
number with a limited precision of 64 bits, about 16 digits. The largest integer
number which can be represented by a JavaScript Number
@ -43,6 +47,8 @@ var ans = math.add(0.1, 0.2); // 0.30000000000000004
math.format(ans, {precision: 14}); // '0.3'
```
## Minimum and maximum
A Number can store values between `5e-324` and `1.7976931348623157e+308`.
Values smaller than the minimum are stored as `0`, and values larger than the
maximum are stored as `+/- Infinity`.
@ -52,3 +58,43 @@ maximum are stored as `+/- Infinity`.
console.log(1e309); // Infinity
console.log(1e-324); // 0
```
## Comparison
Because of rounding errors in calculations, it is unsafe to compare JavaScript
Numbers. For example executing `0.1 + 0.2 == 0.3` in JavaScript will return
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 comparison functions of math.js check whether the
relative difference between the compared values is smaller than the configured
option `epsilon`. In pseudo code (without exceptions for 0, Infinity and NaN):
diff = abs(x - y)
nearlyEqual = (diff <= max(abs(x), abs(y)) * EPSILON) OR (diff < DBL_EPSILON)
where:
- `EPSILON` is the relative difference between x and y. Epsilon is configurable
and is `1e-14` by default. See [Configuration](../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`;
Note that the comparison functions cannot be used to compare small values
(`< 2.22e-16`). These values are all considered equal to zero.
Examples:
```js
// compare values having a round-off error
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
console.log(3e-20 == 3.1e-20); // false
console.log(math.equal(3e-20, 3.1e-20)); // true
```
The available comparison functions are: `compare`, `equal`, `larger`,
`largereq`, `smaller`, `smallereq`, `unequal`.

View File

@ -15,7 +15,7 @@ full name and an abbreviation. The returned object is a `Unit`.
Syntax:
```js
math.unit(value: number, plainUnit: string) : Unit
math.unit(value: number, name: string) : Unit
math.unit(unit: string) : Unit
math.unit(unit: Unit) : Unit
```
@ -35,10 +35,10 @@ A `Unit` contains the following functions:
length, mass, etc.
- `equals(unit)`. Test whether a unit equals an other unit. Units are equal
when they have the same base and same value when normalized to SI units.
- `to(plainUnit)`. Convert the unit to a specific prefix and unit. Returns
a clone of the unit with a fixed prefix and unit.
- `toNumber(plainUnit)`. Get the value of a unit when converted to the specified
plain unit (a unit with optional prefix but without value).
- `to(unitName)`. Convert the unit to a specific unit name. Returns a clone of
the unit with a fixed prefix and unit.
- `toNumber(unitName)`. Get the value of a unit when converted to the
specified unit (a unit with optional prefix but without value).
- `format([precision])`. Get a string representation of the unit. The function
will determine the best fitting prefix for the unit. If precision is defined,
the units value will be rounded to the provided number of digits.

View File

@ -268,35 +268,36 @@ math.eval('(2 + 3) * 4'); // 20
The following operators are available:
Operator | Name | Syntax | Associativity | Example | Result
----------- | --------------------- | --------- | ------------- | --------------------- | ---------------
`(`, `)` | Parentheses | `(x)` | None | `2 * (3 + 4)` | `14`
`[`, `]` | Matrix, Index | `[...]` | None | `[[1,2],[3,4]]` | `[[1,2],[3,4]]`
`,` | Parameter separator | `x, y` | None | `max(2, 1, 5)` | `5`
`;` | Statement separator | `x; y` | Left to right | `a=2; b=3; a*b` | `[6]`
`;` | Row separator | `[x, y]` | Left to right | `[1,2;3,4]` | `[[1,2],[3,4]]`
`\n` | Statement separator | `x \n y` | Left to right | `a=2 \n b=3 \n a*b` | `[2,3,6]`
`+` | Add | `x + y` | Left to right | `4 + 5` | `9`
`-` | Subtract | `x - y` | Left to right | `7 - 3` | `4`
`*` | Multiply | `x * y` | Left to right | `2 * 3` | `6`
`.*` | Element-wise multiply | `x .* y` | Left to right | `[1,2,3] .* [1,2,3]` | `[1,4,9]`
`/` | Divide | `x / y` | Left to right | `6 / 2` | `3`
`./` | Element-wise divide | `x ./ y` | Left to right | `[9,6,4] ./ [3,2,2]` | `[3,3,2]`
`%`, `mod` | Modulus | `x % y` | Left to right | `8 % 3` | `2`
`^` | Power | `x ^ y` | Right to left | `2 ^ 3` | `8`
`.^` | Element-wise power | `x .^ y` | Right to left | `[2,3] .^ [3,3]` | `[9,27]`
`-` | Unary | `-y` | None | `-4` | `-4`
`'` | Transpose | `y'` | None | `[[1,2],[3,4]]'` | `[[1,3],[2,4]]`
`!` | Factorial | `y!` | None | `5!` | `120`
`=` | Assignment | `x = y` | Right to left | `a = 5` | `5`
`:` | Range | `x : y` | None | `1:4` | `[1,2,3,4]`
`to`, `in` | Unit conversion | `x to y` | Left to right | `2 inch to cm` | `5.08 cm`
`==` | Equal | `x == y` | Left to right | `2 == 4 - 2` | `true`
`!=` | Unequal | `x != y` | Left to right | `2 != 3` | `true`
`<` | Smaller | `x < y` | Left to right | `2 < 3` | `true`
`>` | Larger | `x > y` | Left to right | `2 > 3` | `false`
`<=` | Smallereq | `x <= y` | Left to right | `4 <= 3` | `false`
`>=` | Largereq | `x >= y` | Left to right | `2 + 4 >= 6` | `true`
Operator | Name | Syntax | Associativity | Example | Result
----------- | ----------------------- | ---------- | ------------- | --------------------- | ---------------
`(`, `)` | Parentheses | `(x)` | None | `2 * (3 + 4)` | `14`
`[`, `]` | Matrix, Index | `[...]` | None | `[[1,2],[3,4]]` | `[[1,2],[3,4]]`
`,` | Parameter separator | `x, y` | None | `max(2, 1, 5)` | `5`
`;` | Statement separator | `x; y` | Left to right | `a=2; b=3; a*b` | `[6]`
`;` | Row separator | `[x, y]` | Left to right | `[1,2;3,4]` | `[[1,2],[3,4]]`
`\n` | Statement separator | `x \n y` | Left to right | `a=2 \n b=3 \n a*b` | `[2,3,6]`
`+` | Add | `x + y` | Left to right | `4 + 5` | `9`
`-` | Subtract | `x - y` | Left to right | `7 - 3` | `4`
`*` | Multiply | `x * y` | Left to right | `2 * 3` | `6`
`.*` | Element-wise multiply | `x .* y` | Left to right | `[1,2,3] .* [1,2,3]` | `[1,4,9]`
`/` | Divide | `x / y` | Left to right | `6 / 2` | `3`
`./` | Element-wise divide | `x ./ y` | Left to right | `[9,6,4] ./ [3,2,2]` | `[3,3,2]`
`%`, `mod` | Modulus | `x % y` | Left to right | `8 % 3` | `2`
`^` | Power | `x ^ y` | Right to left | `2 ^ 3` | `8`
`.^` | Element-wise power | `x .^ y` | Right to left | `[2,3] .^ [3,3]` | `[9,27]`
`-` | Unary | `-y` | None | `-4` | `-4`
`'` | Transpose | `y'` | None | `[[1,2],[3,4]]'` | `[[1,3],[2,4]]`
`!` | Factorial | `y!` | None | `5!` | `120`
`=` | Assignment | `x = y` | Right to left | `a = 5` | `5`
`?` `:` | Conditional expression | `x ? y : z` | Right to left | `15 > 100 ? 1 : -1` | `-1`
`:` | Range | `x : y` | None | `1:4` | `[1,2,3,4]`
`to`, `in` | Unit conversion | `x to y` | Left to right | `2 inch to cm` | `5.08 cm`
`==` | Equal | `x == y` | Left to right | `2 == 4 - 2` | `true`
`!=` | Unequal | `x != y` | Left to right | `2 != 3` | `true`
`<` | Smaller | `x < y` | Left to right | `2 < 3` | `true`
`>` | Larger | `x > y` | Left to right | `2 > 3` | `false`
`<=` | Smallereq | `x <= y` | Left to right | `4 <= 3` | `false`
`>=` | Largereq | `x >= y` | Left to right | `2 + 4 >= 6` | `true`
The operators have the following precedence, from highest to lowest:
@ -313,6 +314,7 @@ Operators | Description
`:` | Range
`==`, `!=`, `<`, `>`, `<=`, `>=` | Comparison
`to`, `in` | Unit conversion
`?`, `:` | Conditional expression
`=` | Assignment
`,` | Parameter and column separator
`;` | Row separator
@ -454,9 +456,9 @@ math.format(ans, {precision: 14}); // "0.3"
```
#### Big numbers
#### BigNumbers
Math.js supports big numbers for calculations with an arbitrary precision.
Math.js supports BigNumbers for calculations with an arbitrary precision.
The pros and cons of Number and BigNumber are explained in detail on the page
[Numbers](datatypes/numbers.md).
@ -482,7 +484,7 @@ var mathjs = require('mathjs'),
math.eval('0.1 + 0.2'); // BigNumber, 0.3
```
Big numbers can be converted to numbers and vice versa using the functions
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`.

View File

@ -44,6 +44,7 @@ math.add('hello ', 'world!'); // String 'hello world!'
- math.log10(x)
- math.mod(x, y)
- math.multiply(x, y)
- math.norm(x [, p])
- math.pow(x, y)
- math.round(x [, n])
- math.sign()
@ -139,11 +140,11 @@ math.add('hello ', 'world!'); // String 'hello world!'
## Utils
- math.config(settings)
- math.config(options)
- math.clone(x)
- math.forEach(x, callback)
- math.format(value [, precision])
- math.ifElse(conditionalExpr, trueExpr, falseExpr)
- math.ifElse(condition, trueExpr, falseExpr)
- math.import(filename | object, override)
- math.map(x, callback)
- math.print(template, values [, precision])

View File

@ -37,7 +37,7 @@ Or by downloading the latest version from
Math.js can be used in node.js and in the browser. The library must be loaded
and instantiated. When creating an instance, one can optionally provide
configuration settings as described in
configuration options as described in
[Configuration](https://github.com/josdejong/mathjs/blob/master/docs/configuration.md).
### Node.js

View File

@ -7,7 +7,7 @@
- [Chained Operations](chained_operations.md)
- [Data Types](datatypes/index.md)
- [Numbers](datatypes/numbers.md)
- [Big Numbers](datatypes/bignumbers.md)
- [BigNumbers](datatypes/bignumbers.md)
- [Complex Numbers](datatypes/complex_numbers.md)
- [Matrices](datatypes/matrices.md)
- [Units](datatypes/units.md)

View File

@ -1,11 +1,11 @@
// big numbers
// BigNumbers
// load math.js and create an instance
// the default type of numbers is configured as big numbers
// the default type of numbers is configured as BigNumbers
var mathjs = require('../index'),
math = mathjs({
number: 'bignumber', // Default type of number: 'number' (default) or 'bignumber'
decimals: 20 // number decimal places behind the dot for big numbers
precision: 20 // Number of significant digits for BigNumbers
});
/**
@ -21,19 +21,19 @@ print(math.add(0.1, 0.2)); // Number, 0.30000000000000004
print(math.divide(0.3, 0.2)); // Number, 1.4999999999999998
console.log();
console.log('no round-off errors with big numbers');
console.log('no round-off errors with BigNumbers');
print(math.add(math.bignumber(0.1), math.bignumber(0.2))); // BigNumber, 0.3
print(math.divide(math.bignumber(0.3), math.bignumber(0.2))); // BigNumber, 1.5
console.log();
console.log('create big numbers from strings when exceeding the range of a number');
console.log('create BigNumbers from strings when exceeding the range of a number');
print(math.bignumber(1.2e+500)); // BigNumber, Infinity WRONG
print(math.bignumber('1.2e+500')); // BigNumber, 1.2e+500
console.log();
// one can work conveniently with big numbers using the expression parser.
// note though that big numbers are only supported in arithmetic functions
console.log('use big numbers in the expression parser');
// one can work conveniently with BigNumbers using the expression parser.
// note though that BigNumbers are only supported in arithmetic functions
console.log('use BigNumbers in the expression parser');
print(math.eval('0.1 + 0.2')); // BigNumber, 0.3
print(math.eval('0.3 / 0.2')); // BigNumber, 1.5
console.log();

View File

@ -44,3 +44,12 @@ print(math.sin(a)); // -9.6541 + 2.8417i
// some operations will return a complex number depending on the arguments
print(math.sqrt(4)); // 2
print(math.sqrt(-4)); // 2i
// create a complex number from polar coordinates
console.log('create complex numbers with polar coordinates');
var c = math.complex({r: math.sqrt(2), phi: math.pi / 4});
print(c); // 1 + i
// get polar coordinates of a complex number
var d = math.complex(3, 4);
console.log(d.toPolar()); // { r: 5, phi: 0.9272952180016122 }

View File

@ -13,7 +13,7 @@ function print (value) {
console.log(math.format(value, precision));
}
// units can be created by providing a value and plain unit, or by providing
// units can be created by providing a value and unit name, or by providing
// a string with a valued unit.
console.log('create units');
var a = math.unit(45, 'cm');

View File

@ -0,0 +1,31 @@
/**
* Create a syntax error with the message:
* 'Wrong number of arguments in function <fn> (<count> provided, <min>-<max> expected)'
* @param {String} fn Function name
* @param {Number} count Actual argument count
* @param {Number} min Minimum required argument count
* @param {Number} [max] Maximum required argument count
* @extends Error
*/
function ArgumentsError(fn, count, min, max) {
if (!(this instanceof ArgumentsError)) {
throw new SyntaxError('Constructor must be called with the new operator');
}
this.fn = fn;
this.count = count;
this.min = min;
this.max = max;
this.message = 'Wrong number of arguments in function ' + fn +
' (' + count + ' provided, ' +
min + ((max != undefined) ? ('-' + max) : '') + ' expected)';
this.stack = (new Error()).stack;
}
ArgumentsError.prototype = new Error();
ArgumentsError.prototype.constructor = Error;
ArgumentsError.prototype.name = 'ArgumentsError';
module.exports = ArgumentsError;

View File

@ -0,0 +1,32 @@
/**
* Create a range error with the message:
* 'Dimension mismatch (<actual size> != <expected size>)'
* @param {number | number[]} actual The actual size
* @param {number | number[]} expected The expected size
* @param {string} [relation='!='] Optional relation between actual
* and expected size: '!=', '<', etc.
* @extends RangeError
*/
function DimensionError(actual, expected, relation) {
if (!(this instanceof DimensionError)) {
throw new SyntaxError('Constructor must be called with the new operator');
}
this.actual = actual;
this.expected = expected;
this.relation = relation;
this.message = 'Dimension mismatch (' +
(Array.isArray(actual) ? ('[' + actual.join(', ') + ']') : actual) +
' ' + (this.relation || '!=') + ' ' +
(Array.isArray(expected) ? ('[' + expected.join(', ') + ']') : expected) +
')';
this.stack = (new Error()).stack;
}
DimensionError.prototype = new RangeError();
DimensionError.prototype.constructor = RangeError;
DimensionError.prototype.name = 'DimensionError';
module.exports = DimensionError;

43
lib/error/IndexError.js Normal file
View File

@ -0,0 +1,43 @@
/**
* Create a range error with the message:
* 'Index out of range (index < min)'
* 'Index out of range (index < max)'
*
* @param {number} index The actual index
* @param {number} [min=0] Minimum index (included)
* @param {number} [max] Maximum index (excluded)
* @extends RangeError
*/
function IndexError(index, min, max) {
if (!(this instanceof IndexError)) {
throw new SyntaxError('Constructor must be called with the new operator');
}
this.index = index;
if (arguments.length < 3) {
this.min = 0;
this.max = min;
}
else {
this.min = min;
this.max = max;
}
if (this.min !== undefined && this.index < this.min) {
this.message = 'Index out of range (' + this.index + ' < ' + this.min + ')';
}
else if (this.max !== undefined && this.index >= this.max) {
this.message = 'Index out of range (' + this.index + ' > ' + (this.max - 1) + ')';
}
else {
this.message = 'Index out of range (' + this.index + ')';
}
this.stack = (new Error()).stack;
}
IndexError.prototype = new RangeError();
IndexError.prototype.constructor = RangeError;
IndexError.prototype.name = 'IndexError';
module.exports = IndexError;

View File

@ -0,0 +1,35 @@
/**
* Create a TypeError with message:
* 'Function <fn> does not support a parameter of type <type>';
* @param {String} fn Function name
* @param {*...} [types] The types of the function arguments
* @extends TypeError
*/
function UnsupportedTypeError(fn, types) {
if (!(this instanceof UnsupportedTypeError)) {
throw new SyntaxError('Constructor must be called with the new operator');
}
this.fn = fn;
this.types = Array.prototype.splice.call(arguments, 1);
if (!fn) {
this.message = 'Unsupported type of argument';
}
else {
if (this.types.length == 0) {
this.message = 'Unsupported type of argument in function ' + fn;
}
else {
this.message = 'Function ' + fn + '(' + this.types.join(', ') + ') not supported';
}
}
this.stack = (new Error()).stack;
}
UnsupportedTypeError.prototype = new TypeError();
UnsupportedTypeError.prototype.constructor = TypeError;
UnsupportedTypeError.prototype.name = 'UnsupportedTypeError';
module.exports = UnsupportedTypeError;

6
lib/error/index.js Normal file
View File

@ -0,0 +1,6 @@
exports.ArgumentsError = require('./ArgumentsError');
exports.DimensionError = require('./DimensionError');
exports.IndexError = require('./IndexError');
exports.UnsupportedTypeError = require('./UnsupportedTypeError');
// TODO: implement an InvalidValueError?

View File

@ -0,0 +1,15 @@
module.exports = {
'name': 'norm',
'category': 'Arithmetic',
'syntax': [
'norm(x)',
'norm(x, p)'
],
'description': 'Calculate the norm of a number, vector or matrix.',
'examples': [
'norm([[1, 2], [3, 4]])',
'norm([[1, 2, 3, 4]], 3.5)',
'norm(-4.2)',
'norm([[1, 2], [-3, -4]], \'fro\')'
]
};

View File

@ -2,11 +2,13 @@ module.exports = {
'name': 'ifElse',
'category': 'Utils',
'syntax': [
'ifElse(conditionalExpr, trueExpr, falseExpr)'
'ifElse(conditional, trueExpr, falseExpr)'
],
'description': 'Executes a ternary operation.',
'description': 'Executes a conditional expression.',
'examples': [
'ifElse(10 > 0, 10, 0)'
'ifElse(10 > 0, 10, 0)',
'ifElse("", true, false)',
'ifElse([4, 6, 0, -1], true, false)'
],
'seealso': []
};

View File

@ -38,6 +38,7 @@ exports.log = require('./function/arithmetic/log');
exports.log10 = require('./function/arithmetic/log10');
exports.mod = require('./function/arithmetic/mod');
exports.multiply = require('./function/arithmetic/multiply');
exports.norm = require('./function/arithmetic/norm');
exports.pow = require('./function/arithmetic/pow');
exports.round = require('./function/arithmetic/round');
exports.sign = require('./function/arithmetic/sign');

View File

@ -2,7 +2,6 @@ var Node = require('./Node'),
object = require('../../util/object'),
string = require('../../util/string'),
collection = require('../../type/collection'),
Matrix = require('../../type/Matrix'),
util = require('../../util/index'),
isArray = Array.isArray,
@ -50,7 +49,7 @@ ArrayNode.prototype._compile = function (defs) {
/**
* Find all nodes matching given filter
* @param {Object} filter See Node.find for a description of the filter settings
* @param {Object} filter See Node.find for a description of the filter options
* @returns {Node[]} nodes
*/
ArrayNode.prototype.find = function (filter) {

View File

@ -37,7 +37,7 @@ AssignmentNode.prototype._compile = function (defs) {
/**
* Find all nodes matching given filter
* @param {Object} filter See Node.find for a description of the filter settings
* @param {Object} filter See Node.find for a description of the filter options
* @returns {Node[]} nodes
*/
AssignmentNode.prototype.find = function (filter) {

View File

@ -64,7 +64,7 @@ BlockNode.prototype._compile = function (defs) {
/**
* Find all nodes matching given filter
* @param {Object} filter See Node.find for a description of the filter settings
* @param {Object} filter See Node.find for a description of the filter options
* @returns {Node[]} nodes
*/
BlockNode.prototype.find = function (filter) {

View File

@ -1,6 +1,4 @@
var Node = require('./Node'),
Complex = require('../../type/Complex'),
BigNumber = require('bignumber.js'),
string = require('../../util/string'),
isString = string.isString;

View File

@ -42,7 +42,7 @@ FunctionNode.prototype._compile = function (defs) {
' scope = Object.create(scope); ' +
' var fn = function ' + this.name + '(' + this.args.join(',') + ') {' +
' if (arguments.length != ' + this.args.length + ') {' +
// TODO: use math.error.ArgumentsError here
// TODO: use util.error.ArgumentsError here
// TODO: test arguments error
' throw new SyntaxError("Wrong number of arguments in function ' + this.name + ' (" + arguments.length + " provided, ' + this.args.length + ' expected)");' +
' }' +
@ -58,7 +58,7 @@ FunctionNode.prototype._compile = function (defs) {
/**
* Find all nodes matching given filter
* @param {Object} filter See Node.find for a description of the filter settings
* @param {Object} filter See Node.find for a description of the filter options
* @returns {Node[]} nodes
*/
FunctionNode.prototype.find = function (filter) {

View File

@ -1,20 +1,15 @@
var number= require('../../util/number.js'),
var Node = require('./Node.js'),
RangeNode = require('./RangeNode'),
SymbolNode = require('./SymbolNode'),
Node = require('./Node.js'),
RangeNode = require('./RangeNode.js'),
SymbolNode = require('./SymbolNode.js'),
BigNumber = require('bignumber.js'),
Index = require('../../type/Index.js'),
Range = require('../../type/Range.js'),
isNumber = number.isNumber,
toNumber = number.toNumber,
isNode = Node.isNode;
/**
* @constructor IndexNode
* @extends Node
*
* get a subset of a matrix
*
* @param {Node} object
* @param {Node[]} ranges
*/

View File

@ -1,4 +1,6 @@
/**
var error = require('../../error');
/**
* Node
*/
function Node() {
@ -32,7 +34,8 @@ Node.prototype.compile = function (math) {
// definitions globally available inside the closure of the compiled expressions
var defs = {
math: math
math: math,
error: error
};
var code = this._compile(defs);
@ -43,12 +46,20 @@ Node.prototype.compile = function (math) {
var factoryCode =
defsCode.join(' ') +
'return {' +
' "eval": function (scope) {' +
' scope = scope || {};' +
' return ' + code + ';' +
' }' +
'};';
'return {' +
' "eval": function (scope) {' +
' try {' +
' scope = scope || {};' +
' return ' + code + ';' +
' } catch (err) {' +
// replace an index-out-of-range-error with a one-based message
' if (err instanceof defs.error.IndexError) {' +
' err = new defs.error.IndexError(err.index + 1, err.min + 1, err.max + 1);' +
' }' +
' throw err;' +
' }' +
' }' +
'};';
var factory = new Function ('defs', factoryCode);
return factory(defs);

View File

@ -43,7 +43,7 @@ OperatorNode.prototype._compile = function (defs) {
/**
* Find all nodes matching given filter
* @param {Object} filter See Node.find for a description of the filter settings
* @param {Object} filter See Node.find for a description of the filter options
* @returns {Node[]} nodes
*/
OperatorNode.prototype.find = function (filter) {

View File

@ -1,15 +1,5 @@
var number= require('../../util/number'),
var Node = require('./Node'),
Node = require('./Node'),
RangeNode = require('./RangeNode'),
SymbolNode = require('./SymbolNode'),
BigNumber = require('bignumber.js'),
Index = require('../../type/Index'),
Range = require('../../type/Range'),
isNumber = number.isNumber,
toNumber = number.toNumber,
isNode = Node.isNode;
/**
@ -55,7 +45,7 @@ ParamsNode.prototype._compile = function (defs) {
/**
* Find all nodes matching given filter
* @param {Object} filter See Node.find for a description of the filter settings
* @param {Object} filter See Node.find for a description of the filter options
* @returns {Node[]} nodes
*/
ParamsNode.prototype.find = function (filter) {

View File

@ -1,12 +1,5 @@
var number = require('../../util/number'),
Node = require('./Node'),
var Node = require('./Node'),
BigNumber = require('bignumber.js'),
Range = require('../../type/Range'),
Matrix = require('../../type/Matrix'),
toNumber = number.toNumber,
isArray = Array.isArray;
isNode = Node.isNode;
/**
@ -21,7 +14,7 @@ function RangeNode (params) {
}
// validate inputs
if (!isArray(params) ||
if (!Array.isArray(params) ||
(params.length != 2 && params.length != 3) ||
!params.every(isNode)) {
throw new TypeError('Expected an Array containing 2 or 3 Nodes as parameter "params"');
@ -52,7 +45,7 @@ RangeNode.prototype._compile = function (defs) {
/**
* Find all nodes matching given filter
* @param {Object} filter See Node.find for a description of the filter settings
* @param {Object} filter See Node.find for a description of the filter options
* @returns {Node[]} nodes
*/
RangeNode.prototype.find = function (filter) {

View File

@ -39,7 +39,7 @@ SymbolNode.prototype._compile = function (defs) {
return '(' +
'scope["' + this.name + '"] !== undefined ? scope["' + this.name + '"] : ' +
'math["' + this.name + '"] !== undefined ? math["' + this.name + '"] : ' +
(Unit.isPlainUnit(this.name) ?
(Unit.isValuelessUnit(this.name) ?
'new Unit(null, "' + this.name + '")' :
'undef("' + this.name + '")') +
')';

View File

@ -0,0 +1,38 @@
var OperatorNode = require('./OperatorNode');
/**
* @constructor TernaryNode
* @extends {OperatorNode}
*
* A conditional expression
*
* condition ? truePart : falsePart
*
* @param {String[]} ops The operator symbols, for example ['?', ':']
* @param {String} fn The function name, for example 'ifElse'
* @param {Node[]} params The operator parameters, should contain three parameters.
*/
function TernaryNode (ops, fn, params) {
if (!(this instanceof TernaryNode)) {
throw new SyntaxError('Constructor must be called with the new operator');
}
// TODO: validate input
this.ops = ops;
this.fn = fn;
this.params = params;
}
TernaryNode.prototype = new OperatorNode();
/**
* Get string representation
* @return {String} str
*/
TernaryNode.prototype.toString = function() {
return this.params[0] + ' ' + this.ops[0] + ' ' +
this.params[1] + ' ' + this.ops[1] + ' ' +
this.params[2];
};
module.exports = TernaryNode;

View File

@ -1,10 +1,7 @@
var Node = require('./Node'),
BigNumber = require('bignumber.js'),
Complex = require('../../type/Complex'),
Unit = require('../../type/Unit'),
toNumber = require('../../util/number').toNumber,
isString = require('../../util/string').isString;
/**
@ -43,7 +40,7 @@ UnitNode.prototype._compile = function (defs) {
/**
* Find all nodes matching given filter
* @param {Object} filter See Node.find for a description of the filter settings
* @param {Object} filter See Node.find for a description of the filter options
* @returns {Node[]} nodes
*/
UnitNode.prototype.find = function (filter) {

View File

@ -1,16 +1,5 @@
var number= require('../../util/number'),
Node = require('./Node'),
RangeNode = require('./RangeNode'),
IndexNode = require('./IndexNode'),
SymbolNode = require('./SymbolNode'),
BigNumber = require('bignumber.js'),
Index = require('../../type/Index'),
Range = require('../../type/Range'),
isNumber = number.isNumber,
toNumber = number.toNumber;
var Node = require('./Node'),
IndexNode = require('./IndexNode');
/**
* @constructor UpdateNode
@ -53,7 +42,7 @@ UpdateNode.prototype._compile = function (defs) {
/**
* Find all nodes matching given filter
* @param {Object} filter See Node.find for a description of the filter settings
* @param {Object} filter See Node.find for a description of the filter options
* @returns {Node[]} nodes
*/
UpdateNode.prototype.find = function (filter) {

View File

@ -9,5 +9,6 @@ exports.OperatorNode = require('./OperatorNode');
exports.ParamsNode = require('./ParamsNode');
exports.RangeNode = require('./RangeNode');
exports.SymbolNode = require('./SymbolNode');
exports.TernaryNode = require('./TernaryNode');
exports.UnitNode = require('./UnitNode');
exports.UpdateNode = require('./UpdateNode');

View File

@ -1,6 +1,5 @@
var util = require('../util/index'),
toNumber = util.number.toNumber,
isString = util.string.isString,
isArray = Array.isArray,
type = util.types.type,
@ -22,6 +21,7 @@ var util = require('../util/index'),
ParamsNode = require('./node/ParamsNode'),
RangeNode = require('./node/RangeNode'),
SymbolNode = require('./node/SymbolNode'),
TernaryNode = require('./node/TernaryNode'),
UnitNode = require('./node/UnitNode'),
UpdateNode = require('./node/UpdateNode');
@ -117,6 +117,7 @@ var DELIMITERS = {
'\'': true,
'=': true,
':': true,
'?': true,
'==': true,
'!=': true,
@ -576,7 +577,7 @@ function parseRange () {
* @private
*/
function parseBitwiseConditions () {
var node = parseComparison();
var node = parseIfElse();
/* TODO: implement bitwise conditions
var operators = {
@ -598,6 +599,35 @@ function parseBitwiseConditions () {
return node;
}
/**
* conditional operation
*
* condition ? truePart : falsePart
*
* Note: conditional operator is right-associative
*
* @return {Node} node
* @private
*/
function parseIfElse () {
var node = parseComparison();
while (token == '?') {
getToken();
var params = [node];
params.push(parseComparison());
if (token != ':') throw createSyntaxError('False part of conditional expression expected');
getToken();
params.push(parseIfElse());
node = new TernaryNode(['?', ':'], 'ifElse', params);
}
return node;
}
/**
* comparison operators
* @return {Node} node
@ -770,27 +800,16 @@ function parseUnary () {
* @private
*/
function parsePow () {
var node, leftNode, nodes, ops, name, fn, params;
var node, name, fn, params;
nodes = [
parseLeftHandOperators()
];
ops = [];
node = parseLeftHandOperators();
// stack all operands of a chained power operator (like '2^3^3')
while (token == '^' || token == '.^') {
ops.push(token);
getToken();
nodes.push(parseLeftHandOperators());
}
// evaluate the operands from right to left (right associative)
node = nodes.pop();
while (nodes.length) {
leftNode = nodes.pop();
name = ops.pop();
if (token == '^' || token == '.^') {
name = token;
fn = (name == '^') ? 'pow' : 'epow';
params = [leftNode, node];
getToken();
params = [node, parsePow()];
node = new OperatorNode(name, fn, params);
}

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
Matrix = require('../../type/Matrix'),
collection = require('../../type/collection'),
@ -46,6 +46,6 @@ module.exports = function (math) {
return Math.abs(x);
}
throw new math.error.UnsupportedTypeError('abs', x);
throw new math.error.UnsupportedTypeError('abs', math['typeof'](x));
};
};

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
Matrix = require('../../type/Matrix'),
Unit = require('../../type/Unit'),
@ -9,8 +9,6 @@ module.exports = function (math) {
isBoolean = util['boolean'].isBoolean,
isNumber = util.number.isNumber,
toNumber = util.number.toNumber,
toBigNumber = util.number.toBigNumber,
isString = util.string.isString,
isComplex = Complex.isComplex,
isUnit = Unit.isUnit,
@ -88,7 +86,7 @@ module.exports = function (math) {
if (x instanceof BigNumber) {
// try to convert to big number
if (isNumber(y)) {
y = toBigNumber(y);
y = BigNumber.convert(y);
}
else if (isBoolean(y)) {
y = new BigNumber(y ? 1 : 0);
@ -99,12 +97,12 @@ module.exports = function (math) {
}
// downgrade to Number
return add(toNumber(x), y);
return add(x.toNumber(), y);
}
if (y instanceof BigNumber) {
// try to convert to big number
if (isNumber(x)) {
x = toBigNumber(x);
x = BigNumber.convert(x);
}
else if (isBoolean(x)) {
x = new BigNumber(x ? 1 : 0);
@ -115,7 +113,7 @@ module.exports = function (math) {
}
// downgrade to Number
return add(x, toNumber(y));
return add(x, y.toNumber());
}
if (isString(x) || isString(y)) {
@ -133,6 +131,6 @@ module.exports = function (math) {
return add(x, +y);
}
throw new math.error.UnsupportedTypeError('add', x, y);
throw new math.error.UnsupportedTypeError('add', math['typeof'](x), math['typeof'](y));
};
};

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
collection = require('../../type/collection'),
@ -48,6 +48,6 @@ module.exports = function (math) {
return Math.ceil(x);
}
throw new math.error.UnsupportedTypeError('ceil', x);
throw new math.error.UnsupportedTypeError('ceil', math['typeof'](x));
};
};

View File

@ -1,21 +1,18 @@
module.exports = function (math, settings) {
module.exports = function (math, config) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
Unit = require('../../type/Unit'),
collection = require('../../type/collection'),
isNumber = util.number.isNumber,
toNumber = util.number.toNumber,
toBigNumber = util.number.toBigNumber,
nearlyEqual = util.number.nearlyEqual,
isBoolean = util['boolean'].isBoolean,
isString = util.string.isString,
isComplex = Complex.isComplex,
isUnit = Unit.isUnit,
isCollection = collection.isCollection,
epsilon = settings.epsilon;
isCollection = collection.isCollection;
/**
* Compare two values. Returns 1 when x > y, -1 when x < y, and 0 when x == y
@ -23,6 +20,10 @@ module.exports = function (math, settings) {
*
* compare(x, y)
*
* x and y are considered equal when the relative difference between x and y
* is smaller than the configured epsilon. The function cannot be used to
* compare values smaller than approximately 2.22e-16.
*
* @param {Number | BigNumber | Boolean | Unit | String | Array | Matrix} x
* @param {Number | BigNumber | Boolean | Unit | String | Array | Matrix} y
* @return {Number | BigNumber | Array | Matrix} res
@ -33,13 +34,13 @@ module.exports = function (math, settings) {
}
if (isNumber(x) && isNumber(y)) {
return nearlyEqual(x, y, epsilon) ? 0 : (x > y ? 1 : -1);
return nearlyEqual(x, y, config.epsilon) ? 0 : (x > y ? 1 : -1);
}
if (x instanceof BigNumber) {
// try to convert to big number
if (isNumber(y)) {
y = toBigNumber(y);
y = BigNumber.convert(y);
}
else if (isBoolean(y)) {
y = new BigNumber(y ? 1 : 0);
@ -50,12 +51,12 @@ module.exports = function (math, settings) {
}
// downgrade to Number
return compare(toNumber(x), y);
return compare(x.toNumber(), y);
}
if (y instanceof BigNumber) {
// try to convert to big number
if (isNumber(x)) {
x = toBigNumber(x);
x = BigNumber.convert(x);
}
else if (isBoolean(x)) {
x = new BigNumber(x ? 1 : 0);
@ -66,7 +67,7 @@ module.exports = function (math, settings) {
}
// downgrade to Number
return compare(x, toNumber(y));
return compare(x, y.toNumber());
}
if ((isUnit(x)) && (isUnit(y))) {
@ -76,14 +77,16 @@ module.exports = function (math, settings) {
return (x.value > y.value) ? 1 : ((x.value < y.value) ? -1 : 0);
}
if (isString(x) || isString(y)) {
return (x > y) ? 1 : ((x < y) ? -1 : 0);
}
if (isCollection(x) || isCollection(y)) {
return collection.deepMap2(x, y, compare);
}
// Note: test strings after testing collections,
// else we can't compare a string with a matrix
if (isString(x) || isString(y)) {
return (x > y) ? 1 : ((x < y) ? -1 : 0);
}
if (isBoolean(x)) {
return compare(+x, y);
}
@ -95,6 +98,6 @@ module.exports = function (math, settings) {
throw new TypeError('No ordering relation is defined for complex numbers');
}
throw new math.error.UnsupportedTypeError('compare', x, y);
throw new math.error.UnsupportedTypeError('compare', math['typeof'](x), math['typeof'](y));
};
};

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
collection = require('../../type/collection'),
@ -46,6 +46,6 @@ module.exports = function (math) {
return cube(+x);
}
throw new math.error.UnsupportedTypeError('cube', x);
throw new math.error.UnsupportedTypeError('cube', math['typeof'](x));
};
};

View File

@ -1,15 +1,13 @@
module.exports = function(math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
Matrix = require('../../type/Matrix'),
Unit = require('../../type/Unit'),
collection = require('../../type/collection'),
isNumber = util.number.isNumber,
toNumber = util.number.toNumber,
toBigNumber = util.number.toBigNumber,
isBoolean = util['boolean'].isBoolean,
isComplex = Complex.isComplex,
isUnit = Unit.isUnit,
@ -55,7 +53,7 @@ module.exports = function(math) {
if (x instanceof BigNumber) {
// try to convert to big number
if (isNumber(y)) {
y = toBigNumber(y);
y = BigNumber.convert(y);
}
else if (isBoolean(y)) {
y = new BigNumber(y ? 1 : 0);
@ -66,12 +64,12 @@ module.exports = function(math) {
}
// downgrade to Number
return divide(toNumber(x), y);
return divide(x.toNumber(), y);
}
if (y instanceof BigNumber) {
// try to convert to big number
if (isNumber(x)) {
x = toBigNumber(x);
x = BigNumber.convert(x);
}
else if (isBoolean(x)) {
x = new BigNumber(x ? 1 : 0);
@ -82,7 +80,7 @@ module.exports = function(math) {
}
// downgrade to Number
return divide(x, toNumber(y));
return divide(x, y.toNumber());
}
if (isUnit(x)) {
@ -119,7 +117,7 @@ module.exports = function(math) {
return divide(x, +y);
}
throw new math.error.UnsupportedTypeError('divide', x, y);
throw new math.error.UnsupportedTypeError('divide', math['typeof'](x), math['typeof'](y));
};
/**

View File

@ -1,5 +1,6 @@
module.exports = function (math) {
var collection = require('../../type/collection');
var util = require('../../util/index'),
collection = require('../../type/collection');
/**
* Multiply two values element wise.

View File

@ -1,5 +1,6 @@
module.exports = function (math) {
var collection = require('../../type/collection');
var util = require('../../util/index'),
collection = require('../../type/collection');
/**
* Calculates the power of x to y element wise

View File

@ -1,21 +1,18 @@
module.exports = function (math, settings) {
module.exports = function (math, config) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
Unit = require('../../type/Unit'),
collection = require('../../type/collection'),
isNumber = util.number.isNumber,
toNumber = util.number.toNumber,
toBigNumber = util.number.toBigNumber,
nearlyEqual = util.number.nearlyEqual,
isBoolean = util['boolean'].isBoolean,
isString = util.string.isString,
isComplex = Complex.isComplex,
isUnit = Unit.isUnit,
isCollection = collection.isCollection,
epsilon = settings.epsilon;
isCollection = collection.isCollection;
/**
* Check if value x equals y,
@ -26,6 +23,10 @@ module.exports = function (math, settings) {
* For matrices, the function is evaluated element wise.
* In case of complex numbers, x.re must equal y.re, and x.im must equal y.im.
*
* The function checks whether the relative difference between x and y is
* smaller than the configured epsilon. The function cannot be used to
* compare values smaller than approximately 2.22e-16.
*
* @param {Number | BigNumber | Boolean | Complex | Unit | String | Array | Matrix} x
* @param {Number | BigNumber | Boolean | Complex | Unit | String | Array | Matrix} y
* @return {Boolean | Array | Matrix} res
@ -37,26 +38,26 @@ module.exports = function (math, settings) {
if (isNumber(x)) {
if (isNumber(y)) {
return nearlyEqual(x, y, epsilon);
return nearlyEqual(x, y, config.epsilon);
}
else if (isComplex(y)) {
return nearlyEqual(x, y.re, epsilon) && nearlyEqual(y.im, 0, epsilon);
return nearlyEqual(x, y.re, config.epsilon) && nearlyEqual(y.im, 0, config.epsilon);
}
}
if (isComplex(x)) {
if (isNumber(y)) {
return nearlyEqual(x.re, y, epsilon) && nearlyEqual(x.im, 0, epsilon);
return nearlyEqual(x.re, y, config.epsilon) && nearlyEqual(x.im, 0, config.epsilon);
}
else if (isComplex(y)) {
return nearlyEqual(x.re, y.re, epsilon) && nearlyEqual(x.im, y.im, epsilon);
return nearlyEqual(x.re, y.re, config.epsilon) && nearlyEqual(x.im, y.im, config.epsilon);
}
}
if (x instanceof BigNumber) {
// try to convert to big number
if (isNumber(y)) {
y = toBigNumber(y);
y = BigNumber.convert(y);
}
else if (isBoolean(y)) {
y = new BigNumber(y ? 1 : 0);
@ -67,12 +68,12 @@ module.exports = function (math, settings) {
}
// downgrade to Number
return equal(toNumber(x), y);
return equal(x.toNumber(), y);
}
if (y instanceof BigNumber) {
// try to convert to big number
if (isNumber(x)) {
x = toBigNumber(x);
x = BigNumber.convert(x);
}
else if (isBoolean(x)) {
x = new BigNumber(x ? 1 : 0);
@ -83,7 +84,7 @@ module.exports = function (math, settings) {
}
// downgrade to Number
return equal(x, toNumber(y));
return equal(x, y.toNumber());
}
if ((isUnit(x)) && (isUnit(y))) {
@ -93,14 +94,16 @@ module.exports = function (math, settings) {
return x.value == y.value;
}
if (isString(x) || isString(y)) {
return x == y;
}
if (isCollection(x) || isCollection(y)) {
return collection.deepMap2(x, y, equal);
}
// Note: test strings after testing collections,
// else we can't compare a string with a matrix
if (isString(x) || isString(y)) {
return x == y;
}
if (isBoolean(x)) {
return equal(+x, y);
}
@ -108,6 +111,6 @@ module.exports = function (math, settings) {
return equal(x, +y);
}
throw new math.error.UnsupportedTypeError('equal', x, y);
throw new math.error.UnsupportedTypeError('equal', math['typeof'](x), math['typeof'](y));
};
};

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
Matrix = require('../../type/Matrix'),
collection = require('../../type/collection'),
@ -18,8 +18,8 @@ module.exports = function (math) {
*
* For matrices, the function is evaluated element wise.
*
* @param {Number | Boolean | Complex | Array | Matrix} x
* @return {Number | Complex | Array | Matrix} res
* @param {Number | BigNumber | Boolean | Complex | Array | Matrix} x
* @return {Number | BigNumber | Complex | Array | Matrix} res
*/
math.exp = function exp (x) {
if (arguments.length != 1) {
@ -39,9 +39,7 @@ module.exports = function (math) {
}
if (x instanceof BigNumber) {
// TODO: implement BigNumber support
// downgrade to Number
return exp(util.number.toNumber(x));
return x.exp();
}
if (isCollection(x)) {
@ -52,6 +50,6 @@ module.exports = function (math) {
return Math.exp(x);
}
throw new math.error.UnsupportedTypeError('exp', x);
throw new math.error.UnsupportedTypeError('exp', math['typeof'](x));
};
};

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
collection = require('../../type/collection'),
@ -48,6 +48,6 @@ module.exports = function (math) {
return fix(+x);
}
throw new math.error.UnsupportedTypeError('fix', x);
throw new math.error.UnsupportedTypeError('fix', math['typeof'](x));
};
};

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
collection = require('../../type/collection'),
@ -48,6 +48,6 @@ module.exports = function (math) {
return floor(+x);
}
throw new math.error.UnsupportedTypeError('floor', x);
throw new math.error.UnsupportedTypeError('floor', math['typeof'](x));
};
};

View File

@ -1,11 +1,10 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
collection = require('../../type/collection'),
isNumber = util.number.isNumber,
toNumber = util.number.toNumber,
isBoolean = util['boolean'].isBoolean,
isInteger = util.number.isInteger,
isCollection = collection.isCollection;
@ -51,10 +50,10 @@ module.exports = function (math) {
// downgrade bignumbers to numbers
if (a instanceof BigNumber) {
return gcd(toNumber(a), b);
return gcd(a.toNumber(), b);
}
if (b instanceof BigNumber) {
return gcd(a, toNumber(b));
return gcd(a, b.toNumber());
}
if (isBoolean(a)) {
@ -64,7 +63,7 @@ module.exports = function (math) {
return gcd(a, +b);
}
throw new math.error.UnsupportedTypeError('gcd', a, b);
throw new math.error.UnsupportedTypeError('gcd', math['typeof'](a), math['typeof'](b));
}
if (arguments.length > 2) {

View File

@ -1,21 +1,18 @@
module.exports = function (math, settings) {
module.exports = function (math, config) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
Unit = require('../../type/Unit'),
collection = require('../../type/collection'),
isNumber = util.number.isNumber,
toNumber = util.number.toNumber,
toBigNumber = util.number.toBigNumber,
nearlyEqual = util.number.nearlyEqual,
isBoolean = util['boolean'].isBoolean,
isString = util.string.isString,
isComplex = Complex.isComplex,
isUnit = Unit.isUnit,
isCollection = collection.isCollection,
epsilon = settings.epsilon;
isCollection = collection.isCollection;
/**
* Check if value x is larger y
@ -25,6 +22,10 @@ module.exports = function (math, settings) {
*
* For matrices, the function is evaluated element wise.
*
* The function returns true when x is larger than y and the relative
* difference between x and y is larger than the configured epsilon. The
* function cannot be used to compare values smaller than approximately 2.22e-16.
*
* @param {Number | BigNumber | Boolean | Unit | String | Array | Matrix} x
* @param {Number | BigNumber | Boolean | Unit | String | Array | Matrix} y
* @return {Boolean | Array | Matrix} res
@ -35,13 +36,13 @@ module.exports = function (math, settings) {
}
if (isNumber(x) && isNumber(y)) {
return !nearlyEqual(x, y, epsilon) && x > y;
return !nearlyEqual(x, y, config.epsilon) && x > y;
}
if (x instanceof BigNumber) {
// try to convert to big number
if (isNumber(y)) {
y = toBigNumber(y);
y = BigNumber.convert(y);
}
else if (isBoolean(y)) {
y = new BigNumber(y ? 1 : 0);
@ -52,12 +53,12 @@ module.exports = function (math, settings) {
}
// downgrade to Number
return larger(toNumber(x), y);
return larger(x.toNumber(), y);
}
if (y instanceof BigNumber) {
// try to convert to big number
if (isNumber(x)) {
x = toBigNumber(x);
x = BigNumber.convert(x);
}
else if (isBoolean(x)) {
x = new BigNumber(x ? 1 : 0);
@ -68,7 +69,7 @@ module.exports = function (math, settings) {
}
// downgrade to Number
return larger(x, toNumber(y));
return larger(x, y.toNumber());
}
if ((isUnit(x)) && (isUnit(y))) {
@ -78,14 +79,16 @@ module.exports = function (math, settings) {
return x.value > y.value;
}
if (isString(x) || isString(y)) {
return x > y;
}
if (isCollection(x) || isCollection(y)) {
return collection.deepMap2(x, y, larger);
}
// Note: test strings after testing collections,
// else we can't compare a string with a matrix
if (isString(x) || isString(y)) {
return x > y;
}
if (isBoolean(x)) {
return larger(+x, y);
}
@ -97,6 +100,6 @@ module.exports = function (math, settings) {
throw new TypeError('No ordering relation is defined for complex numbers');
}
throw new math.error.UnsupportedTypeError('larger', x, y);
throw new math.error.UnsupportedTypeError('larger', math['typeof'](x), math['typeof'](y));
};
};

View File

@ -1,21 +1,18 @@
module.exports = function (math, settings) {
module.exports = function (math, config) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
Unit = require('../../type/Unit'),
collection = require('../../type/collection'),
isNumber = util.number.isNumber,
toNumber = util.number.toNumber,
toBigNumber = util.number.toBigNumber,
nearlyEqual = util.number.nearlyEqual,
isBoolean = util['boolean'].isBoolean,
isString = util.string.isString,
isComplex = Complex.isComplex,
isUnit = Unit.isUnit,
isCollection = collection.isCollection,
epsilon = settings.epsilon;
isCollection = collection.isCollection;
/**
* Check if value x is larger or equal to y
@ -25,6 +22,10 @@ module.exports = function (math, settings) {
*
* For matrices, the function is evaluated element wise.
*
* The function returns true when x is larger than y or the relative
* difference between x and y is smaller than the configured epsilon. The
* function cannot be used to compare values smaller than approximately 2.22e-16.
*
* @param {Number | BigNumber | Boolean | Unit | String | Array | Matrix} x
* @param {Number | BigNumber | Boolean | Unit | String | Array | Matrix} y
* @return {Boolean | Array | Matrix} res
@ -35,13 +36,13 @@ module.exports = function (math, settings) {
}
if (isNumber(x) && isNumber(y)) {
return nearlyEqual(x, y, epsilon) || x > y;
return nearlyEqual(x, y, config.epsilon) || x > y;
}
if (x instanceof BigNumber) {
// try to convert to big number
if (isNumber(y)) {
y = toBigNumber(y);
y = BigNumber.convert(y);
}
else if (isBoolean(y)) {
y = new BigNumber(y ? 1 : 0);
@ -52,12 +53,12 @@ module.exports = function (math, settings) {
}
// downgrade to Number
return largereq(toNumber(x), y);
return largereq(x.toNumber(), y);
}
if (y instanceof BigNumber) {
// try to convert to big number
if (isNumber(x)) {
x = toBigNumber(x);
x = BigNumber.convert(x);
}
else if (isBoolean(x)) {
x = new BigNumber(x ? 1 : 0);
@ -68,7 +69,7 @@ module.exports = function (math, settings) {
}
// downgrade to Number
return largereq(x, toNumber(y));
return largereq(x, y.toNumber());
}
if ((isUnit(x)) && (isUnit(y))) {
@ -78,14 +79,16 @@ module.exports = function (math, settings) {
return x.value >= y.value;
}
if (isString(x) || isString(y)) {
return x >= y;
}
if (isCollection(x) || isCollection(y)) {
return collection.deepMap2(x, y, largereq);
}
// Note: test strings after testing collections,
// else we can't compare a string with a matrix
if (isString(x) || isString(y)) {
return x >= y;
}
if (isBoolean(x)) {
return largereq(+x, y);
}
@ -97,6 +100,6 @@ module.exports = function (math, settings) {
throw new TypeError('No ordering relation is defined for complex numbers');
}
throw new math.error.UnsupportedTypeError('largereq', x, y);
throw new math.error.UnsupportedTypeError('largereq', math['typeof'](x), math['typeof'](y));
};
};

View File

@ -1,11 +1,10 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
collection = require('../../type/collection'),
isNumber = util.number.isNumber,
toNumber = util.number.toNumber,
isBoolean = util['boolean'].isBoolean,
isInteger = util.number.isInteger,
isCollection = collection.isCollection;
@ -67,13 +66,13 @@ module.exports = function (math) {
// downgrade bignumbers to numbers
if (a instanceof BigNumber) {
return lcm(toNumber(a), b);
return lcm(a.toNumber(), b);
}
if (b instanceof BigNumber) {
return lcm(a, toNumber(b));
return lcm(a, b.toNumber());
}
throw new math.error.UnsupportedTypeError('lcm', a, b);
throw new math.error.UnsupportedTypeError('lcm', math['typeof'](a), math['typeof'](b));
}
if (arguments.length > 2) {

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
collection = require('../../type/collection'),
@ -19,9 +19,9 @@ module.exports = function (math) {
* base is optional. If not provided, the natural logarithm of x is calculated.
* For matrices, the function is evaluated element wise.
*
* @param {Number | Boolean | Complex | Array | Matrix} x
* @param {Number | Boolean | Complex} [base]
* @return {Number | Complex | Array | Matrix} res
* @param {Number | BigNumber | Boolean | Complex | Array | Matrix} x
* @param {Number | BigNumber | Boolean | Complex} [base]
* @return {Number | BigNumber | Complex | Array | Matrix} res
*/
math.log = function log(x, base) {
if (arguments.length == 1) {
@ -44,9 +44,7 @@ module.exports = function (math) {
}
if (x instanceof BigNumber) {
// TODO: implement BigNumber support
// downgrade to Number
return log(util.number.toNumber(x));
return x.ln();
}
if (isCollection(x)) {
@ -57,7 +55,7 @@ module.exports = function (math) {
return log(+x);
}
throw new math.error.UnsupportedTypeError('log', x);
throw new math.error.UnsupportedTypeError('log', math['typeof'](x));
}
else if (arguments.length == 2) {
// calculate logarithm for a specified base, log(x, base)

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
collection = require('../../type/collection'),
@ -17,8 +17,8 @@ module.exports = function (math) {
*
* For matrices, the function is evaluated element wise.
*
* @param {Number | Boolean | Complex | Array | Matrix} x
* @return {Number | Complex | Array | Matrix} res
* @param {Number | BigNumber | Boolean | Complex | Array | Matrix} x
* @return {Number | BigNumber | Complex | Array | Matrix} res
*/
math.log10 = function log10(x) {
if (arguments.length != 1) {
@ -36,9 +36,7 @@ module.exports = function (math) {
}
if (x instanceof BigNumber) {
// TODO: implement BigNumber support
// downgrade to Number
return log10(util.number.toNumber(x));
return x.log();
}
if (isComplex(x)) {
@ -56,6 +54,6 @@ module.exports = function (math) {
return log10(+x);
}
throw new math.error.UnsupportedTypeError('log10', x);
throw new math.error.UnsupportedTypeError('log10', math['typeof'](x));
};
};

View File

@ -1,12 +1,10 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
collection = require('../../type/collection'),
isNumber = util.number.isNumber,
toNumber = util.number.toNumber,
toBigNumber = util.number.toBigNumber,
isBoolean = util['boolean'].isBoolean,
isCollection = collection.isCollection;
@ -39,34 +37,34 @@ module.exports = function (math) {
if (x instanceof BigNumber) {
// try to convert to big number
if (isNumber(y)) {
y = toBigNumber(y);
y = BigNumber.convert(y);
}
else if (isBoolean(y)) {
y = new BigNumber(y ? 1 : 0);
}
if (y instanceof BigNumber) {
return x.mod(y);
return y.isZero() ? x : x.mod(y);
}
// downgrade to Number
return mod(toNumber(x), y);
// downgrade x to Number
return mod(x.toNumber(), y);
}
if (y instanceof BigNumber) {
// try to convert to big number
if (isNumber(x)) {
x = toBigNumber(x);
x = BigNumber.convert(x);
}
else if (isBoolean(x)) {
x = new BigNumber(x ? 1 : 0);
}
if (x instanceof BigNumber) {
return x.mod(y)
return y.isZero() ? x : x.mod(y);
}
// downgrade to Number
return mod(x, toNumber(y));
// downgrade y to Number
return mod(x, y.toNumber());
}
// TODO: implement mod for complex values
@ -82,7 +80,7 @@ module.exports = function (math) {
return mod(x, +y);
}
throw new math.error.UnsupportedTypeError('mod', x, y);
throw new math.error.UnsupportedTypeError('mod', math['typeof'](x), math['typeof'](y));
};
/**

View File

@ -1,7 +1,7 @@
module.exports = function(math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
Matrix = require('../../type/Matrix'),
Unit = require('../../type/Unit'),
@ -9,8 +9,6 @@ module.exports = function(math) {
array = util.array,
isNumber = util.number.isNumber,
toNumber = util.number.toNumber,
toBigNumber = util.number.toBigNumber,
isBoolean = util['boolean'].isBoolean,
isComplex = Complex.isComplex,
isArray = Array.isArray,
@ -27,6 +25,8 @@ module.exports = function(math) {
* @return {Number | BigNumber | Complex | Unit | Array | Matrix} res
*/
math.multiply = function multiply(x, y) {
var res;
if (arguments.length != 2) {
throw new math.error.ArgumentsError('multiply', arguments.length, 2);
}
@ -61,7 +61,7 @@ module.exports = function(math) {
if (x instanceof BigNumber) {
// try to convert to big number
if (isNumber(y)) {
y = toBigNumber(y);
y = BigNumber.convert(y);
}
else if (isBoolean(y)) {
y = new BigNumber(y ? 1 : 0);
@ -72,12 +72,12 @@ module.exports = function(math) {
}
// downgrade to Number
return multiply(toNumber(x), y);
return multiply(x.toNumber(), y);
}
if (y instanceof BigNumber) {
// try to convert to big number
if (isNumber(x)) {
x = toBigNumber(x);
x = BigNumber.convert(x);
}
else if (isBoolean(x)) {
x = new BigNumber(x ? 1 : 0);
@ -88,7 +88,7 @@ module.exports = function(math) {
}
// downgrade to Number
return multiply(x, toNumber(y));
return multiply(x, y.toNumber());
}
if (isUnit(x)) {
@ -109,7 +109,7 @@ module.exports = function(math) {
if (sizeY.length == 1) {
// vector * vector
if (sizeX[0] != sizeY[0]) {
throw new RangeError('Dimensions mismatch in multiplication. ' +
throw new RangeError('Dimension mismatch in multiplication. ' +
'Length of A must match length of B ' +
'(A is ' + sizeX[0] +
', B is ' + sizeY[0] +
@ -121,7 +121,7 @@ module.exports = function(math) {
else if (sizeY.length == 2) {
// vector * matrix
if (sizeX[0] != sizeY[0]) {
throw new RangeError('Dimensions mismatch in multiplication. ' +
throw new RangeError('Dimension mismatch in multiplication. ' +
'Length of A must match rows of B ' +
'(A is ' + sizeX[0] +
', B is ' + sizeY[0] + 'x' + sizeY[1] + ', ' +
@ -139,7 +139,7 @@ module.exports = function(math) {
if (sizeY.length == 1) {
// matrix * vector
if (sizeX[1] != sizeY[0]) {
throw new RangeError('Dimensions mismatch in multiplication. ' +
throw new RangeError('Dimension mismatch in multiplication. ' +
'Columns of A must match length of B ' +
'(A is ' + sizeX[0] + 'x' + sizeX[0] +
', B is ' + sizeY[0] + ', ' +
@ -151,7 +151,7 @@ module.exports = function(math) {
else if (sizeY.length == 2) {
// matrix * matrix
if (sizeX[1] != sizeY[0]) {
throw new RangeError('Dimensions mismatch in multiplication. ' +
throw new RangeError('Dimension mismatch in multiplication. ' +
'Columns of A must match rows of B ' +
'(A is ' + sizeX[0] + 'x' + sizeX[1] +
', B is ' + sizeY[0] + 'x' + sizeY[1] + ', ' +
@ -208,7 +208,7 @@ module.exports = function(math) {
return multiply(x, +y);
}
throw new math.error.UnsupportedTypeError('multiply', x, y);
throw new math.error.UnsupportedTypeError('multiply', math['typeof'](x), math['typeof'](y));
};
/**

View File

@ -0,0 +1,153 @@
module.exports = function (math) {
var util = require('../../util/index'),
array = require('../../../lib/util/array'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
Matrix = require('../../type/Matrix'),
collection = require('../../type/collection'),
isNumber = util.number.isNumber,
isBoolean = util['boolean'].isBoolean,
isComplex = Complex.isComplex,
isCollection = collection.isCollection;
/**
* Calculate the norm of a number, vector or matrix.
*
* norm(x)
* norm(x, p)
*
* p is optional. If not provided, defaults to 2 (The Frobenius norm or 'fro')).
*
* @param {Number | BigNumber | Complex | Boolean | Array | Matrix} x
* @param {Number | Infinity | -Infinity, 'inf', '-inf', 'fro'} [p]
* @return {Number} the p-norm
*/
math.norm = function norm(x, p) {
if (arguments.length < 1 || arguments.length > 2) {
throw new math.error.ArgumentsError('abs', arguments.length, 1, 2);
}
if (isNumber(x)) {
// norm(x) = abs(x)
return Math.abs(x);
}
if (isComplex(x)) {
// ignore p, complex numbers
return Math.sqrt(x.re * x.re + x.im * x.im);
}
if (x instanceof BigNumber) {
// norm(x) = abs(x)
return x.abs();
}
if (isBoolean(x)) {
// norm(x) = abs(x)
return Math.abs(x);
}
if (isArray(x)) {
// size
var sizeX = array.size(x);
// p
p = p || 2;
// check it is a Vector
if (sizeX.length == 1) {
// check p
if (p === Number.POSITIVE_INFINITY || p === 'inf') {
// norm(x, Infinity) = max(abs(x))
var n;
math.forEach(x, function (value) {
var v = math.abs(value);
if (!n || math.larger(v, n))
n = v;
});
return n;
}
if (p === Number.NEGATIVE_INFINITY || p === '-inf') {
// norm(x, -Infinity) = min(abs(x))
var n;
math.forEach(x, function (value) {
var v = math.abs(value);
if (!n || math.smaller(v, n))
n = v;
});
return n;
}
if (p === 'fro')
return norm(x);
if (isNumber(p) && !isNaN(p)) {
// check p != 0
if (!math.equal(p, 0)) {
// norm(x, p) = sum(abs(xi) ^ p) ^ 1/p
var n = 0;
math.forEach(x, function (value) {
n = math.add(math.pow(math.abs(value), p), n);
});
return math.pow(n, 1 / p);
}
return Number.POSITIVE_INFINITY;
}
// invalid parameter value
throw new Error('Unsupported parameter value');
}
else if (sizeX.length == 2) {
// check p
if (p == 1) {
// norm(x) = the largest column sum
var c = [];
// loop rows
for (var i = 0; i < x.length; i++) {
var r = x[i];
// loop columns
for (var j = 0; j < r.length; j++) {
c[j] = math.add(c[j] || 0, math.abs(r[j]));
}
}
return math.max(c);
}
if (p == Number.POSITIVE_INFINITY || p === 'inf') {
// norm(x) = the largest row sum
var n = 0;
// loop rows
for (var i = 0; i < x.length; i++) {
var rs = 0;
var r = x[i];
// loop columns
for (var j = 0; j < r.length; j++) {
rs = math.add(rs, math.abs(r[j]));
}
if (math.larger(rs, n))
n = rs;
}
return n;
}
if (p === 'fro') {
// norm(x) = sqrt(sum(diag(x'x)))
var d = math.diag(math.multiply(math.transpose(x), x));
var s = 0;
math.forEach(d, function (value) {
s = math.add(value, s);
});
return math.sqrt(s);
}
if (p == 2) {
// not implemented
throw new Error('Unsupported parameter value, missing implementation of matrix singular value decomposition');
}
// invalid parameter value
throw new Error('Unsupported parameter value');
}
}
if (x instanceof Matrix) {
return norm(x.valueOf(), p);
}
throw new math.error.UnsupportedTypeError('norm', x);
};
};

View File

@ -1,15 +1,13 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
Matrix = require('../../type/Matrix'),
collection = require('../../type/collection'),
array = util.array,
isNumber = util.number.isNumber,
toNumber = util.number.toNumber,
toBigNumber = util.number.toBigNumber,
isBoolean = util['boolean'].isBoolean,
isArray = Array.isArray,
isInteger = util.number.isInteger,
@ -54,12 +52,10 @@ module.exports = function (math) {
}
}
// TODO: pow for complex numbers and bignumbers
if (x instanceof BigNumber) {
// try to convert to big number
if (isNumber(y)) {
y = toBigNumber(y);
y = BigNumber.convert(y);
}
else if (isBoolean(y)) {
y = new BigNumber(y ? 1 : 0);
@ -70,12 +66,12 @@ module.exports = function (math) {
}
// downgrade to Number
return pow(toNumber(x), y);
return pow(x.toNumber(), y);
}
if (y instanceof BigNumber) {
// try to convert to big number
if (isNumber(x)) {
x = toBigNumber(x);
x = BigNumber.convert(x);
}
else if (isBoolean(x)) {
x = new BigNumber(x ? 1 : 0);
@ -86,7 +82,7 @@ module.exports = function (math) {
}
// downgrade to Number
return pow(x, toNumber(y));
return pow(x, y.toNumber());
}
@ -129,7 +125,7 @@ module.exports = function (math) {
return pow(x, +y);
}
throw new math.error.UnsupportedTypeError('pow', x, y);
throw new math.error.UnsupportedTypeError('pow', math['typeof'](x), math['typeof'](y));
};
/**

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
collection = require('../../type/collection'),
@ -43,7 +43,7 @@ module.exports = function (math) {
}
if (x instanceof BigNumber) {
return x.round();
return x.toDecimalPlaces(0);
}
if (isCollection(x)) {
@ -54,7 +54,7 @@ module.exports = function (math) {
return Math.round(x);
}
throw new math.error.UnsupportedTypeError('round', x);
throw new math.error.UnsupportedTypeError('round', math['typeof'](x));
}
else {
// round (x, n)
@ -85,7 +85,7 @@ module.exports = function (math) {
}
if (x instanceof BigNumber) {
return x.round(n);
return x.toDecimalPlaces(n);
}
if (isCollection(x) || isCollection(n)) {
@ -96,7 +96,7 @@ module.exports = function (math) {
return round(+x, n);
}
throw new math.error.UnsupportedTypeError('round', x, n);
throw new math.error.UnsupportedTypeError('round', math['typeof'](x), math['typeof'](n));
}
};

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
collection = require('../../type/collection'),
@ -48,6 +48,6 @@ module.exports = function (math) {
return number.sign(x);
}
throw new math.error.UnsupportedTypeError('sign', x);
throw new math.error.UnsupportedTypeError('sign', math['typeof'](x));
};
};

View File

@ -1,21 +1,18 @@
module.exports = function (math, settings) {
module.exports = function (math, config) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
Unit = require('../../type/Unit'),
collection = require('../../type/collection'),
isNumber = util.number.isNumber,
toNumber = util.number.toNumber,
toBigNumber = util.number.toBigNumber,
nearlyEqual = util.number.nearlyEqual,
isBoolean = util['boolean'].isBoolean,
isString = util.string.isString,
isComplex = Complex.isComplex,
isUnit = Unit.isUnit,
isCollection = collection.isCollection,
epsilon = settings.epsilon;
isCollection = collection.isCollection;
/**
* Check if value x is smaller y
@ -25,6 +22,10 @@ module.exports = function (math, settings) {
*
* For matrices, the function is evaluated element wise.
*
* The function returns true when x is smaller than y and the relative
* difference between x and y is larger than the configured epsilon. The
* function cannot be used to compare values smaller than approximately 2.22e-16.
*
* @param {Number | BigNumber | Boolean | Unit | String | Array | Matrix} x
* @param {Number | BigNumber | Boolean | Unit | String | Array | Matrix} y
* @return {Boolean | Array | Matrix} res
@ -35,13 +36,13 @@ module.exports = function (math, settings) {
}
if (isNumber(x) && isNumber(y)) {
return !nearlyEqual(x, y, epsilon) && x < y;
return !nearlyEqual(x, y, config.epsilon) && x < y;
}
if (x instanceof BigNumber) {
// try to convert to big number
if (isNumber(y)) {
y = toBigNumber(y);
y = BigNumber.convert(y);
}
else if (isBoolean(y)) {
y = new BigNumber(y ? 1 : 0);
@ -52,12 +53,12 @@ module.exports = function (math, settings) {
}
// downgrade to Number
return smaller(toNumber(x), y);
return smaller(x.toNumber(), y);
}
if (y instanceof BigNumber) {
// try to convert to big number
if (isNumber(x)) {
x = toBigNumber(x);
x = BigNumber.convert(x);
}
else if (isBoolean(x)) {
x = new BigNumber(x ? 1 : 0);
@ -68,7 +69,7 @@ module.exports = function (math, settings) {
}
// downgrade to Number
return smaller(x, toNumber(y));
return smaller(x, y.toNumber());
}
if ((isUnit(x)) && (isUnit(y))) {
@ -78,14 +79,16 @@ module.exports = function (math, settings) {
return x.value < y.value;
}
if (isString(x) || isString(y)) {
return x < y;
}
if (isCollection(x) || isCollection(y)) {
return collection.deepMap2(x, y, smaller);
}
// Note: test strings after testing collections,
// else we can't compare a string with a matrix
if (isString(x) || isString(y)) {
return x < y;
}
if (isBoolean(x)) {
return smaller(+x, y);
}
@ -97,6 +100,6 @@ module.exports = function (math, settings) {
throw new TypeError('No ordering relation is defined for complex numbers');
}
throw new math.error.UnsupportedTypeError('smaller', x, y);
throw new math.error.UnsupportedTypeError('smaller', math['typeof'](x), math['typeof'](y));
};
};

View File

@ -1,30 +1,31 @@
module.exports = function (math, settings) {
module.exports = function (math, config) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
Unit = require('../../type/Unit'),
collection = require('../../type/collection'),
isNumber = util.number.isNumber,
toNumber = util.number.toNumber,
toBigNumber = util.number.toBigNumber,
nearlyEqual = util.number.nearlyEqual,
isBoolean = util['boolean'].isBoolean,
isString = util.string.isString,
isComplex = Complex.isComplex,
isUnit = Unit.isUnit,
isCollection = collection.isCollection,
epsilon = settings.epsilon;
isCollection = collection.isCollection;
/**
* Check if value a is smaller or equal to b
* Check if value x is smaller or equal to y
*
* a <= b
* smallereq(a, b)
* x <= y
* smallereq(x, y)
*
* For matrices, the function is evaluated element wise.
*
* The function returns true when x is smaller than y or the relative
* difference between x and y is smaller than the configured epsilon. The
* function cannot be used to compare values smaller than approximately 2.22e-16.
*
* @param {Number | BigNumber | Boolean | Complex | Unit | String | Array | Matrix} x
* @param {Number | BigNumber | Boolean | Complex | Unit | String | Array | Matrix} y
* @return {Boolean | Array | Matrix} res
@ -35,13 +36,13 @@ module.exports = function (math, settings) {
}
if (isNumber(x) && isNumber(y)) {
return nearlyEqual(x, y, epsilon) || x < y;
return nearlyEqual(x, y, config.epsilon) || x < y;
}
if (x instanceof BigNumber) {
// try to convert to big number
if (isNumber(y)) {
y = toBigNumber(y);
y = BigNumber.convert(y);
}
else if (isBoolean(y)) {
y = new BigNumber(y ? 1 : 0);
@ -52,12 +53,12 @@ module.exports = function (math, settings) {
}
// downgrade to Number
return smallereq(toNumber(x), y);
return smallereq(x.toNumber(), y);
}
if (y instanceof BigNumber) {
// try to convert to big number
if (isNumber(x)) {
x = toBigNumber(x);
x = BigNumber.convert(x);
}
else if (isBoolean(x)) {
x = new BigNumber(x ? 1 : 0);
@ -68,7 +69,7 @@ module.exports = function (math, settings) {
}
// downgrade to Number
return smallereq(x, toNumber(y));
return smallereq(x, y.toNumber());
}
if ((isUnit(x)) && (isUnit(y))) {
@ -78,14 +79,16 @@ module.exports = function (math, settings) {
return x.value <= y.value;
}
if (isString(x) || isString(y)) {
return x <= y;
}
if (isCollection(x) || isCollection(y)) {
return collection.deepMap2(x, y, smallereq);
}
// Note: test strings after testing collections,
// else we can't compare a string with a matrix
if (isString(x) || isString(y)) {
return x <= y;
}
if (isBoolean(x)) {
return smallereq(+x, y);
}
@ -97,6 +100,6 @@ module.exports = function (math, settings) {
throw new TypeError('No ordering relation is defined for complex numbers');
}
throw new math.error.UnsupportedTypeError('smallereq', x, y);
throw new math.error.UnsupportedTypeError('smallereq', math['typeof'](x), math['typeof'](y));
};
};

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
collection = require('../../type/collection'),
@ -62,6 +62,6 @@ module.exports = function (math) {
return sqrt(+x);
}
throw new math.error.UnsupportedTypeError('sqrt', x);
throw new math.error.UnsupportedTypeError('sqrt', math['typeof'](x));
};
};

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
collection = require('../../type/collection'),
@ -46,6 +46,6 @@ module.exports = function (math) {
return x * x;
}
throw new math.error.UnsupportedTypeError('square', x);
throw new math.error.UnsupportedTypeError('square', math['typeof'](x));
};
};

View File

@ -1,14 +1,12 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
Matrix = require('../../type/Matrix'),
Unit = require('../../type/Unit'),
collection = require('../../type/collection'),
toNumber = util.number.toNumber,
toBigNumber = util.number.toBigNumber,
isBoolean = util['boolean'].isBoolean,
isNumber = util.number.isNumber,
isComplex = Complex.isComplex,
@ -65,7 +63,7 @@ module.exports = function (math) {
if (x instanceof BigNumber) {
// try to convert to big number
if (isNumber(y)) {
y = toBigNumber(y);
y = BigNumber.convert(y);
}
else if (isBoolean(y)) {
y = new BigNumber(y ? 1 : 0);
@ -76,12 +74,12 @@ module.exports = function (math) {
}
// downgrade to Number
return subtract(toNumber(x), y);
return subtract(x.toNumber(), y);
}
if (y instanceof BigNumber) {
// try to convert to big number
if (isNumber(x)) {
x = toBigNumber(x);
x = BigNumber.convert(x);
}
else if (isBoolean(x)) {
x = new BigNumber(x ? 1 : 0);
@ -92,7 +90,7 @@ module.exports = function (math) {
}
// downgrade to Number
return subtract(x, toNumber(y));
return subtract(x, y.toNumber());
}
if (isUnit(x)) {
@ -128,6 +126,6 @@ module.exports = function (math) {
return subtract(x, +y);
}
throw new math.error.UnsupportedTypeError('subtract', x, y);
throw new math.error.UnsupportedTypeError('subtract', math['typeof'](x), math['typeof'](y));
};
};

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
Unit = require('../../type/Unit'),
collection = require('../../type/collection'),
@ -57,6 +57,6 @@ module.exports = function (math) {
return -x;
}
throw new math.error.UnsupportedTypeError('unary', x);
throw new math.error.UnsupportedTypeError('unary', math['typeof'](x));
};
};

View File

@ -1,25 +1,27 @@
module.exports = function (math, settings) {
module.exports = function (math, config) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
Unit = require('../../type/Unit'),
collection = require('../../type/collection'),
isNumber = util.number.isNumber,
toNumber = util.number.toNumber,
toBigNumber = util.number.toBigNumber,
nearlyEqual = util.number.nearlyEqual,
isBoolean = util['boolean'].isBoolean,
isString = util.string.isString,
isComplex = Complex.isComplex,
isUnit = Unit.isUnit,
isCollection = collection.isCollection,
epsilon = settings.epsilon;
isCollection = collection.isCollection;
/**
* Check if value x unequals y, x != y
* In case of complex numbers, x.re must unequal y.re, or x.im must unequal y.im
*
* The function checks whether the relative difference between x and y is
* larger than the configured epsilon. The function cannot be used to compare
* values smaller than approximately 2.22e-16.
*
* @param {Number | BigNumber | Boolean | Complex | Unit | String | Array | Matrix} x
* @param {Number | BigNumber | Boolean | Complex | Unit | String | Array | Matrix} y
* @return {Boolean | Array | Matrix} res
@ -31,26 +33,26 @@ module.exports = function (math, settings) {
if (isNumber(x)) {
if (isNumber(y)) {
return !nearlyEqual(x, y, epsilon);
return !nearlyEqual(x, y, config.epsilon);
}
else if (isComplex(y)) {
return !nearlyEqual(x, y.re, epsilon) || !nearlyEqual(y.im, 0, epsilon);
return !nearlyEqual(x, y.re, config.epsilon) || !nearlyEqual(y.im, 0, config.epsilon);
}
}
if (isComplex(x)) {
if (isNumber(y)) {
return !nearlyEqual(x.re, y, epsilon) || !nearlyEqual(x.im, 0, epsilon);
return !nearlyEqual(x.re, y, config.epsilon) || !nearlyEqual(x.im, 0, config.epsilon);
}
else if (isComplex(y)) {
return !nearlyEqual(x.re, y.re, epsilon) || !nearlyEqual(x.im, y.im, epsilon);
return !nearlyEqual(x.re, y.re, config.epsilon) || !nearlyEqual(x.im, y.im, config.epsilon);
}
}
if (x instanceof BigNumber) {
// try to convert to big number
if (isNumber(y)) {
y = toBigNumber(y);
y = BigNumber.convert(y);
}
else if (isBoolean(y)) {
y = new BigNumber(y ? 1 : 0);
@ -61,12 +63,12 @@ module.exports = function (math, settings) {
}
// downgrade to Number
return unequal(toNumber(x), y);
return unequal(x.toNumber(), y);
}
if (y instanceof BigNumber) {
// try to convert to big number
if (isNumber(x)) {
x = toBigNumber(x);
x = BigNumber.convert(x);
}
else if (isBoolean(x)) {
x = new BigNumber(x ? 1 : 0);
@ -77,7 +79,7 @@ module.exports = function (math, settings) {
}
// downgrade to Number
return unequal(x, toNumber(y));
return unequal(x, y.toNumber());
}
if ((isUnit(x)) && (isUnit(y))) {
@ -87,14 +89,16 @@ module.exports = function (math, settings) {
return x.value != y.value;
}
if (isString(x) || isString(y)) {
return x != y;
}
if (isCollection(x) || isCollection(y)) {
return collection.deepMap2(x, y, unequal);
}
// Note: test strings after testing collections,
// else we can't compare a string with a matrix
if (isString(x) || isString(y)) {
return x != y;
}
if (isBoolean(x)) {
return unequal(+x, y);
}
@ -102,6 +106,6 @@ module.exports = function (math, settings) {
return unequal(x, +y);
}
throw new math.error.UnsupportedTypeError('unequal', x, y);
throw new math.error.UnsupportedTypeError('unequal', math['typeof'](x), math['typeof'](y));
};
};

View File

@ -1,9 +1,8 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
toNumber = util.number.toNumber,
isNumber = util.number.isNumber,
isBoolean = util['boolean'].isBoolean,
isInteger = util.number.isInteger;
@ -35,10 +34,10 @@ module.exports = function (math) {
// downgrade bignumbers to numbers
if (a instanceof BigNumber) {
return xgcd(toNumber(a), b);
return xgcd(a.toNumber(), b);
}
if (b instanceof BigNumber) {
return xgcd(a, toNumber(b));
return xgcd(a, b.toNumber());
}
if (isBoolean(a)) {
@ -48,7 +47,7 @@ module.exports = function (math) {
return xgcd(a, +b);
}
throw new math.error.UnsupportedTypeError('xgcd', a, b);
throw new math.error.UnsupportedTypeError('xgcd', math['typeof'](a), math['typeof'](b));
}
// zero or one argument

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
collection = require('../../type/collection'),
@ -45,9 +45,9 @@ module.exports = function (math) {
if (x instanceof BigNumber) {
// downgrade to Number
// TODO: implement BigNumber support
return arg(util.number.toNumber(x));
return arg(x.toNumber());
}
throw new math.error.UnsupportedTypeError('arg', x);
throw new math.error.UnsupportedTypeError('arg', math['typeof'](x));
};
};

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
collection = require('../../type/collection'),

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
collection = require('../../type/collection'),

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
collection = require('../../type/collection'),

View File

@ -1,7 +1,8 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
// take the BigNumber instance the provided math.js instance
BigNumber = math.type.BigNumber,
collection = require('../../type/collection'),
isCollection = collection.isCollection,
@ -9,17 +10,6 @@ module.exports = function (math) {
isString = util.string.isString,
isBoolean = util['boolean'].isBoolean;
// extend BigNumber with a function clone
if (typeof BigNumber.prototype.clone !== 'function') {
/**
* Clone a bignumber
* @return {BigNumber} clone
*/
BigNumber.prototype.clone = function clone () {
return new BigNumber(this);
};
}
/**
* Create a big number, which can store numbers with higher precision than
* a JavaScript Number.
@ -49,6 +39,6 @@ module.exports = function (math) {
return new BigNumber(0);
}
throw new math.error.UnsupportedTypeError('bignumber', value);
throw new math.error.UnsupportedTypeError('bignumber', math['typeof'](value));
};
};

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
collection = require('../../type/collection'),
isCollection = collection.isCollection,

View File

@ -1,13 +1,12 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
collection = require('../../type/collection'),
isCollection = collection.isCollection,
isNumber = util.number.isNumber,
toNumber = util.number.toNumber,
isString = util.string.isString,
isComplex = Complex.isComplex;
@ -26,6 +25,10 @@ module.exports = function (math) {
* complex(array : Array) converts the elements of the array
* or matrix element wise into a
* complex value.
* complex({re: number, im: number}) creates a complex value with provided
* values for real an imaginary part.
* complex({r: number, phi: number}) creates a complex value with provided
* polar coordinates
*
* Example usage:
* var a = math.complex(3, -4); // 3 - 4i
@ -54,7 +57,7 @@ module.exports = function (math) {
if (arg instanceof BigNumber) {
// convert to Number
return new Complex(toNumber(arg), 0);
return new Complex(arg.toNumber(), 0);
}
if (isComplex(arg)) {
@ -76,7 +79,15 @@ module.exports = function (math) {
return collection.deepMap(arg, complex);
}
throw new TypeError('Two numbers or a single string expected in function complex');
if (typeof arg === 'object') {
if('re' in arg && 'im' in arg) {
return new Complex(arg.re, arg.im);
} else if ('r' in arg && 'phi' in arg) {
return Complex.fromPolar(arg.r, arg.phi);
}
}
throw new TypeError('Two numbers, single string or an fitting object expected in function complex');
case 2:
// re and im provided
@ -85,12 +96,12 @@ module.exports = function (math) {
// convert re to number
if (re instanceof BigNumber) {
re = toNumber(re);
re = re.toNumber();
}
// convert im to number
if (im instanceof BigNumber) {
im = toNumber(im);
im = im.toNumber();
}
if (isNumber(re) && isNumber(im)) {

View File

@ -1,10 +1,8 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
Index = require('../../type/Index'),
toNumber = util.number.toNumber;
BigNumber = math.type.BigNumber,
Index = require('../../type/Index');
/**
* Create an index. An Index can store ranges having start, step, and end
@ -30,11 +28,11 @@ module.exports = function (math) {
// downgrade BigNumber to Number
var args = Array.prototype.slice.apply(arguments).map(function (arg) {
if (arg instanceof BigNumber) {
return toNumber(arg);
return arg.toNumber();
}
else if (Array.isArray(arg)) {
return arg.map(function (elem) {
return (elem instanceof BigNumber) ? toNumber (elem) : elem;
return (elem instanceof BigNumber) ? elem.toNumber() : elem;
});
}
else {

View File

@ -1,5 +1,6 @@
module.exports = function (math) {
var Matrix = require('../../type/Matrix');
var util = require('../../util/index'),
Matrix = require('../../type/Matrix');
/**
* Create a matrix. The function creates a new math.type.Matrix object.

View File

@ -1,11 +1,10 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
collection = require('../../type/collection'),
isCollection = collection.isCollection,
toNumber = util.number.toNumber,
isNumber = util.number.isNumber,
isBoolean = util['boolean'].isBoolean,
isString = util.string.isString;
@ -27,7 +26,7 @@ module.exports = function (math) {
}
if (value instanceof BigNumber) {
return toNumber(value);
return value.toNumber();
}
if (isString(value)) {
@ -49,7 +48,7 @@ module.exports = function (math) {
return value;
}
throw new math.error.UnsupportedTypeError('number', value);
throw new math.error.UnsupportedTypeError('number', math['typeof'](value));
default:
throw new math.error.ArgumentsError('number', arguments.length, 0, 1);

View File

@ -1,12 +1,11 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Unit = require('../../type/Unit'),
collection = require('../../type/collection'),
isCollection = collection.isCollection,
toNumber = util.number.toNumber,
isString = util.string.isString;
/**
@ -38,7 +37,7 @@ module.exports = function (math) {
}
if (isString(arg)) {
if (Unit.isPlainUnit(arg)) {
if (Unit.isValuelessUnit(arg)) {
return new Unit(null, arg); // a pure unit
}
@ -61,7 +60,7 @@ module.exports = function (math) {
if (arguments[0] instanceof BigNumber) {
// convert value to number
return new Unit(toNumber(arguments[0]), arguments[1]);
return new Unit(arguments[0].toNumber(), arguments[1]);
}
else {
return new Unit(arguments[0], arguments[1]);

View File

@ -1,4 +1,4 @@
module.exports = function (math, settings) {
module.exports = function (math, config) {
var util = require('../../util/index'),
_parse = require('../../expression/parse'),

View File

@ -1,4 +1,4 @@
module.exports = function (math, settings) {
module.exports = function (math, config) {
var _parse = require('../../expression/parse');
/**

View File

@ -49,8 +49,7 @@ module.exports = function (math) {
}
if (i > 0 && dim > prevDim) {
throw new RangeError('Dimension out of range ' +
'(' + dim + ' > ' + prevDim + ')');
throw new math.error.DimensionError(dim, prevDim, '>');
}
}
else if (isCollection(arg)) {
@ -63,12 +62,11 @@ module.exports = function (math) {
// verify whether each of the matrices has the same number of dimensions
if (i > 0 && dim != prevDim) {
throw new RangeError('Dimension mismatch ' +
'(' + prevDim + ' != ' + dim + ')');
throw new math.error.DimensionError(dim, prevDim);
}
}
else {
throw new math.error.UnsupportedTypeError('concat', arg);
throw new math.error.UnsupportedTypeError('concat', math['typeof'](arg));
}
}
@ -98,7 +96,7 @@ module.exports = function (math) {
if (dim < concatDim) {
// recurse into next dimension
if (a.length != b.length) {
throw new Error('Dimensions mismatch (' + a.length + ' != ' + b.length + ')');
throw new math.error.DimensionError(a.length, b.length);
}
var c = [];

View File

@ -90,64 +90,47 @@ module.exports = function (math) {
}
else {
// this is an n x n matrix
// TODO: support for bignumbers, complex numbers, etc
var a;
var d = 1;
var lead = 0;
for (var r = 0; r < rows; r++) {
if (lead >= cols) {
break;
function compute_mu(matrix) {
var i, j;
// Compute the matrix with zero lower triangle, same upper triangle,
// and diagonals given by the negated sum of the below diagonal
// elements.
var mu = new Array(matrix.length);
var sum = 0;
for (i = 1; i < matrix.length; i++) {
sum = math.add(sum, matrix[i][i]);
}
var i = r;
// Find the pivot element.
while (matrix[i][lead] == 0) {
i++;
if (i == rows) {
i = r;
lead++;
if (lead == cols) {
// We found the last pivot.
if (object.deepEqual(matrix, math.eye(rows).valueOf())) {
return math.round(d, 6); // FIXME: should d be rounded to 6 here?
} else {
return 0;
}
}
for (i = 0; i < matrix.length; i++) {
mu[i] = new Array(matrix.length);
mu[i][i] = math.unary(sum);
for (j = 0; j < i; j++) {
mu[i][j] = 0;
}
for (j = i + 1; j < matrix.length; j++) {
mu[i][j] = matrix[i][j];
}
if (i+1 < matrix.length) {
sum = math.subtract(sum, matrix[i + 1][i + 1]);
}
}
if (i != r) {
// Swap rows i and r, which negates the determinant.
for (a = 0; a < cols; a++) {
var temp = matrix[i][a];
matrix[i][a] = matrix[r][a];
matrix[r][a] = temp;
}
d *= -1;
}
// Scale row r and the determinant simultaneously.
var div = matrix[r][lead];
for (a = 0; a < cols; a++) {
matrix[r][a] = matrix[r][a] / div;
}
d *= div;
// Back-substitute upwards.
for (var j = 0; j < rows; j++) {
if (j != r) {
// Taking linear combinations does not change the det.
var c = matrix[j][lead];
for (a = 0; a < cols; a++) {
matrix[j][a] = matrix[j][a] - matrix[r][a] * c;
}
}
}
lead++; // Now looking for a pivot further right.
return mu;
}
// If reduction did not result in the identity, the matrix is singular.
if (object.deepEqual(matrix, math.eye(rows).valueOf())) {
return math.round(d, 6); // FIXME: should d be rounded to 6 here?
var fa = matrix;
for (var i = 0; i < rows - 1; i++) {
fa = math.multiply(compute_mu(fa), matrix);
}
if (rows % 2 == 0) {
return math.unary(fa[0][0]);
} else {
return 0;
return fa[0][0];
}
}
}

View File

@ -1,6 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = math.type.BigNumber,
Matrix = require('../../type/Matrix'),
object = util.object,
@ -19,7 +20,7 @@ module.exports = function (math) {
* TODO: more documentation on diag
*
* @param {Matrix | Array} x
* @param {Number} [k]
* @param {Number | BigNumber} [k]
* @return {Matrix | Array} matrix
*/
math.diag = function diag (x, k) {
@ -30,6 +31,9 @@ module.exports = function (math) {
}
if (k) {
// convert BigNumber to a number
if (k instanceof BigNumber) k = k.toNumber();
if (!isNumber(k) || !isInteger(k)) {
throw new TypeError ('Second parameter in function diag must be an integer');
}
@ -54,15 +58,13 @@ module.exports = function (math) {
throw new TypeError ('First parameter in function diag must be a Matrix or Array');
}
// TODO: bignumber support for diag
var s = x.size();
switch (s.length) {
case 1:
// x is a vector. create diagonal matrix
vector = x.valueOf();
var matrix = new Matrix();
var defaultValue = 0;
var defaultValue = (vector[0] instanceof BigNumber) ? new BigNumber(0) : 0;
matrix.resize([vector.length + kSub, vector.length + kSuper], defaultValue);
data = matrix.valueOf();
iMax = vector.length;

View File

@ -1,11 +1,10 @@
module.exports = function (math, settings) {
module.exports = function (math, config) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Matrix = require('../../type/Matrix'),
collection = require('../../type/collection'),
toNumber = util.number.toNumber,
isNumber = util.number.isNumber,
isInteger = util.number.isInteger,
isArray = Array.isArray;
@ -25,7 +24,7 @@ module.exports = function (math, settings) {
math.eye = function eye (size) {
var args = collection.argsToArray(arguments),
asMatrix = (size instanceof Matrix) ? true :
(isArray(size) ? false : (settings.matrix === 'matrix'));
(isArray(size) ? false : (config.matrix === 'matrix'));
if (args.length == 0) {
@ -41,16 +40,11 @@ module.exports = function (math, settings) {
throw new math.error.ArgumentsError('eye', args.length, 0, 2);
}
var asBigNumber = args[0] instanceof BigNumber,
rows = args[0],
var rows = args[0],
cols = args[1];
if (rows instanceof BigNumber) {
rows = toNumber(rows);
}
if (cols instanceof BigNumber) {
cols = toNumber(cols);
}
if (rows instanceof BigNumber) rows = rows.toNumber();
if (cols instanceof BigNumber) cols = cols.toNumber();
if (!isNumber(rows) || !isInteger(rows) || rows < 1) {
throw new Error('Parameters in function eye must be positive integers');
@ -59,11 +53,22 @@ module.exports = function (math, settings) {
throw new Error('Parameters in function eye must be positive integers');
}
// convert arguments from bignumber to numbers if needed
var asBigNumber = false;
args = args.map(function (value) {
if (value instanceof BigNumber) {
asBigNumber = true;
return value.toNumber();
} else {
return value;
}
});
// create the matrix
var matrix = new Matrix();
var one = asBigNumber ? new BigNumber(1) : 1;
var defaultValue = asBigNumber ? new BigNumber(0) : 0;
matrix.resize(args.map(toNumber), defaultValue);
matrix.resize(args, defaultValue);
// fill in ones on the diagonal
var minimum = math.min(args);

View File

@ -1,5 +1,6 @@
module.exports = function (math) {
var string = require('../../util/string'),
var util = require('../../util/index'),
string = util.string,
Matrix = require('../../type/Matrix'),
collection = require('../../type/collection');

View File

@ -1,13 +1,12 @@
module.exports = function (math, settings) {
module.exports = function (math, config) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Matrix = require('../../type/Matrix'),
collection = require('../../type/collection'),
array = util.array,
toNumber = util.number.toNumber,
isArray = Array.isArray;
/**
@ -24,7 +23,7 @@ module.exports = function (math, settings) {
math.ones = function ones (size) {
var args = collection.argsToArray(arguments);
var asMatrix = (size instanceof Matrix) ? true :
(isArray(size) ? false : (settings.matrix === 'matrix'));
(isArray(size) ? false : (config.matrix === 'matrix'));
if (args.length == 0) {
// output an empty matrix
@ -32,9 +31,22 @@ module.exports = function (math, settings) {
}
else {
// output an array or matrix
// convert arguments from bignumber to numbers if needed
var asBigNumber = false;
args = args.map(function (value) {
if (value instanceof BigNumber) {
asBigNumber = true;
return value.toNumber();
} else {
return value;
}
});
// resize the matrix
var res = [];
var defaultValue = (args[0] instanceof BigNumber) ? new BigNumber(1) : 1;
res = array.resize(res, args.map(toNumber), defaultValue);
var defaultValue = asBigNumber ? new BigNumber(1) : 1;
res = array.resize(res, args, defaultValue);
return asMatrix ? new Matrix(res) : res;
}

View File

@ -1,15 +1,13 @@
module.exports = function (math, settings) {
module.exports = function (math, config) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Matrix = require('../../type/Matrix'),
collection = require('../../type/collection'),
isBoolean = util['boolean'].isBoolean,
isString = util.string.isString,
isNumber = util.number.isNumber,
toNumber = util.number.toNumber,
toBigNumber = util.number.toBigNumber;
isNumber = util.number.isNumber;
/**
* Create an array from a range.
@ -71,8 +69,7 @@ module.exports = function (math, settings) {
step = r.step;
}
else {
throw new TypeError(
'Two or three numbers or a single string expected in function range');
throw new TypeError('Two or three numbers or a single string expected in function range');
}
break;
@ -115,23 +112,17 @@ module.exports = function (math, settings) {
var asBigNumber = true;
// convert start, end, step to BigNumber
if (!(start instanceof BigNumber)) {
start = toBigNumber(start);
}
if (!(end instanceof BigNumber)) {
end = toBigNumber(end);
}
if (!(step instanceof BigNumber)) {
step = toBigNumber(step);
}
if (!(start instanceof BigNumber)) start = BigNumber.convert(start);
if (!(end instanceof BigNumber)) end = BigNumber.convert(end);
if (!(step instanceof BigNumber)) step = BigNumber.convert(step);
if (!(start instanceof BigNumber) || !(end instanceof BigNumber) || !(step instanceof BigNumber)) {
// not all values can be converted to big number :(
// fall back to numbers
asBigNumber = false;
start = toNumber(start);
end = toNumber(end);
step = toNumber(step);
if (start instanceof BigNumber) start = start.toNumber();
if (end instanceof BigNumber) end = end.toNumber();
if (step instanceof BigNumber) step = step.toNumber();
}
}
@ -142,7 +133,7 @@ module.exports = function (math, settings) {
var array = fn(start, end, step);
// return as array or matrix
return (settings.matrix === 'array') ? array : new Matrix(array);
return (config.matrix === 'array') ? array : new Matrix(array);
};
/**
@ -268,7 +259,7 @@ module.exports = function (math, settings) {
var args = str.split(':'),
nums = null;
if (settings.number === 'bignumber') {
if (config.number === 'bignumber') {
// bignumber
try {
nums = args.map(function (arg) {

View File

@ -1,14 +1,13 @@
module.exports = function (math, settings) {
module.exports = function (math, config) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Matrix = require('../../type/Matrix'),
array = util.array,
clone = util.object.clone,
string = util.string,
isString = util.string.isString,
toNumber = util.number.toNumber,
isNumber = util.number.isNumber,
isInteger = util.number.isInteger,
isArray = array.isArray;
@ -31,7 +30,7 @@ module.exports = function (math, settings) {
throw new math.error.ArgumentsError('resize', arguments.length, 2, 3);
}
var asMatrix = (x instanceof Matrix) ? true : isArray(x) ? false : (settings.matrix !== 'array');
var asMatrix = (x instanceof Matrix) ? true : isArray(x) ? false : (config.matrix !== 'array');
if (x instanceof Matrix) {
x = x.valueOf(); // get Array
@ -42,7 +41,9 @@ module.exports = function (math, settings) {
if (size.length && size[0] instanceof BigNumber) {
// convert bignumbers to numbers
size = size.map(toNumber);
size = size.map(function (value) {
return (value instanceof BigNumber) ? value.toNumber() : value;
});
}
if (isString(x)) {
@ -88,7 +89,7 @@ module.exports = function (math, settings) {
}
if (size.length !== 1) {
throw new Error('Dimension mismatch: (' + size.length + ' != 1)');
throw new math.error.DimensionError(size.length, 1);
}
var len = size[0];
if (!isNumber(len) || !isInteger(len)) {

View File

@ -1,7 +1,7 @@
module.exports = function (math, settings) {
module.exports = function (math, config) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Complex = require('../../type/Complex'),
Unit = require('../../type/Unit'),
Matrix = require('../../type/Matrix'),
@ -26,7 +26,7 @@ module.exports = function (math, settings) {
throw new math.error.ArgumentsError('size', arguments.length, 1);
}
var asArray = (settings.matrix === 'array');
var asArray = (config.matrix === 'array');
if (isNumber(x) || isComplex(x) || isUnit(x) || isBoolean(x) ||
x == null || x instanceof BigNumber) {
@ -45,6 +45,6 @@ module.exports = function (math, settings) {
return new Matrix(x.size());
}
throw new math.error.UnsupportedTypeError('size', x);
throw new math.error.UnsupportedTypeError('size', math['typeof'](x));
};
};

View File

@ -67,7 +67,7 @@ module.exports = function (math) {
return _getSubstring(value, index);
}
else {
throw new math.error.UnsupportedTypeError('subset', value);
throw new math.error.UnsupportedTypeError('subset', math['typeof'](value));
}
}
@ -84,7 +84,7 @@ module.exports = function (math) {
throw new TypeError('Index expected');
}
if (index.size().length != 1) {
throw new RangeError('Dimension mismatch (' + index.size().length + ' != 1)');
throw new math.error.DimensionError(index.size().length, 1);
}
var range = index.range(0);
@ -126,7 +126,7 @@ module.exports = function (math) {
return _setSubstring(value, index, replacement, defaultValue);
}
else {
throw new math.error.UnsupportedTypeError('subset', value);
throw new math.error.UnsupportedTypeError('subset', math['typeof'](value));
}
}
@ -146,7 +146,7 @@ module.exports = function (math) {
throw new TypeError('Index expected');
}
if (index.size().length != 1) {
throw new RangeError('Dimension mismatch (' + index.size().length + ' != 1)');
throw new math.error.DimensionError(index.size().length, 1);
}
if (defaultValue !== undefined) {
if (!isString(defaultValue) || defaultValue.length !== 1) {
@ -161,8 +161,7 @@ module.exports = function (math) {
var len = range.size()[0];
if (len != replacement.length) {
throw new RangeError('Dimension mismatch ' +
'(' + range.size()[0] + ' != ' + replacement.length + ')');
throw new math.error.DimensionError(range.size()[0], replacement.length);
}
// copy the string into an array with characters

View File

@ -1,12 +1,11 @@
module.exports = function (math, settings) {
module.exports = function (math, config) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
Matrix = require('../../type/Matrix'),
collection = require('../../type/collection'),
array = util.array,
toNumber = util.number.toNumber,
isArray = Array.isArray;
/**
@ -23,7 +22,7 @@ module.exports = function (math, settings) {
math.zeros = function zeros (size) {
var args = collection.argsToArray(arguments);
var asMatrix = (size instanceof Matrix) ? true :
(isArray(size) ? false : (settings.matrix === 'matrix'));
(isArray(size) ? false : (config.matrix === 'matrix'));
if (args.length == 0) {
// output an empty matrix
@ -31,9 +30,22 @@ module.exports = function (math, settings) {
}
else {
// output an array or matrix
// convert arguments from bignumber to numbers if needed
var asBigNumber = false;
args = args.map(function (value) {
if (value instanceof BigNumber) {
asBigNumber = true;
return value.toNumber();
} else {
return value;
}
});
// resize the matrix
var res = [];
var defaultValue = (args[0] instanceof BigNumber) ? new BigNumber(0) : 0;
res = array.resize(res, args.map(toNumber), defaultValue);
var defaultValue = asBigNumber ? new BigNumber(0) : 0;
res = array.resize(res, args, defaultValue);
return asMatrix ? new Matrix(res) : res;
}

View File

@ -1,12 +1,11 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
collection = require('../../type/collection'),
isNumber = util.number.isNumber,
isInteger = util.number.isInteger,
toBigNumber = util.number.toBigNumber;
isInteger = util.number.isInteger;
/**
* Compute the number of combinations of n items taken k at a time
@ -47,7 +46,7 @@ module.exports = function (math) {
if (n instanceof BigNumber) {
// make sure k is a BigNumber as well
// not all numbers can be converted to BigNumber
k = toBigNumber(k);
k = BigNumber.convert(k);
if (!(k instanceof BigNumber) || !isPositiveInteger(n) || !isPositiveInteger(k)) {
throw new TypeError('Positive integer value expected in function combinations');
@ -65,7 +64,7 @@ module.exports = function (math) {
return result;
}
throw new math.error.UnsupportedTypeError('combinations', n);
throw new math.error.UnsupportedTypeError('combinations', math['typeof'](n));
};
/**
@ -74,6 +73,6 @@ module.exports = function (math) {
* @returns {boolean} isPositiveInteger
*/
var isPositiveInteger = function(n) {
return n.round().equals(n) && n.gte(0);
return n.isInteger() && n.gte(0);
};
};

View File

@ -1,7 +1,7 @@
module.exports = function (math) {
var util = require('../../util/index'),
BigNumber = require('bignumber.js'),
BigNumber = math.type.BigNumber,
collection = require('../../type/collection'),
isNumber = util.number.isNumber,
@ -76,7 +76,7 @@ module.exports = function (math) {
return collection.deepMap(n, factorial);
}
throw new math.error.UnsupportedTypeError('factorial', n);
throw new math.error.UnsupportedTypeError('factorial', math['typeof'](n));
};
/**
@ -85,6 +85,6 @@ module.exports = function (math) {
* @returns {boolean} isPositiveInteger
*/
var isPositiveInteger = function(n) {
return n.round().equals(n) && n.gte(0);
return n.isInteger() && n.gte(0);
};
};

Some files were not shown because too many files have changed in this diff Show More