mathjs 3.1.0 → 3.1.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of mathjs might be problematic. Click here for more details.

Files changed (45) hide show
  1. package/HISTORY.md +34 -1
  2. package/dist/math.js +614 -500
  3. package/dist/math.map +1 -1
  4. package/dist/math.min.js +17 -17
  5. package/docs/expressions/customization.md +1 -0
  6. package/docs/reference/functions/format.md +12 -5
  7. package/docs/reference/functions/log10.md +1 -1
  8. package/docs/reference/functions.md +1 -1
  9. package/lib/expression/node/FunctionNode.js +7 -6
  10. package/lib/expression/node/OperatorNode.js +4 -4
  11. package/lib/expression/parse.js +42 -20
  12. package/lib/function/arithmetic/cbrt.js +32 -32
  13. package/lib/function/arithmetic/log10.js +12 -2
  14. package/lib/function/arithmetic/nthRoot.js +2 -2
  15. package/lib/function/statistics/max.js +7 -2
  16. package/lib/function/statistics/mean.js +7 -2
  17. package/lib/function/statistics/median.js +8 -2
  18. package/lib/function/statistics/min.js +7 -2
  19. package/lib/function/statistics/mode.js +3 -3
  20. package/lib/function/statistics/prod.js +2 -2
  21. package/lib/function/statistics/std.js +2 -2
  22. package/lib/function/statistics/sum.js +2 -2
  23. package/lib/function/statistics/var.js +2 -2
  24. package/lib/function/string/format.js +12 -5
  25. package/lib/function/trigonometry/acosh.js +11 -1
  26. package/lib/function/trigonometry/asec.js +1 -1
  27. package/lib/function/trigonometry/asinh.js +1 -1
  28. package/lib/function/trigonometry/atanh.js +11 -1
  29. package/lib/function/trigonometry/cosh.js +2 -2
  30. package/lib/function/trigonometry/sinh.js +3 -7
  31. package/lib/function/trigonometry/tanh.js +2 -2
  32. package/lib/type/unit/Unit.js +3 -0
  33. package/lib/utils/collection/containsCollections.js +18 -0
  34. package/lib/utils/number.js +1 -1
  35. package/lib/utils/types.js +10 -0
  36. package/lib/version.js +1 -1
  37. package/package.json +1 -1
  38. package/test/expression/node/FunctionNode.test.js +12 -0
  39. package/test/expression/parse.test.js +24 -3
  40. package/test/function/arithmetic/nthRoot.test.js +10 -0
  41. package/test/function/statistics/max.test.js +5 -0
  42. package/test/function/statistics/mean.test.js +5 -0
  43. package/test/function/statistics/median.test.js +5 -0
  44. package/test/function/statistics/min.test.js +5 -0
  45. package/test/function/trigonometry/sinh.test.js +41 -30
