mathjs 15.0.0 → 15.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/HISTORY.md +22 -6
  2. package/README.md +1 -1
  3. package/lib/browser/math.js +1 -1
  4. package/lib/browser/math.js.LICENSE.txt +2 -2
  5. package/lib/browser/math.js.map +1 -1
  6. package/lib/cjs/entry/dependenciesAny/dependenciesBernoulli.generated.js +25 -0
  7. package/lib/cjs/entry/dependenciesAny/dependenciesConstantNode.generated.js +2 -0
  8. package/lib/cjs/entry/dependenciesAny/dependenciesEqual.generated.js +0 -2
  9. package/lib/cjs/entry/dependenciesAny/dependenciesIsBounded.generated.js +17 -0
  10. package/lib/cjs/entry/dependenciesAny/dependenciesIsFinite.generated.js +21 -0
  11. package/lib/cjs/entry/dependenciesAny/dependenciesIsInteger.generated.js +2 -0
  12. package/lib/cjs/entry/dependenciesAny/dependenciesSimplifyConstant.generated.js +2 -0
  13. package/lib/cjs/entry/dependenciesAny/dependenciesUnitClass.generated.js +0 -2
  14. package/lib/cjs/entry/dependenciesAny/dependenciesZeta.generated.js +2 -0
  15. package/lib/cjs/entry/dependenciesAny.generated.js +21 -0
  16. package/lib/cjs/entry/dependenciesNumber/dependenciesBernoulli.generated.js +21 -0
  17. package/lib/cjs/entry/dependenciesNumber/dependenciesConstantNode.generated.js +2 -0
  18. package/lib/cjs/entry/dependenciesNumber/dependenciesIsBounded.generated.js +17 -0
  19. package/lib/cjs/entry/dependenciesNumber/dependenciesIsFinite.generated.js +21 -0
  20. package/lib/cjs/entry/dependenciesNumber/dependenciesSimplifyConstant.generated.js +2 -0
  21. package/lib/cjs/entry/dependenciesNumber/dependenciesZeta.generated.js +2 -0
  22. package/lib/cjs/entry/dependenciesNumber.generated.js +21 -0
  23. package/lib/cjs/entry/impureFunctionsAny.generated.js +217 -212
  24. package/lib/cjs/entry/impureFunctionsNumber.generated.js +82 -77
  25. package/lib/cjs/entry/pureFunctionsAny.generated.js +668 -652
  26. package/lib/cjs/entry/pureFunctionsNumber.generated.js +155 -140
  27. package/lib/cjs/expression/embeddedDocs/embeddedDocs.js +6 -0
  28. package/lib/cjs/expression/embeddedDocs/function/combinatorics/stirlingS2.js +2 -2
  29. package/lib/cjs/expression/embeddedDocs/function/probability/bernoulli.js +14 -0
  30. package/lib/cjs/expression/embeddedDocs/function/utils/isBounded.js +14 -0
  31. package/lib/cjs/expression/embeddedDocs/function/utils/isFinite.js +14 -0
  32. package/lib/cjs/expression/embeddedDocs/function/utils/isNaN.js +1 -1
  33. package/lib/cjs/expression/embeddedDocs/function/utils/isNumeric.js +1 -1
  34. package/lib/cjs/expression/node/AccessorNode.js +36 -7
  35. package/lib/cjs/expression/node/ConstantNode.js +4 -4
  36. package/lib/cjs/expression/node/FunctionNode.js +20 -5
  37. package/lib/cjs/expression/parse.js +36 -12
  38. package/lib/cjs/factoriesAny.js +21 -0
  39. package/lib/cjs/factoriesNumber.js +23 -2
  40. package/lib/cjs/function/algebra/simplifyConstant.js +3 -2
  41. package/lib/cjs/function/arithmetic/nthRoots.js +5 -1
  42. package/lib/cjs/function/probability/bernoulli.js +108 -0
  43. package/lib/cjs/function/relational/equal.js +2 -3
  44. package/lib/cjs/function/special/zeta.js +3 -2
  45. package/lib/cjs/function/utils/isBounded.js +54 -0
  46. package/lib/cjs/function/utils/isFinite.js +50 -0
  47. package/lib/cjs/function/utils/isInteger.js +7 -15
  48. package/lib/cjs/function/utils/isNaN.js +1 -1
  49. package/lib/cjs/function/utils/isNumeric.js +1 -1
  50. package/lib/cjs/header.js +2 -2
  51. package/lib/cjs/json/replacer.js +1 -1
  52. package/lib/cjs/plain/number/probability.js +2 -2
  53. package/lib/cjs/plain/number/trigonometry.js +1 -1
  54. package/lib/cjs/type/fraction/function/fraction.js +1 -1
  55. package/lib/cjs/type/matrix/SparseMatrix.js +24 -4
  56. package/lib/cjs/type/unit/Unit.js +12 -8
  57. package/lib/cjs/utils/number.js +7 -7
  58. package/lib/cjs/utils/optimizeCallback.js +13 -1
  59. package/lib/cjs/version.js +1 -1
  60. package/lib/esm/entry/dependenciesAny/dependenciesBernoulli.generated.js +18 -0
  61. package/lib/esm/entry/dependenciesAny/dependenciesConstantNode.generated.js +2 -0
  62. package/lib/esm/entry/dependenciesAny/dependenciesEqual.generated.js +0 -2
  63. package/lib/esm/entry/dependenciesAny/dependenciesIsBounded.generated.js +10 -0
  64. package/lib/esm/entry/dependenciesAny/dependenciesIsFinite.generated.js +14 -0
  65. package/lib/esm/entry/dependenciesAny/dependenciesIsInteger.generated.js +2 -0
  66. package/lib/esm/entry/dependenciesAny/dependenciesSimplifyConstant.generated.js +2 -0
  67. package/lib/esm/entry/dependenciesAny/dependenciesUnitClass.generated.js +0 -2
  68. package/lib/esm/entry/dependenciesAny/dependenciesZeta.generated.js +2 -0
  69. package/lib/esm/entry/dependenciesAny.generated.js +3 -0
  70. package/lib/esm/entry/dependenciesNumber/dependenciesBernoulli.generated.js +14 -0
  71. package/lib/esm/entry/dependenciesNumber/dependenciesConstantNode.generated.js +2 -0
  72. package/lib/esm/entry/dependenciesNumber/dependenciesIsBounded.generated.js +10 -0
  73. package/lib/esm/entry/dependenciesNumber/dependenciesIsFinite.generated.js +14 -0
  74. package/lib/esm/entry/dependenciesNumber/dependenciesSimplifyConstant.generated.js +2 -0
  75. package/lib/esm/entry/dependenciesNumber/dependenciesZeta.generated.js +2 -0
  76. package/lib/esm/entry/dependenciesNumber.generated.js +3 -0
  77. package/lib/esm/entry/impureFunctionsAny.generated.js +219 -214
  78. package/lib/esm/entry/impureFunctionsNumber.generated.js +84 -79
  79. package/lib/esm/entry/pureFunctionsAny.generated.js +665 -649
  80. package/lib/esm/entry/pureFunctionsNumber.generated.js +154 -139
  81. package/lib/esm/expression/embeddedDocs/embeddedDocs.js +6 -0
  82. package/lib/esm/expression/embeddedDocs/function/combinatorics/stirlingS2.js +2 -2
  83. package/lib/esm/expression/embeddedDocs/function/probability/bernoulli.js +8 -0
  84. package/lib/esm/expression/embeddedDocs/function/utils/isBounded.js +8 -0
  85. package/lib/esm/expression/embeddedDocs/function/utils/isFinite.js +8 -0
  86. package/lib/esm/expression/embeddedDocs/function/utils/isNaN.js +1 -1
  87. package/lib/esm/expression/embeddedDocs/function/utils/isNumeric.js +1 -1
  88. package/lib/esm/expression/node/AccessorNode.js +36 -7
  89. package/lib/esm/expression/node/ConstantNode.js +4 -4
  90. package/lib/esm/expression/node/FunctionNode.js +20 -5
  91. package/lib/esm/expression/parse.js +36 -12
  92. package/lib/esm/factoriesAny.js +3 -0
  93. package/lib/esm/factoriesNumber.js +3 -0
  94. package/lib/esm/function/algebra/simplifyConstant.js +3 -2
  95. package/lib/esm/function/arithmetic/nthRoots.js +5 -1
  96. package/lib/esm/function/probability/bernoulli.js +102 -0
  97. package/lib/esm/function/relational/equal.js +2 -3
  98. package/lib/esm/function/special/zeta.js +3 -2
  99. package/lib/esm/function/utils/isBounded.js +48 -0
  100. package/lib/esm/function/utils/isFinite.js +44 -0
  101. package/lib/esm/function/utils/isInteger.js +7 -15
  102. package/lib/esm/function/utils/isNaN.js +1 -1
  103. package/lib/esm/function/utils/isNumeric.js +1 -1
  104. package/lib/esm/json/replacer.js +1 -1
  105. package/lib/esm/plain/number/probability.js +2 -2
  106. package/lib/esm/plain/number/trigonometry.js +1 -1
  107. package/lib/esm/type/fraction/function/fraction.js +1 -1
  108. package/lib/esm/type/matrix/SparseMatrix.js +24 -4
  109. package/lib/esm/type/unit/Unit.js +12 -8
  110. package/lib/esm/utils/number.js +7 -7
  111. package/lib/esm/utils/optimizeCallback.js +13 -1
  112. package/lib/esm/version.js +1 -1
  113. package/package.json +8 -8
  114. package/types/index.d.ts +535 -223
