mathjs 5.0.0 → 5.0.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.
- package/HISTORY.md +48 -1
- package/README.md +2 -1
- package/dist/math.js +20114 -20090
- package/dist/math.min.js +7 -7
- package/dist/math.min.map +1 -1
- package/docs/core/configuration.md +1 -1
- package/docs/datatypes/numbers.md +1 -1
- package/docs/datatypes/units.md +1 -1
- package/docs/expressions/algebra.md +25 -1
- package/docs/getting_started.md +2 -2
- package/docs/reference/functions/format.md +2 -2
- package/docs/reference/functions/qr.md +2 -1
- package/docs/reference/functions/rationalize.md +13 -10
- package/docs/reference/functions/stirlingS2.md +1 -1
- package/docs/reference/functions/typeof.md +13 -13
- package/examples/advanced/add_new_datatypes/MyType.js +0 -10
- package/examples/advanced/add_new_datatypes/index.js +2 -6
- package/examples/browser/rocket_trajectory_optimization.html +2 -2
- package/lib/constants.js +3 -1
- package/lib/core/function/import.js +15 -2
- package/lib/core/typed.js +1 -1
- package/lib/expression/node/FunctionNode.js +5 -4
- package/lib/expression/parse.js +429 -466
- package/lib/function/algebra/decomposition/qr.js +1 -1
- package/lib/function/algebra/rationalize.js +41 -45
- package/lib/function/algebra/simplify/resolve.js +1 -1
- package/lib/function/algebra/simplify/simplifyCore.js +3 -3
- package/lib/function/algebra/simplify/util.js +1 -1
- package/lib/function/algebra/simplify.js +5 -0
- package/lib/function/combinatorics/stirlingS2.js +1 -1
- package/lib/function/probability/combinations.js +11 -10
- package/lib/function/probability/gamma.js +5 -13
- package/lib/function/probability/permutations.js +2 -12
- package/lib/function/probability/product.js +19 -0
- package/lib/function/string/format.js +2 -2
- package/lib/function/utils/typeof.js +13 -13
- package/lib/index.js +5 -1
- package/lib/type/bignumber/BigNumber.js +6 -2
- package/lib/type/matrix/utils/algorithm13.js +0 -2
- package/lib/type/unit/Unit.js +2 -2
- package/lib/utils/array.js +27 -19
- package/lib/utils/bignumber/formatter.js +3 -2
- package/lib/utils/number.js +15 -10
- package/lib/version.js +1 -1
- package/package.json +13 -8
- package/src/constants.js +3 -1
- package/src/core/function/import.js +15 -2
- package/src/core/typed.js +1 -1
- package/src/expression/node/FunctionNode.js +3 -4
- package/src/expression/parse.js +432 -470
- package/src/function/algebra/decomposition/qr.js +1 -1
- package/src/function/algebra/rationalize.js +41 -43
- package/src/function/algebra/simplify/resolve.js +1 -1
- package/src/function/algebra/simplify/simplifyCore.js +3 -3
- package/src/function/algebra/simplify/util.js +1 -1
- package/src/function/algebra/simplify.js +5 -0
- package/src/function/combinatorics/stirlingS2.js +1 -1
- package/src/function/probability/combinations.js +10 -8
- package/src/function/probability/gamma.js +5 -13
- package/src/function/probability/permutations.js +2 -11
- package/src/function/probability/product.js +17 -0
- package/src/function/string/format.js +2 -2
- package/src/function/utils/typeof.js +13 -13
- package/src/index.js +5 -1
- package/src/type/bignumber/BigNumber.js +2 -1
- package/src/type/matrix/utils/algorithm13.js +0 -2
- package/src/type/unit/Unit.js +2 -2
- package/src/utils/array.js +31 -23
- package/src/utils/bignumber/formatter.js +3 -2
- package/src/utils/number.js +15 -10
- package/src/version.js +1 -1
@@ -4,7 +4,6 @@ function factory(type, config, load, typed) {
|
|
4
4
|
var simplify = load(require('./simplify'));
|
5
5
|
var simplifyCore = load(require('./simplify/simplifyCore'));
|
6
6
|
var simplifyConstant = load(require('./simplify/simplifyConstant'));
|
7
|
-
var ArgumentsError = require('../../error/ArgumentsError');
|
8
7
|
var parse = load(require('../../expression/function/parse'));
|
9
8
|
var number = require('../../utils/number');
|
10
9
|
var ConstantNode = load(require('../../expression/node/ConstantNode'));
|
@@ -26,22 +25,25 @@ function factory(type, config, load, typed) {
|
|
26
25
|
*
|
27
26
|
* Examples:
|
28
27
|
*
|
29
|
-
* math.rationalize('sin(x)+y')
|
30
|
-
*
|
28
|
+
* math.rationalize('sin(x)+y')
|
29
|
+
* // Error: There is an unsolved function call
|
30
|
+
* math.rationalize('2x/y - y/(x+1)')
|
31
|
+
* // (2*x^2-y^2+2*x)/(x*y+y)
|
31
32
|
* math.rationalize('(2x+1)^6')
|
32
|
-
* //
|
33
|
+
* // 64*x^6+192*x^5+240*x^4+160*x^3+60*x^2+12*x+1
|
33
34
|
* math.rationalize('2x/( (2x-1) / (3x+2) ) - 5x/ ( (3x+4) / (2x^2-5) ) + 3')
|
34
|
-
* //
|
35
|
+
* // -20*x^4+28*x^3+104*x^2+6*x-12)/(6*x^2+5*x-4)
|
35
36
|
* math.rationalize('x/(1-x)/(x-2)/(x-3)/(x-4) + 2x/ ( (1-2x)/(2-3x) )/ ((3-4x)/(4-5x) )') =
|
36
|
-
* //
|
37
|
-
* //
|
37
|
+
* // (-30*x^7+344*x^6-1506*x^5+3200*x^4-3472*x^3+1846*x^2-381*x)/
|
38
|
+
* // (-8*x^6+90*x^5-383*x^4+780*x^3-797*x^2+390*x-72)
|
38
39
|
*
|
39
40
|
* math.rationalize('x+x+x+y',{y:1}) // 3*x+1
|
40
41
|
* math.rationalize('x+x+x+y',{}) // 3*x+y
|
41
|
-
*
|
42
|
-
*
|
43
|
-
*
|
44
|
-
*
|
42
|
+
*
|
43
|
+
* const ret = math.rationalize('x+x+x+y',{},true)
|
44
|
+
* // ret.expression=3*x+y, ret.variables = ["x","y"]
|
45
|
+
* const ret = math.rationalize('-2+5x^2',{},true)
|
46
|
+
* // ret.expression=5*x^2-2, ret.variables = ["x"], ret.coefficients=[-2,0,5]
|
45
47
|
*
|
46
48
|
* See also:
|
47
49
|
*
|
@@ -99,33 +101,21 @@ function factory(type, config, load, typed) {
|
|
99
101
|
// If expression in not a constant
|
100
102
|
var setRules = rulesRationalize(); // Rules for change polynomial in near canonical form
|
101
103
|
expr = expandPower(expr); // First expand power of polynomials (cannot be made from rules!)
|
102
|
-
var redoInic = true; // If has change after start, redo the beginning
|
103
|
-
var s = ''; // New expression
|
104
104
|
var sBefore = void 0; // Previous expression
|
105
|
-
var rules = void 0;
|
106
|
-
var eDistrDiv = true;
|
107
|
-
|
108
|
-
expr = simplify(expr, setRules.firstRules); // Apply the initial rules, including succ div rules
|
109
|
-
s = expr.toString();
|
110
105
|
|
111
106
|
while (true) {
|
112
107
|
// Apply alternately successive division rules and distr.div.rules
|
113
|
-
|
114
|
-
expr = simplify(expr,
|
115
|
-
eDistrDiv = !eDistrDiv; // Swap between Distr.Div and Succ. Div. Rules
|
108
|
+
expr = simplify(expr, setRules.firstRules); // Apply the initial rules, including succ div rules
|
109
|
+
expr = simplify(expr, setRules.distrDivRules); // and distr.div.rules until no more changes
|
116
110
|
|
117
|
-
s = expr.toString();
|
111
|
+
var s = expr.toString();
|
118
112
|
if (s === sBefore) break; // No changes : end of the loop
|
119
113
|
|
120
|
-
redoInic = true;
|
121
114
|
sBefore = s;
|
122
115
|
}
|
123
116
|
|
124
|
-
|
125
|
-
|
126
|
-
expr = simplify(expr, setRules.firstRulesAgain);
|
127
|
-
}
|
128
|
-
expr = simplify(expr, setRules.finalRules); // Aplly final rules
|
117
|
+
expr = simplify(expr, setRules.firstRulesAgain);
|
118
|
+
expr = simplify(expr, setRules.finalRules); // Apply final rules
|
129
119
|
} // NVars >= 1
|
130
120
|
|
131
121
|
var coefficients = [];
|
@@ -212,17 +202,23 @@ function factory(type, config, load, typed) {
|
|
212
202
|
var tp = node.type; // node type
|
213
203
|
if (tp === 'FunctionNode') {
|
214
204
|
// No function call in polynomial expression
|
215
|
-
throw new
|
205
|
+
throw new Error('There is an unsolved function call');
|
216
206
|
} else if (tp === 'OperatorNode') {
|
217
207
|
if (node.op === '^' && node.isBinary()) {
|
218
|
-
if (node.args[1].
|
219
|
-
|
208
|
+
if (node.args[1].op === '-' && node.args[1].isUnary()) {
|
209
|
+
if (node.args[1].args[0].type !== 'ConstantNode' || !number.isInteger(parseFloat(node.args[1].args[0].value))) {
|
210
|
+
throw new Error('There is a non-integer exponent');
|
211
|
+
} else {
|
212
|
+
recPoly(node.args[0]);
|
213
|
+
}
|
214
|
+
} else if (node.args[1].type !== 'ConstantNode' || !number.isInteger(parseFloat(node.args[1].value))) {
|
215
|
+
throw new Error('There is a non-integer exponent');
|
220
216
|
} else {
|
221
217
|
recPoly(node.args[0]);
|
222
218
|
}
|
223
219
|
} else {
|
224
220
|
if (oper.indexOf(node.op) === -1) {
|
225
|
-
throw new
|
221
|
+
throw new Error('Operator ' + node.op + ' invalid in polynomial expression');
|
226
222
|
}
|
227
223
|
for (var i = 0; i < node.args.length; i++) {
|
228
224
|
recPoly(node.args[i]);
|
@@ -238,7 +234,7 @@ function factory(type, config, load, typed) {
|
|
238
234
|
} else if (tp === 'ParenthesisNode') {
|
239
235
|
recPoly(node.content);
|
240
236
|
} else if (tp !== 'ConstantNode') {
|
241
|
-
throw new
|
237
|
+
throw new Error('type ' + tp + ' is not allowed in polynomial expression');
|
242
238
|
}
|
243
239
|
} // end of recPoly
|
244
240
|
} // end of polynomial
|
@@ -256,7 +252,7 @@ function factory(type, config, load, typed) {
|
|
256
252
|
function rulesRationalize() {
|
257
253
|
var oldRules = [simplifyCore, // sCore
|
258
254
|
{ l: 'n+n', r: '2*n' }, { l: 'n+-n', r: '0' }, simplifyConstant, // sConstant
|
259
|
-
{ l: 'n*(n1^-1)', r: 'n/n1' }, { l: 'n*n1^-n2', r: 'n/n1^n2' }, { l: 'n1^-1', r: '1/n1' }, { l: 'n*(n1/n2)', r: '(n*n1)/n2' }, { l: '1*n', r: 'n' }];
|
255
|
+
{ l: 'n*(n1^-1)', r: 'n/n1' }, { l: 'n*n1^-n2', r: 'n/n1^n2' }, { l: 'n1^-1', r: '1/n1' }, { l: 'n1^-n2', r: '1/n1^n2' }, { l: 'n*(n1/n2)', r: '(n*n1)/n2' }, { l: '1*n', r: 'n' }];
|
260
256
|
|
261
257
|
var rulesFirst = [{ l: '(-n1)/(-n2)', r: 'n1/n2' }, // Unary division
|
262
258
|
{ l: '(-n1)*(-n2)', r: 'n1*n2' }, // Unary multiplication
|
@@ -513,25 +509,25 @@ function factory(type, config, load, typed) {
|
|
513
509
|
if (tp === 'FunctionNode') {
|
514
510
|
// ***** FunctionName *****
|
515
511
|
// No function call in polynomial expression
|
516
|
-
throw new
|
512
|
+
throw new Error('There is an unsolved function call');
|
517
513
|
} else if (tp === 'OperatorNode') {
|
518
514
|
// ***** OperatorName *****
|
519
|
-
if ('+-*^'.indexOf(node.op) === -1) throw new
|
515
|
+
if ('+-*^'.indexOf(node.op) === -1) throw new Error('Operator ' + node.op + ' invalid');
|
520
516
|
|
521
517
|
if (noPai !== null) {
|
522
518
|
// -(unary),^ : children of *,+,-
|
523
519
|
if ((node.fn === 'unaryMinus' || node.fn === 'pow') && noPai.fn !== 'add' && noPai.fn !== 'subtract' && noPai.fn !== 'multiply') {
|
524
|
-
throw new
|
520
|
+
throw new Error('Invalid ' + node.op + ' placing');
|
525
521
|
}
|
526
522
|
|
527
523
|
// -,+,* : children of +,-
|
528
524
|
if ((node.fn === 'subtract' || node.fn === 'add' || node.fn === 'multiply') && noPai.fn !== 'add' && noPai.fn !== 'subtract') {
|
529
|
-
throw new
|
525
|
+
throw new Error('Invalid ' + node.op + ' placing');
|
530
526
|
}
|
531
527
|
|
532
528
|
// -,+ : first child
|
533
529
|
if ((node.fn === 'subtract' || node.fn === 'add' || node.fn === 'unaryMinus') && o.noFil !== 0) {
|
534
|
-
throw new
|
530
|
+
throw new Error('Invalid ' + node.op + ' placing');
|
535
531
|
}
|
536
532
|
} // Has parent
|
537
533
|
|
@@ -554,7 +550,7 @@ function factory(type, config, load, typed) {
|
|
554
550
|
} else if (tp === 'SymbolNode') {
|
555
551
|
// ***** SymbolName *****
|
556
552
|
if (node.name !== varname && varname !== '') {
|
557
|
-
throw new
|
553
|
+
throw new Error('There is more than one variable');
|
558
554
|
}
|
559
555
|
varname = node.name;
|
560
556
|
if (noPai === null) {
|
@@ -564,12 +560,12 @@ function factory(type, config, load, typed) {
|
|
564
560
|
|
565
561
|
// ^: Symbol is First child
|
566
562
|
if (noPai.op === '^' && o.noFil !== 0) {
|
567
|
-
throw new
|
563
|
+
throw new Error('In power the variable should be the first parameter');
|
568
564
|
}
|
569
565
|
|
570
566
|
// *: Symbol is Second child
|
571
567
|
if (noPai.op === '*' && o.noFil !== 1) {
|
572
|
-
throw new
|
568
|
+
throw new Error('In multiply the variable should be the second parameter');
|
573
569
|
}
|
574
570
|
|
575
571
|
// Symbol: firers '',* => it means there is no exponent above, so it's 1 (cte * var)
|
@@ -586,10 +582,10 @@ function factory(type, config, load, typed) {
|
|
586
582
|
}
|
587
583
|
if (noPai.op === '^') {
|
588
584
|
// cte: second child of power
|
589
|
-
if (o.noFil !== 1) throw new
|
585
|
+
if (o.noFil !== 1) throw new Error('Constant cannot be powered');
|
590
586
|
|
591
587
|
if (!number.isInteger(valor) || valor <= 0) {
|
592
|
-
throw new
|
588
|
+
throw new Error('Non-integer exponent is not allowed');
|
593
589
|
}
|
594
590
|
|
595
591
|
for (var _i2 = maxExpo + 1; _i2 < valor; _i2++) {
|
@@ -606,7 +602,7 @@ function factory(type, config, load, typed) {
|
|
606
602
|
coefficients[0] += o.cte * (o.oper === '+' ? 1 : -1);
|
607
603
|
}
|
608
604
|
} else {
|
609
|
-
throw new
|
605
|
+
throw new Error('Type ' + tp + ' is not allowed');
|
610
606
|
}
|
611
607
|
} // End of recurPol
|
612
608
|
} // End of polyToCanonical
|
@@ -38,7 +38,7 @@ function factory(type, config, load, typed, math) {
|
|
38
38
|
var args = node.args.map(function (arg) {
|
39
39
|
return resolve(arg, scope);
|
40
40
|
});
|
41
|
-
return new OperatorNode(node.op, node.fn, args);
|
41
|
+
return new OperatorNode(node.op, node.fn, args, node.implicit);
|
42
42
|
} else if (type.isParenthesisNode(node)) {
|
43
43
|
return new ParenthesisNode(resolve(node.content, scope));
|
44
44
|
} else if (type.isFunctionNode(node)) {
|
@@ -116,12 +116,12 @@ function factory(type, config, load, typed, math) {
|
|
116
116
|
var a00 = _a.args[0];
|
117
117
|
if (type.isConstantNode(a00)) {
|
118
118
|
var a00a1 = new ConstantNode(multiply(a00.value, a1.value));
|
119
|
-
return new OperatorNode(node.op, node.fn, [a00a1, _a.args[1]]); // constants on left
|
119
|
+
return new OperatorNode(node.op, node.fn, [a00a1, _a.args[1]], node.implicit); // constants on left
|
120
120
|
}
|
121
121
|
}
|
122
|
-
return new OperatorNode(node.op, node.fn, [a1, _a]); // constants on left
|
122
|
+
return new OperatorNode(node.op, node.fn, [a1, _a], node.implicit); // constants on left
|
123
123
|
}
|
124
|
-
return new OperatorNode(node.op, node.fn, [_a, a1]);
|
124
|
+
return new OperatorNode(node.op, node.fn, [_a, a1], node.implicit);
|
125
125
|
} else if (node.op === '/') {
|
126
126
|
if (type.isConstantNode(_a)) {
|
127
127
|
if (isZero(_a.value)) {
|
@@ -127,7 +127,7 @@ function factory(type, config, load, typed, math) {
|
|
127
127
|
if (type.isOperatorNode(node)) {
|
128
128
|
return function (args) {
|
129
129
|
try {
|
130
|
-
return new OperatorNode(node.op, node.fn, args);
|
130
|
+
return new OperatorNode(node.op, node.fn, args, node.implicit);
|
131
131
|
} catch (err) {
|
132
132
|
console.error(err);
|
133
133
|
return [];
|
@@ -336,7 +336,12 @@ function factory(type, config, load, typed, math) {
|
|
336
336
|
// const before = res.toString({parenthesis: 'all'})
|
337
337
|
|
338
338
|
// Create a new node by cloning the rhs of the matched rule
|
339
|
+
// we keep any implicit multiplication state if relevant
|
340
|
+
var implicit = res.implicit;
|
339
341
|
res = repl.clone();
|
342
|
+
if (implicit && 'implicit' in repl) {
|
343
|
+
res.implicit = true;
|
344
|
+
}
|
340
345
|
|
341
346
|
// Replace placeholders with their respective nodes without traversing deeper into the replaced nodes
|
342
347
|
var _transform = function _transform(node) {
|
@@ -1,7 +1,7 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
3
|
var isInteger = require('../../utils/number').isInteger;
|
4
|
-
|
4
|
+
var product = require('./product');
|
5
5
|
function factory(type, config, load, typed) {
|
6
6
|
/**
|
7
7
|
* Compute the number of ways of picking `k` unordered outcomes from `n`
|
@@ -26,11 +26,11 @@ function factory(type, config, load, typed) {
|
|
26
26
|
* @param {number | BigNumber} k Number of objects in the subset
|
27
27
|
* @return {number | BigNumber} Number of possible combinations.
|
28
28
|
*/
|
29
|
+
|
29
30
|
var combinations = typed('combinations', {
|
30
31
|
'number, number': function numberNumber(n, k) {
|
31
|
-
var
|
32
|
-
|
33
|
-
i = void 0;
|
32
|
+
var prodrange = void 0,
|
33
|
+
nMinusk = void 0;
|
34
34
|
|
35
35
|
if (!isInteger(n) || n < 0) {
|
36
36
|
throw new TypeError('Positive integer value expected in function combinations');
|
@@ -42,13 +42,14 @@ function factory(type, config, load, typed) {
|
|
42
42
|
throw new TypeError('k must be less than or equal to n');
|
43
43
|
}
|
44
44
|
|
45
|
-
|
46
|
-
result = 1;
|
47
|
-
for (i = 1; i <= n - max; i++) {
|
48
|
-
result = result * (max + i) / i;
|
49
|
-
}
|
45
|
+
nMinusk = n - k;
|
50
46
|
|
51
|
-
|
47
|
+
if (k < nMinusk) {
|
48
|
+
prodrange = product(nMinusk + 1, n);
|
49
|
+
return prodrange / product(1, k);
|
50
|
+
}
|
51
|
+
prodrange = product(k + 1, n);
|
52
|
+
return prodrange / product(1, nMinusk);
|
52
53
|
},
|
53
54
|
|
54
55
|
'BigNumber, BigNumber': function BigNumberBigNumber(n, k) {
|
@@ -6,7 +6,7 @@ var isInteger = require('../../utils/number').isInteger;
|
|
6
6
|
function factory(type, config, load, typed) {
|
7
7
|
var multiply = load(require('../arithmetic/multiply'));
|
8
8
|
var pow = load(require('../arithmetic/pow'));
|
9
|
-
|
9
|
+
var product = require('./product');
|
10
10
|
/**
|
11
11
|
* Compute the gamma function of a value using Lanczos approximation for
|
12
12
|
* small values, and an extended Stirling approximation for large values.
|
@@ -30,7 +30,9 @@ function factory(type, config, load, typed) {
|
|
30
30
|
* @param {number | Array | Matrix} n A real or complex number
|
31
31
|
* @return {number | Array | Matrix} The gamma of `n`
|
32
32
|
*/
|
33
|
+
|
33
34
|
var gamma = typed('gamma', {
|
35
|
+
|
34
36
|
'number': function number(n) {
|
35
37
|
var t = void 0,
|
36
38
|
x = void 0;
|
@@ -44,18 +46,7 @@ function factory(type, config, load, typed) {
|
|
44
46
|
return Infinity; // Will overflow
|
45
47
|
}
|
46
48
|
|
47
|
-
|
48
|
-
var res = n - 1;
|
49
|
-
while (value > 1) {
|
50
|
-
res *= value;
|
51
|
-
value--;
|
52
|
-
}
|
53
|
-
|
54
|
-
if (res === 0) {
|
55
|
-
res = 1; // 0! is per definition 1
|
56
|
-
}
|
57
|
-
|
58
|
-
return res;
|
49
|
+
return product(1, n - 1);
|
59
50
|
}
|
60
51
|
|
61
52
|
if (n < 0.5) {
|
@@ -150,6 +141,7 @@ function factory(type, config, load, typed) {
|
|
150
141
|
* @param {BigNumber} n
|
151
142
|
* @returns {BigNumber} Returns the factorial of n
|
152
143
|
*/
|
144
|
+
|
153
145
|
function bigFactorial(n) {
|
154
146
|
if (n.isZero()) {
|
155
147
|
return new type.BigNumber(1); // 0! is per definition 1
|
@@ -4,7 +4,7 @@ var isInteger = require('../../utils/number').isInteger;
|
|
4
4
|
|
5
5
|
function factory(type, config, load, typed) {
|
6
6
|
var factorial = load(require('./factorial'));
|
7
|
-
|
7
|
+
var product = require('./product');
|
8
8
|
/**
|
9
9
|
* Compute the number of ways of obtaining an ordered subset of `k` elements
|
10
10
|
* from a set of `n` elements.
|
@@ -32,11 +32,7 @@ function factory(type, config, load, typed) {
|
|
32
32
|
*/
|
33
33
|
var permutations = typed('permutations', {
|
34
34
|
'number | BigNumber': factorial,
|
35
|
-
|
36
35
|
'number, number': function numberNumber(n, k) {
|
37
|
-
var result = void 0,
|
38
|
-
i = void 0;
|
39
|
-
|
40
36
|
if (!isInteger(n) || n < 0) {
|
41
37
|
throw new TypeError('Positive integer value expected in function permutations');
|
42
38
|
}
|
@@ -46,14 +42,8 @@ function factory(type, config, load, typed) {
|
|
46
42
|
if (k > n) {
|
47
43
|
throw new TypeError('second argument k must be less than or equal to first argument n');
|
48
44
|
}
|
49
|
-
|
50
45
|
// Permute n objects, k at a time
|
51
|
-
|
52
|
-
for (i = n - k + 1; i <= n; i++) {
|
53
|
-
result = result * i;
|
54
|
-
}
|
55
|
-
|
56
|
-
return result;
|
46
|
+
return product(n - k + 1, n);
|
57
47
|
},
|
58
48
|
|
59
49
|
'BigNumber, BigNumber': function BigNumberBigNumber(n, k) {
|
@@ -0,0 +1,19 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
/** @param {integer} i
|
4
|
+
* @param {integer} n
|
5
|
+
* @returns : product of i to n
|
6
|
+
*/
|
7
|
+
function product(i, n) {
|
8
|
+
var half = void 0;
|
9
|
+
if (n < i) {
|
10
|
+
return 1;
|
11
|
+
}
|
12
|
+
if (n === i) {
|
13
|
+
return n;
|
14
|
+
}
|
15
|
+
half = n + i >> 1; // divide (n + i) by 2 and truncate to integer
|
16
|
+
return product(i, half) * product(half + 1, n);
|
17
|
+
}
|
18
|
+
|
19
|
+
module.exports = product;
|
@@ -37,8 +37,8 @@ function factory(type, config, load, typed) {
|
|
37
37
|
* For example '123.4' and '1.4e7'.
|
38
38
|
* - `precision: number`
|
39
39
|
* A number between 0 and 16 to round the digits of the number. In case
|
40
|
-
* of notations 'exponential' and 'auto', `precision`
|
41
|
-
* number of significant digits returned.
|
40
|
+
* of notations 'exponential', 'engineering', and 'auto', `precision`
|
41
|
+
* defines the total number of significant digits returned.
|
42
42
|
* In case of notation 'fixed', `precision` defines the number of
|
43
43
|
* significant digits after the decimal point.
|
44
44
|
* `precision` is undefined by default.
|
@@ -31,19 +31,19 @@ function factory(type, config, load, typed) {
|
|
31
31
|
* math.type.Range | `'Range'` | `math.typeof(math.range(0, 10))`
|
32
32
|
* math.type.ResultSet | `'ResultSet'` | `math.typeof(math.eval('a=2\nb=3'))`
|
33
33
|
* math.type.Unit | `'Unit'` | `math.typeof(math.unit('45 deg'))`
|
34
|
-
* math.expression.node
|
35
|
-
* math.expression.node
|
36
|
-
* math.expression.node
|
37
|
-
* math.expression.node
|
38
|
-
* math.expression.node
|
39
|
-
* math.expression.node
|
40
|
-
* math.expression.node
|
41
|
-
* math.expression.node
|
42
|
-
* math.expression.node
|
43
|
-
* math.expression.node
|
44
|
-
* math.expression.node
|
45
|
-
* math.expression.node
|
46
|
-
* math.expression.node
|
34
|
+
* math.expression.node​.AccessorNode | `'AccessorNode'` | `math.typeof(math.parse('A[2]'))`
|
35
|
+
* math.expression.node​.ArrayNode | `'ArrayNode'` | `math.typeof(math.parse('[1,2,3]'))`
|
36
|
+
* math.expression.node​.AssignmentNode | `'AssignmentNode'` | `math.typeof(math.parse('x=2'))`
|
37
|
+
* math.expression.node​.BlockNode | `'BlockNode'` | `math.typeof(math.parse('a=2; b=3'))`
|
38
|
+
* math.expression.node​.ConditionalNode | `'ConditionalNode'` | `math.typeof(math.parse('x<0 ? -x : x'))`
|
39
|
+
* math.expression.node​.ConstantNode | `'ConstantNode'` | `math.typeof(math.parse('2.3'))`
|
40
|
+
* math.expression.node​.FunctionAssignmentNode | `'FunctionAssignmentNode'` | `math.typeof(math.parse('f(x)=x^2'))`
|
41
|
+
* math.expression.node​.FunctionNode | `'FunctionNode'` | `math.typeof(math.parse('sqrt(4)'))`
|
42
|
+
* math.expression.node​.IndexNode | `'IndexNode'` | `math.typeof(math.parse('A[2]').index)`
|
43
|
+
* math.expression.node​.ObjectNode | `'ObjectNode'` | `math.typeof(math.parse('{a:2}'))`
|
44
|
+
* math.expression.node​.ParenthesisNode | `'ParenthesisNode'` | `math.typeof(math.parse('(2+3)'))`
|
45
|
+
* math.expression.node​.RangeNode | `'RangeNode'` | `math.typeof(math.parse('1:10'))`
|
46
|
+
* math.expression.node​.SymbolNode | `'SymbolNode'` | `math.typeof(math.parse('x'))`
|
47
47
|
*
|
48
48
|
* Syntax:
|
49
49
|
*
|
package/lib/index.js
CHANGED
@@ -4,8 +4,12 @@
|
|
4
4
|
|
5
5
|
module.exports = [require('./type'), // data types (Matrix, Complex, Unit, ...)
|
6
6
|
require('./constants'), // constants
|
7
|
-
require('./expression'), // expression parsing
|
8
7
|
require('./function'), // functions
|
8
|
+
|
9
|
+
// load ./expression *after* ./function since we need to
|
10
|
+
// attach transforms to functions that are imported there
|
11
|
+
require('./expression'), // expression parsing
|
12
|
+
|
9
13
|
require('./json'), // serialization utility (math.json.reviver)
|
10
14
|
require('./error') // errors
|
11
15
|
];
|
@@ -1,9 +1,13 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
|
-
var
|
3
|
+
var _decimal = require('decimal.js');
|
4
|
+
|
5
|
+
var _decimal2 = _interopRequireDefault(_decimal);
|
6
|
+
|
7
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
4
8
|
|
5
9
|
function factory(type, config, load, typed, math) {
|
6
|
-
var BigNumber =
|
10
|
+
var BigNumber = _decimal2.default.clone({ precision: config.precision });
|
7
11
|
|
8
12
|
/**
|
9
13
|
* Attach type information
|
package/lib/type/unit/Unit.js
CHANGED
@@ -807,7 +807,7 @@ function factory(type, config, load, typed, math) {
|
|
807
807
|
// other = new Unit(null, valuelessUnit)
|
808
808
|
other = Unit.parse(valuelessUnit);
|
809
809
|
if (!this.equalBase(other)) {
|
810
|
-
throw new Error('Units do not match');
|
810
|
+
throw new Error('Units do not match (\'' + other.toString() + '\' != \'' + this.toString() + '\')');
|
811
811
|
}
|
812
812
|
if (other.value !== null) {
|
813
813
|
throw new Error('Cannot convert to a unit with a value');
|
@@ -819,7 +819,7 @@ function factory(type, config, load, typed, math) {
|
|
819
819
|
return other;
|
820
820
|
} else if (type.isUnit(valuelessUnit)) {
|
821
821
|
if (!this.equalBase(valuelessUnit)) {
|
822
|
-
throw new Error('Units do not match');
|
822
|
+
throw new Error('Units do not match (\'' + valuelessUnit.toString() + '\' != \'' + this.toString() + '\')');
|
823
823
|
}
|
824
824
|
if (valuelessUnit.value !== null) {
|
825
825
|
throw new Error('Cannot convert to a unit with a value');
|
package/lib/utils/array.js
CHANGED
@@ -247,6 +247,15 @@ function reshape(array, sizes) {
|
|
247
247
|
throw new _DimensionError2.default(0, product(exports.size(array)), '!=');
|
248
248
|
}
|
249
249
|
|
250
|
+
var totalSize = 1;
|
251
|
+
for (var sizeIndex = 0; sizeIndex < sizes.length; sizeIndex++) {
|
252
|
+
totalSize *= sizes[sizeIndex];
|
253
|
+
}
|
254
|
+
|
255
|
+
if (flatArray.length !== totalSize) {
|
256
|
+
throw new _DimensionError2.default(product(sizes), product(exports.size(array)), '!=');
|
257
|
+
}
|
258
|
+
|
250
259
|
try {
|
251
260
|
newArray = _reshape(flatArray, sizes);
|
252
261
|
} catch (e) {
|
@@ -256,37 +265,36 @@ function reshape(array, sizes) {
|
|
256
265
|
throw e;
|
257
266
|
}
|
258
267
|
|
259
|
-
if (flatArray.length > 0) {
|
260
|
-
throw new _DimensionError2.default(product(sizes), product(exports.size(array)), '!=');
|
261
|
-
}
|
262
|
-
|
263
268
|
return newArray;
|
264
269
|
}
|
265
270
|
|
266
271
|
/**
|
267
|
-
*
|
272
|
+
* Iteratively re-shape a multi dimensional array to fit the specified dimensions
|
268
273
|
* @param {Array} array Array to be reshaped
|
269
274
|
* @param {Array.<number>} sizes List of sizes for each dimension
|
270
275
|
* @returns {Array} Array whose data has been formatted to fit the
|
271
276
|
* specified dimensions
|
272
|
-
*
|
273
|
-
* @throws {DimensionError} If the product of the new dimension sizes does
|
274
|
-
* not equal that of the old ones
|
275
277
|
*/
|
276
|
-
function _reshape(array, sizes) {
|
277
|
-
var accumulator = [];
|
278
|
-
var i = void 0;
|
279
278
|
|
280
|
-
|
281
|
-
|
282
|
-
|
279
|
+
function _reshape(array, sizes) {
|
280
|
+
// testing if there are enough elements for the requested shape
|
281
|
+
var tmpArray = array;
|
282
|
+
var tmpArray2;
|
283
|
+
// for each dimensions starting by the last one and ignoring the first one
|
284
|
+
for (var sizeIndex = sizes.length - 1; sizeIndex > 0; sizeIndex--) {
|
285
|
+
var size = sizes[sizeIndex];
|
286
|
+
tmpArray2 = [];
|
287
|
+
|
288
|
+
// aggregate the elements of the current tmpArray in elements of the requested size
|
289
|
+
var length = tmpArray.length / size;
|
290
|
+
for (var i = 0; i < length; i++) {
|
291
|
+
tmpArray2.push(tmpArray.slice(i * size, (i + 1) * size));
|
283
292
|
}
|
284
|
-
return
|
293
|
+
// set it as the new tmpArray for the next loop turn or for return
|
294
|
+
tmpArray = tmpArray2;
|
285
295
|
}
|
286
|
-
|
287
|
-
|
288
|
-
}
|
289
|
-
return accumulator;
|
296
|
+
|
297
|
+
return tmpArray;
|
290
298
|
}
|
291
299
|
|
292
300
|
/**
|
@@ -31,8 +31,9 @@ var objectUtils = require('../object');
|
|
31
31
|
* For example '123.4' and '1.4e7'.
|
32
32
|
* {number} precision A number between 0 and 16 to round
|
33
33
|
* the digits of the number.
|
34
|
-
* In case of notations 'exponential'
|
35
|
-
* '
|
34
|
+
* In case of notations 'exponential',
|
35
|
+
* 'engineering', and 'auto',
|
36
|
+
* `precision` defines the total
|
36
37
|
* number of significant digits returned.
|
37
38
|
* In case of notation 'fixed',
|
38
39
|
* `precision` defines the number of
|