@@ -62,10 +62,10 @@ function factory (type, config, load, typed) {
62
62
  * @returns {number}
63
63
  * @private
64
64
  */
65
- function _tanh (x) {
65
+ var _tanh = Math.tanh || function (x) {
66
66
  var e = Math.exp(2 * x);
67
67
  return (e - 1) / (e + 1);
68
- }
68
+ };
69
69
 
70
70
  exports.name = 'tanh';
71
71
  exports.factory = factory;
@@ -2633,6 +2633,9 @@ function factory (type, config, load, typed, math) {
2633
2633
  hr: 'hour',
2634
2634
  hrs: 'hour',
2635
2635
  days: 'day',
2636
+ weeks: 'week',
2637
+ months: 'month',
2638
+ years: 'year',
2636
2639
 
2637
2640
  hertz: 'hertz',
2638
2641
 
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ var isCollection = require('./isCollection');
4
+
5
+ /**
6
+ * Test whether an array contains collections
7
+ * @param {Array} array
8
+ * @returns {boolean} Returns true when the array contains one or multiple
9
+ * collections (Arrays or Matrices). Returns false otherwise.
10
+ */
11
+ module.exports = function containsCollections (array) {
12
+ for (var i = 0; i < array.length; i++) {
13
+ if (isCollection(array[i])) {
14
+ return true;
15
+ }
16
+ }
17
+ return false;
18
+ };
@@ -28,7 +28,7 @@ exports.isInteger = function(value) {
28
28
  * @param {number} x
29
29
  * @returns {*}
30
30
  */
31
- exports.sign = function(x) {
31
+ exports.sign = Math.sign || function(x) {
32
32
  if (x > 0) {
33
33
  return 1;
34
34
  }
@@ -42,3 +42,13 @@ exports.type = function(x) {
42
42
 
43
43
  return type;
44
44
  };
45
+
46
+ /**
47
+ * Test whether a value is a scalar
48
+ * @param x
49
+ * @return {boolean} Returns true when x is a scalar, returns false when
50
+ * x is a Matrix or Array.
51
+ */
52
+ exports.isScalar = function (x) {
53
+ return !((x && x.isMatrix) || Array.isArray(x));
54
+ };
package/lib/version.js CHANGED
@@ -1,3 +1,3 @@
1
- module.exports = '3.1.0';
1
+ module.exports = '3.1.4';
2
2
  // Note: This file is automatically generated when building math.js.
3
3
  // Changes made in this file will be overwritten.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mathjs",
3
- "version": "3.1.0",
3
+ "version": "3.1.4",
4
4
  "description": "Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser and offers an integrated solution to work with numbers, big numbers, complex numbers, units, and matrices.",
5
5
  "author": "Jos de Jong <wjosdejong@gmail.com> (https://github.com/josdejong)",
6
6
  "contributors": [
@@ -362,6 +362,18 @@ describe('FunctionNode', function() {
362
362
  assert.equal(n.toString(), 'sqrt(4)');
363
363
  });
364
364
 
365
+ it ('should pass options when stringifying a FunctionNode', function () {
366
+ var s = new SymbolNode('sqrt');
367
+ var a = new ConstantNode(2);
368
+ var b = new SymbolNode('x');
369
+ var c = new OperatorNode('*', 'multiply', [a, b], true); // implicit
370
+ var n = new FunctionNode(s, [c]);
371
+
372
+ assert.equal(n.toString(), 'sqrt(2 x)');
373
+ var options = {implicit: 'show'};
374
+ assert.equal(n.toString(options), 'sqrt(2 * x)');
375
+ });
376
+
365
377
  it ('should stringify a FunctionNode with custom toString', function () {
366
378
  //Also checks if the custom functions get passed on to the children
367
379
  var customFunction = function (node, options) {
@@ -231,6 +231,17 @@ describe('parse', function() {
231
231
  assert.throws(function () {parseAndEval('.'); }, SyntaxError);
232
232
  assert.throws(function () {parseAndEval('3.2.2'); }, SyntaxError);
233
233
  assert.throws(function () {parseAndEval('3.2e2.2'); }, SyntaxError);
234
+
235
+ assert.throws(function () {parseAndEval('3e0.5'); }, /Digit expected, got "."/);
236
+ assert.throws(function () {parseAndEval('3e.5'); }, /Digit expected, got "."/);
237
+ assert.throws(function () {parseAndEval('-3e0.5'); }, /Digit expected, got "."/);
238
+ assert.throws(function () {parseAndEval('-3e.5'); }, /Digit expected, got "."/);
239
+ assert.throws(function () {parseAndEval('3e-0.5'); }, /Digit expected, got "."/);
240
+ assert.throws(function () {parseAndEval('3e-.5'); }, /Digit expected, got "."/);
241
+ assert.throws(function () {parseAndEval('-3e-0.5'); }, /Digit expected, got "."/);
242
+ assert.throws(function () {parseAndEval('-3e-.5'); }, /Digit expected, got "."/);
243
+
244
+ assert.throws(function () {parseAndEval('2e+a'); }, /Digit expected, got "a"/);
234
245
  });
235
246
 
236
247
  });
@@ -274,6 +285,15 @@ describe('parse', function() {
274
285
  assert.deepEqual(parseAndEval(' "hi" '), "hi");
275
286
  });
276
287
 
288
+ it('should parse a with escaped characters', function() {
289
+ assert.deepEqual(parseAndEval('"line end\\nnext"'), 'line end\nnext');
290
+ assert.deepEqual(parseAndEval('"line end\\n"'), 'line end\n');
291
+ assert.deepEqual(parseAndEval('"tab\\tnext"'), 'tab\tnext');
292
+ assert.deepEqual(parseAndEval('"tab\\t"'), 'tab\t');
293
+ assert.deepEqual(parseAndEval('"escaped backslash\\\\next"'), 'escaped backslash\\next');
294
+ assert.deepEqual(parseAndEval('"escaped backslash\\\\"'), 'escaped backslash\\');
295
+ });
296
+
277
297
  it('should throw an error with invalid strings', function() {
278
298
  assert.throws(function () {parseAndEval('"hi'); }, SyntaxError);
279
299
  assert.throws(function () {parseAndEval(' hi" '); }, Error);
@@ -364,9 +384,9 @@ describe('parse', function() {
364
384
  approx.deepEqual(parseAndEval('2 in to meter'), new Unit(2, 'inch').to('meter'));
365
385
  approx.deepEqual(parseAndEval('2 in in meter'), new Unit(2, 'inch').to('meter'));
366
386
  approx.deepEqual(parseAndEval('a in inch', {a: new Unit(5.08, 'cm')}), new Unit(2, 'inch').to('inch'));
367
- // Note: the following is not supported (due to conflicts):
368
- //approx.deepEqual(parseAndEval('(2+3) in'), new Unit(5, 'inch'));
369
- //approx.deepEqual(parseAndEval('a in', {a: 5}), new Unit(5, 'inch'));
387
+ approx.deepEqual(parseAndEval('(2+3) in'), new Unit(5, 'in'));
388
+ approx.deepEqual(parseAndEval('a in', {a: 5}), new Unit(5, 'in'));
389
+ approx.deepEqual(parseAndEval('0.5in + 1.5in to cm'), new Unit(5.08, 'cm').to('cm'));
370
390
  });
371
391
  });
372
392
 
@@ -1053,6 +1073,7 @@ describe('parse', function() {
1053
1073
 
1054
1074
  assert.equal(parseAndEval('(2+3)a', {a:2}), 10);
1055
1075
  assert.equal(parseAndEval('(2+3)2'), 10);
1076
+ assert.equal(parseAndEval('(2)(3)+4'), 10);
1056
1077
  assert.equal(parseAndEval('2(3+4)'), 14);
1057
1078
  assert.equal(parseAndEval('(2+3)-2'), 3); // no implicit multiplication, just a unary minus
1058
1079
  assert.equal(parseAndEval('a(2+3)', {a: function() {return 42;}}), 42); // function call
@@ -56,6 +56,11 @@ describe('nthRoot', function() {
56
56
  approx.equal(nthRoot(-64, -3), -0.25);
57
57
  });
58
58
 
59
+ it('should return the nthRoot for zero', function() {
60
+ assert.equal(nthRoot(0, 2), 0);
61
+ assert.equal(nthRoot(0, -2), Infinity);
62
+ });
63
+
59
64
  it('should return the nthRoot for infinity', function() {
60
65
  approx.equal(nthRoot(Infinity, 2), Infinity);
61
66
  approx.equal(nthRoot(-Infinity, 3), -Infinity);
@@ -94,6 +99,11 @@ describe('nthRoot', function() {
94
99
  assert.deepEqual(nthRoot(big(-64), big(-3)), big(-0.25));
95
100
  });
96
101
 
102
+ it('should return the nthRoot for bignumber zero', function() {
103
+ assert.deepEqual(nthRoot(big(0), big(2)).toString(), '0');
104
+ assert.deepEqual(nthRoot(big(0), big(-2)).toString(), 'Infinity');
105
+ });
106
+
97
107
  it('should return the nthRoot for bignumber infinity', function() {
98
108
  assert.deepEqual(nthRoot(big(Infinity), big(2)).toString(), 'Infinity');
99
109
  assert.deepEqual(nthRoot(big(-Infinity), big(3)).toString(), '-Infinity');
@@ -78,6 +78,11 @@ describe('max', function() {
78
78
  assert.throws(function () {max(new Complex(3,4), 6)}, TypeError);
79
79
  });
80
80
 
81
+ it('should throw an error when called multiple arrays or matrices', function() {
82
+ assert.throws(function () {max([1,2], [3,4])}, /Scalar values expected/);
83
+ assert.throws(function () {max(math.matrix([1,2]), math.matrix([3,4]))}, /Scalar values expected/);
84
+ });
85
+
81
86
  it('should throw an error if called a dimension out of range', function() {
82
87
  assert.throws(function() {max([1,2,3], -1)}, /IndexError: Index out of range \(-1 < 0\)/);
83
88
  assert.throws(function() {max([1,2,3], 1)}, /IndexError: Index out of range \(1 > 0\)/);
@@ -78,6 +78,11 @@ describe('mean', function() {
78
78
  assert.throws(function() {mean([], 2, 3)});
79
79
  });
80
80
 
81
+ it('should throw an error when called multiple arrays or matrices', function() {
82
+ assert.throws(function () {mean([1,2], [3,4])}, /Scalar values expected/);
83
+ assert.throws(function () {mean(math.matrix([1,2]), math.matrix([3,4]))}, /Scalar values expected/);
84
+ });
85
+
81
86
  it('should throw an error if called a dimension out of range', function() {
82
87
  assert.throws(function() {mean([1,2,3], -1)}, /IndexError: Index out of range \(-1 < 0\)/);
83
88
  assert.throws(function() {mean([1,2,3], 1)}, /IndexError: Index out of range \(1 > 0\)/);
@@ -73,6 +73,11 @@ describe('median', function() {
73
73
  assert.throws(function() {median([], 2, 3)});
74
74
  });
75
75
 
76
+ it('should throw an error when called multiple arrays or matrices', function() {
77
+ assert.throws(function () {median([1,2], [3,4])}, /Scalar values expected/);
78
+ assert.throws(function () {median(math.matrix([1,2]), math.matrix([3,4]))}, /Scalar values expected/);
79
+ });
80
+
76
81
  it('should throw an error if called with not yet supported argument dim', function() {
77
82
  assert.throws(function() {median([], 2)}, /not yet supported/);
78
83
  });
@@ -87,6 +87,11 @@ describe('min', function() {
87
87
  assert.throws(function () {min(new Complex(3,4), 6)}, TypeError);
88
88
  });
89
89
 
90
+ it('should throw an error when called multiple arrays or matrices', function() {
91
+ assert.throws(function () {min([1,2], [3,4])}, /Scalar values expected/);
92
+ assert.throws(function () {min(math.matrix([1,2]), math.matrix([3,4]))}, /Scalar values expected/);
93
+ });
94
+
90
95
  it('should throw an error if called a dimension out of range', function() {
91
96
  assert.throws(function() {min([1,2,3], -1)}, /IndexError: Index out of range \(-1 < 0\)/);
92
97
  assert.throws(function() {min([1,2,3], 1)}, /IndexError: Index out of range \(1 > 0\)/);
@@ -1,35 +1,46 @@
1
- var assert = require('assert'),
2
- error = require('../../../lib/error/index'),
3
- math = require('../../../index'),
4
- approx = require('../../../tools/approx'),
5
- pi = math.pi,
6
- complex = math.complex,
7
- matrix = math.matrix,
8
- unit = math.unit,
9
- sinh = math.sinh,
10
- bigmath = math.create({number: 'BigNumber', precision: 20});
1
+ var assert = require('assert');
2
+ var error = require('../../../lib/error/index');
3
+ var math = require('../../../index');
4
+ var approx = require('../../../tools/approx');
5
+ var complex = math.complex;
6
+ var matrix = math.matrix;
7
+ var unit = math.unit;
8
+ var sinh = math.sinh;
9
+ var bigmath = math.create({number: 'BigNumber', precision: 20});
10
+
11
+ var EPSILON = 1e-14;
12
+
11
13
 
12
14
  describe('sinh', function() {
13
15
  it('should return the sinh of a boolean', function () {
14
- approx.equal(sinh(true), 1.1752011936438014);
15
- approx.equal(sinh(false), 0);
16
+ assert.equal(sinh(true), 1.1752011936438014);
17
+ assert.equal(sinh(false), 0);
16
18
  });
17
19
 
18
20
  it('should return the sinh of a null', function () {
19
- approx.equal(sinh(null), 0);
21
+ assert.equal(sinh(null), 0);
20
22
  });
21
23
 
22
24
  it('should return the sinh of a number', function() {
23
- approx.equal(sinh(0), 0);
24
- approx.equal(sinh(pi), 11.548739357257748);
25
- approx.equal(sinh(1), 1.1752011936438014);
25
+ approx.equal(sinh(-2), -3.62686040784701876766821398280126170488634201232113572130, EPSILON);
26
+ approx.equal(sinh(-0.5), -0.52109530549374736162242562641149155910592898261148052794, EPSILON);
27
+ approx.equal(sinh(0), 0, EPSILON);
28
+ approx.equal(sinh(0.3), 0.304520293447142618958435267005095229098024232680179727377, EPSILON);
29
+ approx.equal(sinh(0.5), 0.521095305493747361622425626411491559105928982611480527946, EPSILON);
30
+ approx.equal(sinh(0.8), 0.888105982187623006574717573189756980559709596888150052610, EPSILON);
31
+ approx.equal(sinh(1), 1.175201193643801456882381850595600815155717981334095870229, EPSILON);
32
+ approx.equal(sinh(2), 3.626860407847018767668213982801261704886342012321135721309, EPSILON);
26
33
  });
27
34
 
28
- it('should return the sinh of very small numbers (avoid returning zero)', function() {
29
- // If sinh returns 0, that is bad, so we are using assert.equal, not approx.equal
30
- assert.equal(sinh(-1e-10), -1e-10);
31
- assert.equal(sinh(1e-50), 1e-50);
32
- })
35
+ if (!/v0\.10|v0\.12/.test(process.version)) {
36
+ // skip this test on node v0.10 and v0.12, which have a numerical issue
37
+
38
+ it('should return the sinh of very small numbers (avoid returning zero)', function() {
39
+ // If sinh returns 0, that is bad, so we are using assert.equal, not approx.equal
40
+ assert.equal(sinh(-1e-10), -1e-10);
41
+ assert.equal(sinh(1e-50), 1e-50);
42
+ });
43
+ }
33
44
 
34
45
  it('should return the sinh of a bignumber', function() {
35
46
  var sinhBig = bigmath.sinh;
@@ -56,19 +67,19 @@ describe('sinh', function() {
56
67
  });
57
68
 
58
69
  it('should return the sinh of a complex number', function() {
59
- approx.deepEqual(sinh(complex('1')), complex(1.1752011936438014, 0));
60
- approx.deepEqual(sinh(complex('i')), complex(0, 0.8414709848079));
61
- approx.deepEqual(sinh(complex('2 + i')), complex(1.9596010414216, 3.1657785132162));
70
+ approx.deepEqual(sinh(complex('1')), complex(1.1752011936438014, 0), EPSILON);
71
+ approx.deepEqual(sinh(complex('i')), complex(0, 0.8414709848079), EPSILON);
72
+ approx.deepEqual(sinh(complex('2 + i')), complex(1.9596010414216, 3.1657785132162), EPSILON);
62
73
  });
63
74
 
64
75
  it('should return the sinh of an angle', function() {
65
- approx.equal(sinh(unit('90deg')), 2.3012989023073);
66
- approx.equal(sinh(unit('-45deg')), -0.86867096148601);
76
+ approx.equal(sinh(unit('90deg')), 2.3012989023073, EPSILON);
77
+ approx.equal(sinh(unit('-45deg')), -0.86867096148601, EPSILON);
67
78
 
68
79
  assert(sinh(unit(math.bignumber(90), 'deg')).isBigNumber);
69
- approx.equal(sinh(unit(math.bignumber(90), 'deg')).toNumber(), 2.3012989023073);
80
+ approx.equal(sinh(unit(math.bignumber(90), 'deg')).toNumber(), 2.3012989023073, EPSILON);
70
81
 
71
- approx.deepEqual(sinh(unit(complex('2 + i'), 'rad')), complex(1.9596010414216, 3.1657785132162));
82
+ approx.deepEqual(sinh(unit(complex('2 + i'), 'rad')), complex(1.9596010414216, 3.1657785132162), EPSILON);
72
83
  });
73
84
 
74
85
  it('should throw an error if called with an invalid unit', function() {
@@ -82,11 +93,11 @@ describe('sinh', function() {
82
93
  var sinh123 = [1.1752011936438014, 3.626860407847, 10.01787492741];
83
94
 
84
95
  it('should return the sinh of each element of an array', function() {
85
- approx.deepEqual(sinh([1,2,3]), sinh123);
96
+ approx.deepEqual(sinh([1,2,3]), sinh123, EPSILON);
86
97
  });
87
98
 
88
99
  it('should return the sinh of each element of a matrix', function() {
89
- approx.deepEqual(sinh(matrix([1,2,3])), matrix(sinh123));
100
+ approx.deepEqual(sinh(matrix([1,2,3])), matrix(sinh123), EPSILON);
90
101
  });
91
102
 
92
103
  it('should throw an error in case of invalid number of arguments', function() {