@@ -38,8 +38,13 @@ const createAccessorNode = exports.createAccessorNode = /* #__PURE__ */(0, _fact
38
38
  * @param {Node} object The object from which to retrieve
39
39
  * a property or subset.
40
40
  * @param {IndexNode} index IndexNode containing ranges
41
+ * @param {boolean} [optionalChaining=false]
42
+ * Optional property, if the accessor was written as optional-chaining
43
+ * using `a?.b`, or `a?.["b"] with bracket notation.
44
+ * Forces evaluate to undefined if the given object is undefined or null.
41
45
  */
42
46
  constructor(object, index) {
47
+ let optionalChaining = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
43
48
  super();
44
49
  if (!(0, _is.isNode)(object)) {
45
50
  throw new TypeError('Node expected for parameter "object"');
@@ -49,6 +54,7 @@ const createAccessorNode = exports.createAccessorNode = /* #__PURE__ */(0, _fact
49
54
  }
50
55
  this.object = object;
51
56
  this.index = index;
57
+ this.optionalChaining = optionalChaining;
52
58
  }
53
59
 
54
60
  // readonly property name
@@ -82,15 +88,36 @@ const createAccessorNode = exports.createAccessorNode = /* #__PURE__ */(0, _fact
82
88
  _compile(math, argNames) {
83
89
  const evalObject = this.object._compile(math, argNames);
84
90
  const evalIndex = this.index._compile(math, argNames);
91
+ const optionalChaining = this.optionalChaining;
92
+ const prevOptionalChaining = (0, _is.isAccessorNode)(this.object) && this.object.optionalChaining;
85
93
  if (this.index.isObjectProperty()) {
86
94
  const prop = this.index.getObjectProperty();
87
95
  return function evalAccessorNode(scope, args, context) {
96
+ const ctx = context || {};
97
+ const object = evalObject(scope, args, ctx);
98
+ if (optionalChaining && object == null) {
99
+ ctx.optionalShortCircuit = true;
100
+ return undefined;
101
+ }
102
+ if (prevOptionalChaining && ctx !== null && ctx !== void 0 && ctx.optionalShortCircuit) {
103
+ return undefined;
104
+ }
105
+
88
106
  // get a property from an object evaluated using the scope.
89
- return (0, _customs.getSafeProperty)(evalObject(scope, args, context), prop);
107
+ return (0, _customs.getSafeProperty)(object, prop);
90
108
  };
91
109
  } else {
92
110
  return function evalAccessorNode(scope, args, context) {
93
- const object = evalObject(scope, args, context);
111
+ const ctx = context || {};
112
+ const object = evalObject(scope, args, ctx);
113
+ if (optionalChaining && object == null) {
114
+ ctx.optionalShortCircuit = true;
115
+ return undefined;
116
+ }
117
+ if (prevOptionalChaining && ctx !== null && ctx !== void 0 && ctx.optionalShortCircuit) {
118
+ return undefined;
119
+ }
120
+
94
121
  // we pass just object here instead of context:
95
122
  const index = evalIndex(scope, args, object);
96
123
  return access(object, index);
@@ -114,7 +141,7 @@ const createAccessorNode = exports.createAccessorNode = /* #__PURE__ */(0, _fact
114
141
  * @returns {AccessorNode} Returns a transformed copy of the node
115
142
  */
116
143
  map(callback) {
117
- return new AccessorNode(this._ifNode(callback(this.object, 'object', this)), this._ifNode(callback(this.index, 'index', this)));
144
+ return new AccessorNode(this._ifNode(callback(this.object, 'object', this)), this._ifNode(callback(this.index, 'index', this)), this.optionalChaining);
118
145
  }
119
146
 
120
147
  /**
@@ -122,7 +149,7 @@ const createAccessorNode = exports.createAccessorNode = /* #__PURE__ */(0, _fact
122
149
  * @return {AccessorNode}
123
150
  */
124
151
  clone() {
125
- return new AccessorNode(this.object, this.index);
152
+ return new AccessorNode(this.object, this.index, this.optionalChaining);
126
153
  }
127
154
 
128
155
  /**
@@ -135,7 +162,8 @@ const createAccessorNode = exports.createAccessorNode = /* #__PURE__ */(0, _fact
135
162
  if (needParenthesis(this.object)) {
136
163
  object = '(' + object + ')';
137
164
  }
138
- return object + this.index.toString(options);
165
+ const optionalChaining = this.optionalChaining ? this.index.dotNotation ? '?' : '?.' : '';
166
+ return object + optionalChaining + this.index.toString(options);
139
167
  }
140
168
 
141
169
  /**
@@ -172,7 +200,8 @@ const createAccessorNode = exports.createAccessorNode = /* #__PURE__ */(0, _fact
172
200
  return {
173
201
  mathjs: name,
174
202
  object: this.object,
175
- index: this.index
203
+ index: this.index,
204
+ optionalChaining: this.optionalChaining
176
205
  };
177
206
  }
178
207
 
@@ -185,7 +214,7 @@ const createAccessorNode = exports.createAccessorNode = /* #__PURE__ */(0, _fact
185
214
  * @returns {AccessorNode}
186
215
  */
187
216
  static fromJSON(json) {
188
- return new AccessorNode(json.object, json.index);
217
+ return new AccessorNode(json.object, json.index, json.optionalChaining);
189
218
  }
190
219
  }
191
220
  (0, _defineProperty2.default)(AccessorNode, "name", name);
@@ -11,10 +11,11 @@ var _is = require("../../utils/is.js");
11
11
  var _latex = require("../../utils/latex.js");
12
12
  var _factory = require("../../utils/factory.js");
13
13
  const name = 'ConstantNode';
14
- const dependencies = ['Node'];
14
+ const dependencies = ['Node', 'isBounded'];
15
15
  const createConstantNode = exports.createConstantNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
16
16
  let {
17
- Node
17
+ Node,
18
+ isBounded
18
19
  } = _ref;
19
20
  class ConstantNode extends Node {
20
21
  /**
@@ -157,8 +158,7 @@ const createConstantNode = exports.createConstantNode = /* #__PURE__ */(0, _fact
157
158
  case 'number':
158
159
  case 'BigNumber':
159
160
  {
160
- const finite = type === 'BigNumber' ? this.value.isFinite() : isFinite(this.value);
161
- if (!finite) {
161
+ if (!isBounded(this.value)) {
162
162
  return this.value.valueOf() < 0 ? '-\\infty' : '\\infty';
163
163
  }
164
164
  const index = value.toLowerCase().indexOf('e');
@@ -107,7 +107,7 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
107
107
  * the arguments, typically a SymbolNode or AccessorNode
108
108
  * @param {./Node[]} args
109
109
  */
110
- constructor(fn, args) {
110
+ constructor(fn, args, optional) {
111
111
  super();
112
112
  if (typeof fn === 'string') {
113
113
  fn = new SymbolNode(fn);
@@ -118,8 +118,13 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
118
118
  if (!Array.isArray(args) || !args.every(_is.isNode)) {
119
119
  throw new TypeError('Array containing Nodes expected for parameter "args"');
120
120
  }
121
+ const optionalType = typeof optional;
122
+ if (!(optionalType === 'undefined' || optionalType === 'boolean')) {
123
+ throw new TypeError('optional flag, if specified, must be boolean');
124
+ }
121
125
  this.fn = fn;
122
126
  this.args = args || [];
127
+ this.optional = !!optional;
123
128
  }
124
129
 
125
130
  // readonly property name
@@ -149,6 +154,7 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
149
154
  _compile(math, argNames) {
150
155
  // compile arguments
151
156
  const evalArgs = this.args.map(arg => arg._compile(math, argNames));
157
+ const fromOptionalChaining = this.optional || (0, _is.isAccessorNode)(this.fn) && this.fn.optionalChaining;
152
158
  if ((0, _is.isSymbolNode)(this.fn)) {
153
159
  const name = this.fn.name;
154
160
  if (!argNames[name]) {
@@ -162,10 +168,8 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
162
168
  value = scope.get(name);
163
169
  } else if (name in math) {
164
170
  value = (0, _customs.getSafeProperty)(math, name);
165
- } else {
166
- return FunctionNode.onUndefinedFunction(name);
167
- }
168
- if (typeof value === 'function') {
171
+ } else if (fromOptionalChaining) value = undefined;else return FunctionNode.onUndefinedFunction(name);
172
+ if (typeof value === 'function' || fromOptionalChaining && value === undefined) {
169
173
  return value;
170
174
  }
171
175
  throw new TypeError(`'${name}' is not a function; its value is:\n ${strin(value)}`);
@@ -192,17 +196,20 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
192
196
  case 0:
193
197
  return function evalFunctionNode(scope, args, context) {
194
198
  const fn = resolveFn(scope);
199
+ if (fromOptionalChaining && fn === undefined) return undefined;
195
200
  return fn();
196
201
  };
197
202
  case 1:
198
203
  return function evalFunctionNode(scope, args, context) {
199
204
  const fn = resolveFn(scope);
205
+ if (fromOptionalChaining && fn === undefined) return undefined;
200
206
  const evalArg0 = evalArgs[0];
201
207
  return fn(evalArg0(scope, args, context));
202
208
  };
203
209
  case 2:
204
210
  return function evalFunctionNode(scope, args, context) {
205
211
  const fn = resolveFn(scope);
212
+ if (fromOptionalChaining && fn === undefined) return undefined;
206
213
  const evalArg0 = evalArgs[0];
207
214
  const evalArg1 = evalArgs[1];
208
215
  return fn(evalArg0(scope, args, context), evalArg1(scope, args, context));
@@ -210,6 +217,7 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
210
217
  default:
211
218
  return function evalFunctionNode(scope, args, context) {
212
219
  const fn = resolveFn(scope);
220
+ if (fromOptionalChaining && fn === undefined) return undefined;
213
221
  const values = evalArgs.map(evalArg => evalArg(scope, args, context));
214
222
  return fn(...values);
215
223
  };
@@ -220,6 +228,7 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
220
228
  const rawArgs = this.args;
221
229
  return function evalFunctionNode(scope, args, context) {
222
230
  const fn = (0, _customs.getSafeProperty)(args, name);
231
+ if (fromOptionalChaining && fn === undefined) return undefined;
223
232
  if (typeof fn !== 'function') {
224
233
  throw new TypeError(`Argument '${name}' was not a function; received: ${strin(fn)}`);
225
234
  }
@@ -241,6 +250,11 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
241
250
  const rawArgs = this.args;
242
251
  return function evalFunctionNode(scope, args, context) {
243
252
  const object = evalObject(scope, args, context);
253
+
254
+ // Optional chaining: if the base object is nullish, short-circuit to undefined
255
+ if (fromOptionalChaining && (object == null || object[prop] === undefined)) {
256
+ return undefined;
257
+ }
244
258
  const fn = (0, _customs.getSafeMethod)(object, prop);
245
259
  if (fn !== null && fn !== void 0 && fn.rawArgs) {
246
260
  // "Raw" evaluation
@@ -260,6 +274,7 @@ const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _fact
260
274
  const rawArgs = this.args;
261
275
  return function evalFunctionNode(scope, args, context) {
262
276
  const fn = evalFn(scope, args, context);
277
+ if (fromOptionalChaining && fn === undefined) return undefined;
263
278
  if (typeof fn !== 'function') {
264
279
  throw new TypeError(`Expression '${fnExpr}' did not evaluate to a function; value is:` + `\n ${strin(fn)}`);
265
280
  }
@@ -136,6 +136,7 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
136
136
  '=': true,
137
137
  ':': true,
138
138
  '?': true,
139
+ '?.': true,
139
140
  '??': true,
140
141
  '==': true,
141
142
  '!=': true,
@@ -302,7 +303,9 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
302
303
  }
303
304
 
304
305
  // check for delimiters consisting of 2 characters
305
- if (c2.length === 2 && DELIMITERS[c2]) {
306
+ // Special case: the check for '?.' is to prevent a case like 'a?.3:.7' from being interpreted as optional chaining
307
+ // TODO: refactor the tokenization into some better way to deal with cases like 'a?.3:.7', see https://github.com/josdejong/mathjs/pull/3584
308
+ if (c2.length === 2 && DELIMITERS[c2] && (c2 !== '?.' || !parse.isDigit(state.expression.charAt(state.index + 2)))) {
306
309
  state.tokenType = TOKENTYPE.DELIMITER;
307
310
  state.token = c2;
308
311
  next(state);
@@ -647,6 +650,9 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
647
650
  return new AssignmentNode(new SymbolNode(name), value);
648
651
  } else if ((0, _is.isAccessorNode)(node)) {
649
652
  // parse a matrix subset assignment like 'A[1,2] = 4'
653
+ if (node.optionalChaining) {
654
+ throw createSyntaxError(state, 'Cannot assign to optional chain');
655
+ }
650
656
  getTokenSkipNewline(state);
651
657
  value = parseAssignment(state);
652
658
  return new AssignmentNode(node.object, node.index, value);
@@ -1261,9 +1267,9 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
1261
1267
 
1262
1268
  /**
1263
1269
  * parse accessors:
1264
- * - function invocation in round brackets (...), for example sqrt(2)
1265
- * - index enclosed in square brackets [...], for example A[2,3]
1266
- * - dot notation for properties, like foo.bar
1270
+ * - function invocation in round brackets (...), for example sqrt(2) or sqrt?.(2) with optional chaining
1271
+ * - index enclosed in square brackets [...], for example A[2,3] or A?.[2,3] with optional chaining
1272
+ * - dot notation for properties, like foo.bar or foo?.bar with optional chaining
1267
1273
  * @param {Object} state
1268
1274
  * @param {Node} node Node on which to apply the parameters. If there
1269
1275
  * are no parameters in the expression, the node
@@ -1275,12 +1281,27 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
1275
1281
  */
1276
1282
  function parseAccessors(state, node, types) {
1277
1283
  let params;
1278
- while ((state.token === '(' || state.token === '[' || state.token === '.') && (!types || types.includes(state.token))) {
1284
+
1285
+ // Iterate and handle chained accessors, including repeated optional chaining
1286
+ while (true) {
1279
1287
  // eslint-disable-line no-unmodified-loop-condition
1288
+ // Track whether an optional chaining operator precedes the next accessor
1289
+ let optional = false;
1290
+
1291
+ // Consume an optional chaining operator if present
1292
+ if (state.token === '?.') {
1293
+ optional = true;
1294
+ // consume the '?.' token
1295
+ getToken(state);
1296
+ }
1297
+ const hasNextAccessor = (state.token === '(' || state.token === '[' || state.token === '.') && (!types || types.includes(state.token));
1298
+ if (!(optional || hasNextAccessor)) {
1299
+ break;
1300
+ }
1280
1301
  params = [];
1281
1302
  if (state.token === '(') {
1282
- if ((0, _is.isSymbolNode)(node) || (0, _is.isAccessorNode)(node)) {
1283
- // function invocation like fn(2, 3) or obj.fn(2, 3)
1303
+ if (optional || (0, _is.isSymbolNode)(node) || (0, _is.isAccessorNode)(node)) {
1304
+ // function invocation: fn(2, 3) or obj.fn(2, 3) or (anything)?.(2, 3)
1284
1305
  openParams(state);
1285
1306
  getToken(state);
1286
1307
  if (state.token !== ')') {
@@ -1298,7 +1319,7 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
1298
1319
  }
1299
1320
  closeParams(state);
1300
1321
  getToken(state);
1301
- node = new FunctionNode(node, params);
1322
+ node = new FunctionNode(node, params, optional);
1302
1323
  } else {
1303
1324
  // implicit multiplication like (2+3)(4+5) or sqrt(2)(1+2)
1304
1325
  // don't parse it here but let it be handled by parseImplicitMultiplication
@@ -1324,18 +1345,21 @@ const createParse = exports.createParse = /* #__PURE__ */(0, _factory.factory)(n
1324
1345
  }
1325
1346
  closeParams(state);
1326
1347
  getToken(state);
1327
- node = new AccessorNode(node, new IndexNode(params));
1348
+ node = new AccessorNode(node, new IndexNode(params), optional);
1328
1349
  } else {
1329
1350
  // dot notation like variable.prop
1330
- getToken(state);
1351
+ // consume the `.` (if it was ?., already consumed):
1352
+ if (!optional) getToken(state);
1331
1353
  const isPropertyName = state.tokenType === TOKENTYPE.SYMBOL || state.tokenType === TOKENTYPE.DELIMITER && state.token in NAMED_DELIMITERS;
1332
1354
  if (!isPropertyName) {
1333
- throw createSyntaxError(state, 'Property name expected after dot');
1355
+ let message = 'Property name expected after ';
1356
+ message += optional ? 'optional chain' : 'dot';
1357
+ throw createSyntaxError(state, message);
1334
1358
  }
1335
1359
  params.push(new ConstantNode(state.token));
1336
1360
  getToken(state);
1337
1361
  const dotNotation = true;
1338
- node = new AccessorNode(node, new IndexNode(params, dotNotation));
1362
+ node = new AccessorNode(node, new IndexNode(params, dotNotation), optional);
1339
1363
  }
1340
1364
  }
1341
1365
  return node;
@@ -153,6 +153,12 @@ Object.defineProperty(exports, "createBellNumbers", {
153
153
  return _bellNumbers.createBellNumbers;
154
154
  }
155
155
  });
156
+ Object.defineProperty(exports, "createBernoulli", {
157
+ enumerable: true,
158
+ get: function () {
159
+ return _bernoulli.createBernoulli;
160
+ }
161
+ });
156
162
  Object.defineProperty(exports, "createBigNumberClass", {
157
163
  enumerable: true,
158
164
  get: function () {
@@ -939,6 +945,18 @@ Object.defineProperty(exports, "createInvmod", {
939
945
  return _invmod.createInvmod;
940
946
  }
941
947
  });
948
+ Object.defineProperty(exports, "createIsBounded", {
949
+ enumerable: true,
950
+ get: function () {
951
+ return _isBounded.createIsBounded;
952
+ }
953
+ });
954
+ Object.defineProperty(exports, "createIsFinite", {
955
+ enumerable: true,
956
+ get: function () {
957
+ return _isFinite.createIsFinite;
958
+ }
959
+ });
942
960
  Object.defineProperty(exports, "createIsInteger", {
943
961
  enumerable: true,
944
962
  get: function () {
@@ -2215,6 +2233,8 @@ var _hasNumericValue = require("./function/utils/hasNumericValue.js");
2215
2233
  var _isPositive = require("./function/utils/isPositive.js");
2216
2234
  var _isZero = require("./function/utils/isZero.js");
2217
2235
  var _isNaN = require("./function/utils/isNaN.js");
2236
+ var _isBounded = require("./function/utils/isBounded.js");
2237
+ var _isFinite = require("./function/utils/isFinite.js");
2218
2238
  var _typeOf = require("./function/utils/typeOf.js");
2219
2239
  var _equalScalar = require("./function/relational/equalScalar.js");
2220
2240
  var _SparseMatrix = require("./type/matrix/SparseMatrix.js");
@@ -2443,6 +2463,7 @@ var _variance = require("./function/statistics/variance.js");
2443
2463
  var _quantileSeq = require("./function/statistics/quantileSeq.js");
2444
2464
  var _std = require("./function/statistics/std.js");
2445
2465
  var _corr = require("./function/statistics/corr.js");
2466
+ var _bernoulli = require("./function/probability/bernoulli.js");
2446
2467
  var _combinations = require("./function/probability/combinations.js");
2447
2468
  var _combinationsWithRep = require("./function/probability/combinationsWithRep.js");
2448
2469
  var _gamma = require("./function/probability/gamma.js");
@@ -31,6 +31,12 @@ Object.defineProperty(exports, "createBellNumbers", {
31
31
  return _bellNumbers.createBellNumbers;
32
32
  }
33
33
  });
34
+ Object.defineProperty(exports, "createBernoulli", {
35
+ enumerable: true,
36
+ get: function () {
37
+ return _bernoulli.createBernoulli;
38
+ }
39
+ });
34
40
  Object.defineProperty(exports, "createBigint", {
35
41
  enumerable: true,
36
42
  get: function () {
@@ -303,6 +309,18 @@ Object.defineProperty(exports, "createInfinity", {
303
309
  return _constants.createInfinity;
304
310
  }
305
311
  });
312
+ Object.defineProperty(exports, "createIsBounded", {
313
+ enumerable: true,
314
+ get: function () {
315
+ return _isBounded.createIsBounded;
316
+ }
317
+ });
318
+ Object.defineProperty(exports, "createIsFinite", {
319
+ enumerable: true,
320
+ get: function () {
321
+ return _isFinite.createIsFinite;
322
+ }
323
+ });
306
324
  exports.createIsNegative = exports.createIsNaN = exports.createIsInteger = void 0;
307
325
  Object.defineProperty(exports, "createIsNumeric", {
308
326
  enumerable: true,
@@ -354,8 +372,7 @@ Object.defineProperty(exports, "createLargerEq", {
354
372
  return _largerEq.createLargerEqNumber;
355
373
  }
356
374
  });
357
- exports.createLeftShift = exports.createLcm = void 0;
358
- exports.createLog2 = exports.createLog1p = exports.createLog10 = exports.createLog = exports.createLgamma = void 0;
375
+ exports.createLog2 = exports.createLog1p = exports.createLog10 = exports.createLog = exports.createLgamma = exports.createLeftShift = exports.createLcm = void 0;
359
376
  Object.defineProperty(exports, "createMad", {
360
377
  enumerable: true,
361
378
  get: function () {
@@ -853,6 +870,7 @@ var _map = require("./function/matrix/map.js");
853
870
  var _range = require("./function/matrix/range.js");
854
871
  var _size = require("./function/matrix/size.js");
855
872
  var _partitionSelect = require("./function/matrix/partitionSelect.js");
873
+ var _bernoulli = require("./function/probability/bernoulli.js");
856
874
  var _combinationsWithRep = require("./function/probability/combinationsWithRep.js");
857
875
  var _factorial = require("./function/probability/factorial.js");
858
876
  var _multinomial = require("./function/probability/multinomial.js");
@@ -904,6 +922,8 @@ var _varianceTransform = require("./expression/transform/variance.transform.js")
904
922
  var _clone = require("./function/utils/clone.js");
905
923
  var _isNumeric = require("./function/utils/isNumeric.js");
906
924
  var _hasNumericValue = require("./function/utils/hasNumericValue.js");
925
+ var _isBounded = require("./function/utils/isBounded.js");
926
+ var _isFinite = require("./function/utils/isFinite.js");
907
927
  var _typeOf = require("./function/utils/typeOf.js");
908
928
  var _isPrime = require("./function/utils/isPrime.js");
909
929
  var _numeric = require("./function/utils/numeric.js");
@@ -986,6 +1006,7 @@ const createSubset = exports.createSubset = /* #__PURE__ */(0, _factory.factory)
986
1006
  // TODO: create range implementation for range?
987
1007
 
988
1008
  // probability
1009
+
989
1010
  const createCombinations = exports.createCombinations = createNumberFactory('combinations', _index.combinationsNumber);
990
1011
  const createGamma = exports.createGamma = createNumberFactory('gamma', _index.gammaNumber);
991
1012
  const createLgamma = exports.createLgamma = createNumberFactory('lgamma', _index.lgammaNumber);
@@ -10,13 +10,14 @@ var _number = require("../../utils/number.js");
10
10
  var _util = require("./simplify/util.js");
11
11
  var _noop = require("../../utils/noop.js");
12
12
  const name = 'simplifyConstant';
13
- const dependencies = ['typed', 'config', 'mathWithTransform', 'matrix', '?fraction', '?bignumber', 'AccessorNode', 'ArrayNode', 'ConstantNode', 'FunctionNode', 'IndexNode', 'ObjectNode', 'OperatorNode', 'SymbolNode'];
13
+ const dependencies = ['typed', 'config', 'mathWithTransform', 'matrix', 'isBounded', '?fraction', '?bignumber', 'AccessorNode', 'ArrayNode', 'ConstantNode', 'FunctionNode', 'IndexNode', 'ObjectNode', 'OperatorNode', 'SymbolNode'];
14
14
  const createSimplifyConstant = exports.createSimplifyConstant = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
15
15
  let {
16
16
  typed,
17
17
  config,
18
18
  mathWithTransform,
19
19
  matrix,
20
+ isBounded,
20
21
  fraction,
21
22
  bignumber,
22
23
  AccessorNode,
@@ -134,7 +135,7 @@ const createSimplifyConstant = exports.createSimplifyConstant = /* #__PURE__ */(
134
135
  // and when both numerator and denominator are small enough
135
136
  function _exactFraction(n, options) {
136
137
  const exactFractions = options && options.exactFractions !== false;
137
- if (exactFractions && isFinite(n) && fraction) {
138
+ if (exactFractions && isBounded(n) && fraction) {
138
139
  const f = fraction(n);
139
140
  const fractionsLimit = options && typeof options.fractionsLimit === 'number' ? options.fractionsLimit : Infinity; // no limit by default
140
141
 
@@ -79,7 +79,11 @@ const createNthRoots = exports.createNthRoots = /* #__PURE__ */(0, _factory.fact
79
79
  * Calculate the nth roots of a value.
80
80
  * An nth root of a positive real number A,
81
81
  * is a positive real solution of the equation "x^root = A".
82
- * This function returns an array of complex values.
82
+ * This function returns an array of Complex values.
83
+ * Note that currently the precision of Complex numbers are limited
84
+ * to the precision of a 64-bit IEEE floating point, so even if the input
85
+ * is a BigNumber with greater precision, rounding to 64 bits will occur
86
+ * in computing the nth roots.
83
87
  *
84
88
  * Syntax:
85
89
  *
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createBernoulli = void 0;
7
+ var _factory = require("../../utils/factory.js");
8
+ var _number = require("../../utils/number.js");
9
+ const name = 'bernoulli';
10
+ const dependencies = ['typed', 'config', 'isInteger', 'number', '?BigNumber', '?Fraction'];
11
+ const createBernoulli = exports.createBernoulli = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
12
+ let {
13
+ typed,
14
+ config,
15
+ number,
16
+ BigNumber,
17
+ Fraction
18
+ } = _ref;
19
+ /**
20
+ * Return the `n`th Bernoulli number, for positive integers `n`
21
+ *
22
+ * Syntax:
23
+ *
24
+ * math.bernoulli(n)
25
+ *
26
+ * Examples:
27
+ *
28
+ * math.bernoulli(1) // returns -0.5
29
+ * // All other odd Bernoulli numbers are 0:
30
+ * math.bernoulli(7) // returns 0
31
+ * math.bernoulli(math.bignumber(6)) // value bignumber(1).div(42)
32
+ * // Produces exact rationals for bigint or fraction input:
33
+ * math.bernoulli(8n) // Fraction -1,30
34
+ * math.bernoulli(math.fraction(10)) // Fraction 5,66
35
+ *
36
+ * See also:
37
+ *
38
+ * combinations, gamma, stirlingS2
39
+ *
40
+ * @param {number | BigNumber | bigint | Fraction} n
41
+ * Index of the Bernoulli number
42
+ * @return {number | BigNumber | Fraction}
43
+ * nth Bernoulli number, of a type corresponding to the argument n
44
+ */
45
+
46
+ const numberCache = [undefined];
47
+ const fractionCache = [undefined];
48
+ let bigCache = [undefined];
49
+ let cachedPrecision = 50;
50
+ return typed(name, {
51
+ number: index => _bernoulli(index, n => n, numberCache, (a, b) => a + b, (a, b) => a * b, (a, b) => a / b),
52
+ 'bigint | Fraction': index => _bernoulli(number(index), n => new Fraction(n), fractionCache, (a, b) => a.add(b), (a, b) => a.mul(b), (a, b) => a.div(b)),
53
+ BigNumber: index => {
54
+ if (config.precision !== cachedPrecision) {
55
+ bigCache = [undefined];
56
+ cachedPrecision = config.precision;
57
+ }
58
+ return _bernoulli(number(index), n => new BigNumber(n), bigCache, (a, b) => a.add(b), (a, b) => a.mul(b), (a, b) => a.div(b));
59
+ }
60
+ });
61
+ });
62
+
63
+ /**
64
+ * Underlying implementation, with all operations passed in.
65
+ * Parameters:
66
+ * 1. index: a (positive integer) number specifying which Bernoulli number
67
+ * to compute.
68
+ * 2. promote: a function that takes an integer number and returns
69
+ * the desired type for the Bernoulli number values.
70
+ * 3. A: a cache array of partial computation data that _bernoulli should use.
71
+ * Different cache arrays should be provided for different types.
72
+ * 4. plus: a function that adds two values of the desired type.
73
+ * 5. times: a function that multiplies two values of the desired type.
74
+ * 6. divide: a function that divides one value of the desired type by another.
75
+ */
76
+ function _bernoulli(index, promote, A, plus, times, divide) {
77
+ if (index < 0 || !(0, _number.isInteger)(index)) {
78
+ throw new RangeError('Bernoulli index must be nonnegative integer');
79
+ }
80
+ if (index === 0) return promote(1);
81
+ if (index === 1) return divide(promote(-1), promote(2));
82
+ if (index % 2 === 1) return promote(0);
83
+ // We proceed as in https://math.stackexchange.com/a/2844337
84
+ // (by no means the most efficient, but very simple to implement)
85
+ // A cache entry consists of a triple
86
+ // [cotangent coefficient a_n, prefactor, Bernouilli number B_2n]
87
+ const one = promote(1);
88
+ if (A.length === 1) {
89
+ A.push([divide(one, promote(-3)), divide(one, promote(-2)), divide(one, promote(6))]);
90
+ }
91
+ const half = index / 2;
92
+ const zero = promote(0);
93
+ const two = promote(2);
94
+ while (A.length <= half) {
95
+ const i = A.length; // next cotangent coefficient to compute
96
+ const lim = Math.floor((i + 1) / 2);
97
+ let a = zero;
98
+ for (let m = 1; m < lim; ++m) {
99
+ a = plus(a, times(A[m][0], A[i - m][0]));
100
+ }
101
+ a = times(a, two);
102
+ if (i % 2 === 0) a = plus(a, times(A[lim][0], A[lim][0]));
103
+ a = divide(a, promote(-(2 * i + 1)));
104
+ const prefactor = divide(times(A[i - 1][1], promote(-i * (2 * i - 1))), two);
105
+ A.push([a, prefactor, times(prefactor, a)]);
106
+ }
107
+ return A[half][2];
108
+ }
@@ -10,7 +10,7 @@ var _matAlgo07xSSf = require("../../type/matrix/utils/matAlgo07xSSf.js");
10
10
  var _matAlgo12xSfs = require("../../type/matrix/utils/matAlgo12xSfs.js");
11
11
  var _matrixAlgorithmSuite = require("../../type/matrix/utils/matrixAlgorithmSuite.js");
12
12
  const name = 'equal';
13
- const dependencies = ['typed', 'matrix', 'equalScalar', 'DenseMatrix', 'concat', 'SparseMatrix'];
13
+ const dependencies = ['typed', 'matrix', 'equalScalar', 'DenseMatrix', 'SparseMatrix'];
14
14
  const createEqual = exports.createEqual = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
15
15
  let {
16
16
  typed,
@@ -33,8 +33,7 @@ const createEqual = exports.createEqual = /* #__PURE__ */(0, _factory.factory)(n
33
33
  });
34
34
  const matrixAlgorithmSuite = (0, _matrixAlgorithmSuite.createMatrixAlgorithmSuite)({
35
35
  typed,
36
- matrix,
37
- concat
36
+ matrix
38
37
  });
39
38
 
40
39
  /**
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.createZeta = void 0;
7
7
  var _factory = require("../../utils/factory.js");
8
8
  const name = 'zeta';
9
- const dependencies = ['typed', 'config', 'multiply', 'pow', 'divide', 'factorial', 'equal', 'smallerEq', 'isNegative', 'gamma', 'sin', 'subtract', 'add', '?Complex', '?BigNumber', 'pi'];
9
+ const dependencies = ['typed', 'config', 'multiply', 'pow', 'divide', 'factorial', 'equal', 'smallerEq', 'isBounded', 'isNegative', 'gamma', 'sin', 'subtract', 'add', '?Complex', '?BigNumber', 'pi'];
10
10
  const createZeta = exports.createZeta = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
11
11
  let {
12
12
  typed,
@@ -17,6 +17,7 @@ const createZeta = exports.createZeta = /* #__PURE__ */(0, _factory.factory)(nam
17
17
  factorial,
18
18
  equal,
19
19
  smallerEq,
20
+ isBounded,
20
21
  isNegative,
21
22
  gamma,
22
23
  sin,
@@ -75,7 +76,7 @@ const createZeta = exports.createZeta = /* #__PURE__ */(0, _factory.factory)(nam
75
76
  if (equal(s, 1)) {
76
77
  return createValue(NaN);
77
78
  }
78
- if (!isFinite(s)) {
79
+ if (!isBounded(s)) {
79
80
  return isNegative(s) ? createValue(NaN) : createValue(1);
80
81
  }
81
82
  return zeta(s, createValue, determineDigits, s => s);