mathjs 11.12.0 → 12.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. package/HISTORY.md +39 -2
  2. package/README.md +1 -1
  3. package/lib/browser/math.js +1 -1
  4. package/lib/browser/math.js.LICENSE.txt +1 -1
  5. package/lib/browser/math.js.map +1 -1
  6. package/lib/cjs/entry/dependenciesAny/dependenciesEigs.generated.js +4 -0
  7. package/lib/cjs/entry/pureFunctionsAny.generated.js +2 -0
  8. package/lib/cjs/expression/embeddedDocs/function/matrix/eigs.js +2 -2
  9. package/lib/cjs/expression/node/AssignmentNode.js +1 -1
  10. package/lib/cjs/expression/node/FunctionAssignmentNode.js +1 -1
  11. package/lib/cjs/function/matrix/eigs/complexEigs.js +73 -68
  12. package/lib/cjs/function/matrix/eigs/{realSymetric.js → realSymmetric.js} +57 -51
  13. package/lib/cjs/function/matrix/eigs.js +118 -45
  14. package/lib/cjs/header.js +1 -1
  15. package/lib/cjs/utils/number.js +1 -1
  16. package/lib/cjs/version.js +1 -1
  17. package/lib/esm/entry/dependenciesAny/dependenciesEigs.generated.js +4 -0
  18. package/lib/esm/entry/pureFunctionsAny.generated.js +2 -0
  19. package/lib/esm/expression/embeddedDocs/function/matrix/eigs.js +2 -2
  20. package/lib/esm/expression/node/AssignmentNode.js +1 -1
  21. package/lib/esm/expression/node/FunctionAssignmentNode.js +1 -1
  22. package/lib/esm/function/matrix/eigs/complexEigs.js +73 -68
  23. package/lib/esm/function/matrix/eigs/{realSymetric.js → realSymmetric.js} +55 -51
  24. package/lib/esm/function/matrix/eigs.js +119 -47
  25. package/lib/esm/utils/number.js +1 -1
  26. package/lib/esm/version.js +1 -1
  27. package/package.json +2 -2
  28. package/types/EXPLANATION.md +54 -0
  29. package/types/index.d.ts +6797 -6477
@@ -23,25 +23,29 @@ export function createRealSymmetric(_ref) {
23
23
  function main(arr, N) {
24
24
  var prec = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : config.epsilon;
25
25
  var type = arguments.length > 3 ? arguments[3] : undefined;
26
+ var computeVectors = arguments.length > 4 ? arguments[4] : undefined;
26
27
  if (type === 'number') {
27
- return diag(arr, prec);
28
+ return diag(arr, prec, computeVectors);
28
29
  }
29
30
  if (type === 'BigNumber') {
30
- return diagBig(arr, prec);
31
+ return diagBig(arr, prec, computeVectors);
31
32
  }
32
33
  throw TypeError('Unsupported data type: ' + type);
33
34
  }
34
35
 
35
36
  // diagonalization implementation for number (efficient)
36
- function diag(x, precision) {
37
+ function diag(x, precision, computeVectors) {
37
38
  var N = x.length;
38
39
  var e0 = Math.abs(precision / N);
39
40
  var psi;
40
- var Sij = new Array(N);
41
- // Sij is Identity Matrix
42
- for (var i = 0; i < N; i++) {
43
- Sij[i] = createArray(N, 0);
44
- Sij[i][i] = 1.0;
41
+ var Sij;
42
+ if (computeVectors) {
43
+ Sij = new Array(N);
44
+ // Sij is Identity Matrix
45
+ for (var i = 0; i < N; i++) {
46
+ Sij[i] = Array(N).fill(0);
47
+ Sij[i][i] = 1.0;
48
+ }
45
49
  }
46
50
  // initial error
47
51
  var Vab = getAij(x);
@@ -50,26 +54,29 @@ export function createRealSymmetric(_ref) {
50
54
  var j = Vab[0][1];
51
55
  psi = getTheta(x[_i][_i], x[j][j], x[_i][j]);
52
56
  x = x1(x, psi, _i, j);
53
- Sij = Sij1(Sij, psi, _i, j);
57
+ if (computeVectors) Sij = Sij1(Sij, psi, _i, j);
54
58
  Vab = getAij(x);
55
59
  }
56
- var Ei = createArray(N, 0); // eigenvalues
60
+ var Ei = Array(N).fill(0); // eigenvalues
57
61
  for (var _i2 = 0; _i2 < N; _i2++) {
58
62
  Ei[_i2] = x[_i2][_i2];
59
63
  }
60
- return sorting(clone(Ei), clone(Sij));
64
+ return sorting(clone(Ei), Sij, computeVectors);
61
65
  }
62
66
 
63
67
  // diagonalization implementation for bigNumber
64
- function diagBig(x, precision) {
68
+ function diagBig(x, precision, computeVectors) {
65
69
  var N = x.length;
66
70
  var e0 = abs(precision / N);
67
71
  var psi;
68
- var Sij = new Array(N);
69
- // Sij is Identity Matrix
70
- for (var i = 0; i < N; i++) {
71
- Sij[i] = createArray(N, 0);
72
- Sij[i][i] = 1.0;
72
+ var Sij;
73
+ if (computeVectors) {
74
+ Sij = new Array(N);
75
+ // Sij is Identity Matrix
76
+ for (var i = 0; i < N; i++) {
77
+ Sij[i] = Array(N).fill(0);
78
+ Sij[i][i] = 1.0;
79
+ }
73
80
  }
74
81
  // initial error
75
82
  var Vab = getAijBig(x);
@@ -78,15 +85,15 @@ export function createRealSymmetric(_ref) {
78
85
  var j = Vab[0][1];
79
86
  psi = getThetaBig(x[_i3][_i3], x[j][j], x[_i3][j]);
80
87
  x = x1Big(x, psi, _i3, j);
81
- Sij = Sij1Big(Sij, psi, _i3, j);
88
+ if (computeVectors) Sij = Sij1Big(Sij, psi, _i3, j);
82
89
  Vab = getAijBig(x);
83
90
  }
84
- var Ei = createArray(N, 0); // eigenvalues
91
+ var Ei = Array(N).fill(0); // eigenvalues
85
92
  for (var _i4 = 0; _i4 < N; _i4++) {
86
93
  Ei[_i4] = x[_i4][_i4];
87
94
  }
88
95
  // return [clone(Ei), clone(Sij)]
89
- return sorting(clone(Ei), clone(Sij));
96
+ return sorting(clone(Ei), Sij, computeVectors);
90
97
  }
91
98
 
92
99
  // get angle
@@ -114,8 +121,8 @@ export function createRealSymmetric(_ref) {
114
121
  var N = Sij.length;
115
122
  var c = Math.cos(theta);
116
123
  var s = Math.sin(theta);
117
- var Ski = createArray(N, 0);
118
- var Skj = createArray(N, 0);
124
+ var Ski = Array(N).fill(0);
125
+ var Skj = Array(N).fill(0);
119
126
  for (var k = 0; k < N; k++) {
120
127
  Ski[k] = c * Sij[k][i] - s * Sij[k][j];
121
128
  Skj[k] = s * Sij[k][i] + c * Sij[k][j];
@@ -131,8 +138,8 @@ export function createRealSymmetric(_ref) {
131
138
  var N = Sij.length;
132
139
  var c = cos(theta);
133
140
  var s = sin(theta);
134
- var Ski = createArray(N, bignumber(0));
135
- var Skj = createArray(N, bignumber(0));
141
+ var Ski = Array(N).fill(bignumber(0));
142
+ var Skj = Array(N).fill(bignumber(0));
136
143
  for (var k = 0; k < N; k++) {
137
144
  Ski[k] = subtract(multiplyScalar(c, Sij[k][i]), multiplyScalar(s, Sij[k][j]));
138
145
  Skj[k] = addScalar(multiplyScalar(s, Sij[k][i]), multiplyScalar(c, Sij[k][j]));
@@ -151,8 +158,8 @@ export function createRealSymmetric(_ref) {
151
158
  var s = bignumber(sin(theta));
152
159
  var c2 = multiplyScalar(c, c);
153
160
  var s2 = multiplyScalar(s, s);
154
- var Aki = createArray(N, bignumber(0));
155
- var Akj = createArray(N, bignumber(0));
161
+ var Aki = Array(N).fill(bignumber(0));
162
+ var Akj = Array(N).fill(bignumber(0));
156
163
  // 2cs Hij
157
164
  var csHij = multiply(bignumber(2), c, s, Hij[i][j]);
158
165
  // Aii
@@ -187,8 +194,8 @@ export function createRealSymmetric(_ref) {
187
194
  var s = Math.sin(theta);
188
195
  var c2 = c * c;
189
196
  var s2 = s * s;
190
- var Aki = createArray(N, 0);
191
- var Akj = createArray(N, 0);
197
+ var Aki = Array(N).fill(0);
198
+ var Akj = Array(N).fill(0);
192
199
  // Aii
193
200
  var Aii = c2 * Hij[i][i] - 2 * c * s * Hij[i][j] + s2 * Hij[j][j];
194
201
  var Ajj = s2 * Hij[i][i] + 2 * c * s * Hij[i][j] + c2 * Hij[j][j];
@@ -247,12 +254,15 @@ export function createRealSymmetric(_ref) {
247
254
  }
248
255
 
249
256
  // sort results
250
- function sorting(E, S) {
257
+ function sorting(E, S, computeVectors) {
251
258
  var N = E.length;
252
259
  var values = Array(N);
253
- var vectors = Array(N);
254
- for (var k = 0; k < N; k++) {
255
- vectors[k] = Array(N);
260
+ var vecs;
261
+ if (computeVectors) {
262
+ vecs = Array(N);
263
+ for (var k = 0; k < N; k++) {
264
+ vecs[k] = Array(N);
265
+ }
256
266
  }
257
267
  for (var i = 0; i < N; i++) {
258
268
  var minID = 0;
@@ -264,30 +274,24 @@ export function createRealSymmetric(_ref) {
264
274
  }
265
275
  }
266
276
  values[i] = E.splice(minID, 1)[0];
267
- for (var _k5 = 0; _k5 < N; _k5++) {
268
- vectors[_k5][i] = S[_k5][minID];
269
- S[_k5].splice(minID, 1);
277
+ if (computeVectors) {
278
+ for (var _k5 = 0; _k5 < N; _k5++) {
279
+ vecs[i][_k5] = S[_k5][minID];
280
+ S[_k5].splice(minID, 1);
281
+ }
270
282
  }
271
283
  }
284
+ if (!computeVectors) return {
285
+ values
286
+ };
287
+ var eigenvectors = vecs.map((vector, i) => ({
288
+ value: values[i],
289
+ vector
290
+ }));
272
291
  return {
273
292
  values,
274
- vectors
293
+ eigenvectors
275
294
  };
276
295
  }
277
-
278
- /**
279
- * Create an array of a certain size and fill all items with an initial value
280
- * @param {number} size
281
- * @param {number} value
282
- * @return {number[]}
283
- */
284
- function createArray(size, value) {
285
- // TODO: as soon as all browsers support Array.fill, use that instead (IE doesn't support it)
286
- var array = new Array(size);
287
- for (var i = 0; i < size; i++) {
288
- array[i] = value;
289
- }
290
- return array;
291
- }
292
296
  return main;
293
297
  }
@@ -1,12 +1,13 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
1
2
  import { factory } from '../../utils/factory.js';
2
3
  import { format } from '../../utils/string.js';
3
4
  import { createComplexEigs } from './eigs/complexEigs.js';
4
- import { createRealSymmetric } from './eigs/realSymetric.js';
5
+ import { createRealSymmetric } from './eigs/realSymmetric.js';
5
6
  import { typeOf, isNumber, isBigNumber, isComplex, isFraction } from '../../utils/is.js';
6
7
  var name = 'eigs';
7
8
 
8
9
  // The absolute state of math.js's dependency system:
9
- var dependencies = ['config', 'typed', 'matrix', 'addScalar', 'equal', 'subtract', 'abs', 'atan', 'cos', 'sin', 'multiplyScalar', 'divideScalar', 'inv', 'bignumber', 'multiply', 'add', 'larger', 'column', 'flatten', 'number', 'complex', 'sqrt', 'diag', 'qr', 'usolve', 'usolveAll', 'im', 're', 'smaller', 'matrixFromColumns', 'dot'];
10
+ var dependencies = ['config', 'typed', 'matrix', 'addScalar', 'equal', 'subtract', 'abs', 'atan', 'cos', 'sin', 'multiplyScalar', 'divideScalar', 'inv', 'bignumber', 'multiply', 'add', 'larger', 'column', 'flatten', 'number', 'complex', 'sqrt', 'diag', 'size', 'reshape', 'qr', 'usolve', 'usolveAll', 'im', 're', 'smaller', 'matrixFromColumns', 'dot'];
10
11
  export var createEigs = /* #__PURE__ */factory(name, dependencies, _ref => {
11
12
  var {
12
13
  config,
@@ -32,6 +33,8 @@ export var createEigs = /* #__PURE__ */factory(name, dependencies, _ref => {
32
33
  complex,
33
34
  sqrt,
34
35
  diag,
36
+ size,
37
+ reshape,
35
38
  qr,
36
39
  usolve,
37
40
  usolveAll,
@@ -41,7 +44,7 @@ export var createEigs = /* #__PURE__ */factory(name, dependencies, _ref => {
41
44
  matrixFromColumns,
42
45
  dot
43
46
  } = _ref;
44
- var doRealSymetric = createRealSymmetric({
47
+ var doRealSymmetric = createRealSymmetric({
45
48
  config,
46
49
  addScalar,
47
50
  subtract,
@@ -71,6 +74,8 @@ export var createEigs = /* #__PURE__ */factory(name, dependencies, _ref => {
71
74
  abs,
72
75
  bignumber,
73
76
  diag,
77
+ size,
78
+ reshape,
74
79
  qr,
75
80
  inv,
76
81
  usolve,
@@ -84,26 +89,54 @@ export var createEigs = /* #__PURE__ */factory(name, dependencies, _ref => {
84
89
  });
85
90
 
86
91
  /**
87
- * Compute eigenvalues and eigenvectors of a matrix. The eigenvalues are sorted by their absolute value, ascending.
88
- * An eigenvalue with multiplicity k will be listed k times. The eigenvectors are returned as columns of a matrix
89
- * the eigenvector that belongs to the j-th eigenvalue in the list (eg. `values[j]`) is the j-th column (eg. `column(vectors, j)`).
90
- * If the algorithm fails to converge, it will throw an error – in that case, however, you may still find useful information
92
+ * Compute eigenvalues and optionally eigenvectors of a square matrix.
93
+ * The eigenvalues are sorted by their absolute value, ascending, and
94
+ * returned as a vector in the `values` property of the returned project.
95
+ * An eigenvalue with algebraic multiplicity k will be listed k times, so
96
+ * that the returned `values` vector always has length equal to the size
97
+ * of the input matrix.
98
+ *
99
+ * The `eigenvectors` property of the return value provides the eigenvectors.
100
+ * It is an array of plain objects: the `value` property of each gives the
101
+ * associated eigenvalue, and the `vector` property gives the eigenvector
102
+ * itself. Note that the same `value` property will occur as many times in
103
+ * the list provided by `eigenvectors` as the geometric multiplicity of
104
+ * that value.
105
+ *
106
+ * If the algorithm fails to converge, it will throw an error –
107
+ * in that case, however, you may still find useful information
91
108
  * in `err.values` and `err.vectors`.
92
109
  *
110
+ * Note that the 'precision' option does not directly specify the _accuracy_
111
+ * of the returned eigenvalues. Rather, it determines how small an entry
112
+ * of the iterative approximations to an upper triangular matrix must be
113
+ * in order to be considered zero. The actual accuracy of the returned
114
+ * eigenvalues may be greater or less than the precision, depending on the
115
+ * conditioning of the matrix and how far apart or close the actual
116
+ * eigenvalues are. Note that currently, relatively simple, "traditional"
117
+ * methods of eigenvalue computation are being used; this is not a modern,
118
+ * high-precision eigenvalue computation. That said, it should typically
119
+ * produce fairly reasonable results.
120
+ *
93
121
  * Syntax:
94
122
  *
95
123
  * math.eigs(x, [prec])
124
+ * math.eigs(x, {options})
96
125
  *
97
126
  * Examples:
98
127
  *
99
- * const { eigs, multiply, column, transpose } = math
128
+ * const { eigs, multiply, column, transpose, matrixFromColumns } = math
100
129
  * const H = [[5, 2.3], [2.3, 1]]
101
- * const ans = eigs(H) // returns {values: [E1,E2...sorted], vectors: [v1,v2.... corresponding vectors as columns]}
130
+ * const ans = eigs(H) // returns {values: [E1,E2...sorted], eigenvectors: [{value: E1, vector: v2}, {value: e, vector: v2}, ...]
102
131
  * const E = ans.values
103
- * const U = ans.vectors
104
- * multiply(H, column(U, 0)) // returns multiply(E[0], column(U, 0))
105
- * const UTxHxU = multiply(transpose(U), H, U) // diagonalizes H
106
- * E[0] == UTxHxU[0][0] // returns true
132
+ * const V = ans.eigenvectors
133
+ * multiply(H, V[0].vector)) // returns multiply(E[0], V[0].vector))
134
+ * const U = matrixFromColumns(...V.map(obj => obj.vector))
135
+ * const UTxHxU = multiply(transpose(U), H, U) // diagonalizes H if possible
136
+ * E[0] == UTxHxU[0][0] // returns true always
137
+ *
138
+ * // Compute only approximate eigenvalues:
139
+ * const {values} = eigs(H, {eigenvectors: false, precision: 1e-6})
107
140
  *
108
141
  * See also:
109
142
  *
@@ -111,59 +144,98 @@ export var createEigs = /* #__PURE__ */factory(name, dependencies, _ref => {
111
144
  *
112
145
  * @param {Array | Matrix} x Matrix to be diagonalized
113
146
  *
114
- * @param {number | BigNumber} [prec] Precision, default value: 1e-15
115
- * @return {{values: Array|Matrix, vectors: Array|Matrix}} Object containing an array of eigenvalues and a matrix with eigenvectors as columns.
147
+ * @param {number | BigNumber | OptsObject} [opts] Object with keys `precision`, defaulting to config.epsilon, and `eigenvectors`, defaulting to true and specifying whether to compute eigenvectors. If just a number, specifies precision.
148
+ * @return {{values: Array|Matrix, eigenvectors?: Array<EVobj>}} Object containing an array of eigenvalues and an array of {value: number|BigNumber, vector: Array|Matrix} objects. The eigenvectors property is undefined if eigenvectors were not requested.
116
149
  *
117
150
  */
118
151
  return typed('eigs', {
152
+ // The conversion to matrix in the first two implementations,
153
+ // just to convert back to an array right away in
154
+ // computeValuesAndVectors, is unfortunate, and should perhaps be
155
+ // streamlined. It is done because the Matrix object carries some
156
+ // type information about its entries, and so constructing the matrix
157
+ // is a roundabout way of doing type detection.
119
158
  Array: function Array(x) {
120
- var mat = matrix(x);
121
- return computeValuesAndVectors(mat);
159
+ return doEigs(matrix(x));
122
160
  },
123
161
  'Array, number|BigNumber': function ArrayNumberBigNumber(x, prec) {
124
- var mat = matrix(x);
125
- return computeValuesAndVectors(mat, prec);
162
+ return doEigs(matrix(x), {
163
+ precision: prec
164
+ });
165
+ },
166
+ 'Array, Object'(x, opts) {
167
+ return doEigs(matrix(x), opts);
126
168
  },
127
169
  Matrix: function Matrix(mat) {
128
- var {
129
- values,
130
- vectors
131
- } = computeValuesAndVectors(mat);
132
- return {
133
- values: matrix(values),
134
- vectors: matrix(vectors)
135
- };
170
+ return doEigs(mat, {
171
+ matricize: true
172
+ });
136
173
  },
137
174
  'Matrix, number|BigNumber': function MatrixNumberBigNumber(mat, prec) {
138
- var {
139
- values,
140
- vectors
141
- } = computeValuesAndVectors(mat, prec);
142
- return {
143
- values: matrix(values),
144
- vectors: matrix(vectors)
175
+ return doEigs(mat, {
176
+ precision: prec,
177
+ matricize: true
178
+ });
179
+ },
180
+ 'Matrix, Object': function MatrixObject(mat, opts) {
181
+ var useOpts = {
182
+ matricize: true
145
183
  };
184
+ _extends(useOpts, opts);
185
+ return doEigs(mat, useOpts);
146
186
  }
147
187
  });
148
- function computeValuesAndVectors(mat, prec) {
149
- if (prec === undefined) {
150
- prec = config.epsilon;
188
+ function doEigs(mat) {
189
+ var _opts$precision;
190
+ var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
191
+ var computeVectors = 'eigenvectors' in opts ? opts.eigenvectors : true;
192
+ var prec = (_opts$precision = opts.precision) !== null && _opts$precision !== void 0 ? _opts$precision : config.epsilon;
193
+ var result = computeValuesAndVectors(mat, prec, computeVectors);
194
+ if (opts.matricize) {
195
+ result.values = matrix(result.values);
196
+ if (computeVectors) {
197
+ result.eigenvectors = result.eigenvectors.map(_ref2 => {
198
+ var {
199
+ value,
200
+ vector
201
+ } = _ref2;
202
+ return {
203
+ value,
204
+ vector: matrix(vector)
205
+ };
206
+ });
207
+ }
208
+ }
209
+ if (computeVectors) {
210
+ Object.defineProperty(result, 'vectors', {
211
+ enumerable: false,
212
+ // to make sure that the eigenvectors can still be
213
+ // converted to string.
214
+ get: () => {
215
+ throw new Error('eigs(M).vectors replaced with eigs(M).eigenvectors');
216
+ }
217
+ });
151
218
  }
152
- var size = mat.size();
153
- if (size.length !== 2 || size[0] !== size[1]) {
154
- throw new RangeError('Matrix must be square (size: ' + format(size) + ')');
219
+ return result;
220
+ }
221
+ function computeValuesAndVectors(mat, prec, computeVectors) {
222
+ var arr = mat.toArray(); // NOTE: arr is guaranteed to be unaliased
223
+ // and so safe to modify in place
224
+ var asize = mat.size();
225
+ if (asize.length !== 2 || asize[0] !== asize[1]) {
226
+ throw new RangeError("Matrix must be square (size: ".concat(format(asize), ")"));
155
227
  }
156
- var arr = mat.toArray();
157
- var N = size[0];
228
+ var N = asize[0];
158
229
  if (isReal(arr, N, prec)) {
159
- coerceReal(arr, N);
230
+ coerceReal(arr, N); // modifies arr by side effect
231
+
160
232
  if (isSymmetric(arr, N, prec)) {
161
- var _type = coerceTypes(mat, arr, N);
162
- return doRealSymetric(arr, N, prec, _type);
233
+ var _type = coerceTypes(mat, arr, N); // modifies arr by side effect
234
+ return doRealSymmetric(arr, N, prec, _type, computeVectors);
163
235
  }
164
236
  }
165
- var type = coerceTypes(mat, arr, N);
166
- return doComplexEigs(arr, N, prec, type);
237
+ var type = coerceTypes(mat, arr, N); // modifies arr by side effect
238
+ return doComplexEigs(arr, N, prec, type, computeVectors);
167
239
  }
168
240
 
169
241
  /** @return {boolean} */
@@ -583,7 +583,7 @@ export function nearlyEqual(x, y, epsilon) {
583
583
  if (isFinite(x) && isFinite(y)) {
584
584
  // check numbers are very close, needed when comparing numbers near zero
585
585
  var diff = Math.abs(x - y);
586
- if (diff < DBL_EPSILON) {
586
+ if (diff <= DBL_EPSILON) {
587
587
  return true;
588
588
  } else {
589
589
  // use relative error
@@ -1,3 +1,3 @@
1
- export var version = '11.12.0';
1
+ export var version = '12.0.0';
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": "11.12.0",
3
+ "version": "12.0.0",
4
4
  "description": "Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser with support for symbolic computation, comes with a large set of built-in functions and constants, and offers an integrated solution to work with different data types like numbers, big numbers, complex numbers, fractions, units, and matrices.",
5
5
  "author": "Jos de Jong <wjosdejong@gmail.com> (https://github.com/josdejong)",
6
6
  "homepage": "https://mathjs.org",
@@ -169,7 +169,7 @@
169
169
  "mathjs": "./bin/cli.js"
170
170
  },
171
171
  "engines": {
172
- "node": ">= 14"
172
+ "node": ">= 18"
173
173
  },
174
174
  "bugs": {
175
175
  "url": "https://github.com/josdejong/mathjs/issues"
@@ -0,0 +1,54 @@
1
+ # Mathjs TypeScript types
2
+
3
+ The code base of Mathjs is writting in JavaScript. The TypeScript definitions are maintained separately.
4
+
5
+ ## Library structure
6
+
7
+ The over all structure is:
8
+
9
+ - The library exports the core function `create` which creates a MathJS instance and returns `MathJsInstance`.
10
+ - Mathjs has a special function `chain`, which allows you to use the functions in a chained way, like `chain(2).add(3).done()`. The function `chain` returns an interface `MathJsChain`, which contains all mathjs functions and constants as a method. Unlike the static functions, these methods are defined with the chain instance `this` as first argument.
11
+ - The library exports collections with factory functions of all functions and their dependencies. To create an instance of the function `add`, one can do `create(addDependencies)` for example. To import all functions, one can do `create(all)`.
12
+ - The library also returns a static instance, which can directly be used like `import { add } from 'mathjs'`.
13
+
14
+ ## Defining the types of a new function
15
+
16
+ Maintaining the TypeScript types is done manually. When adding a function, one has to create the following TypeScript definitions:
17
+
18
+ 1. Add a normal definition inside `interface MathJsInstance {...}`
19
+ 2. Add a chained definition inside `interface MathJsChain {...}`
20
+ 3. Add a static definition inside `export const {...} : MathJsInstance`
21
+ 4. Add a dependencies definition inside `export const {...} : Record<string, FactoryFunctionMap>`
22
+
23
+ For exampe for the function `add`, we can have the following definitions:
24
+
25
+ ```ts
26
+ // instance
27
+ export interface MathJsInstance extends MathJsFactory {
28
+ //...
29
+ add<T extends MathType>(x: T, y: T): T
30
+ //...
31
+ }
32
+
33
+ // chain
34
+ export interface MathJsChain<TValue> {
35
+ //...
36
+ add<T extends MathType>(this: MathJsChain<T>, y: T): MathJsChain<T>
37
+ //...
38
+ }
39
+
40
+ // static
41
+ export const {
42
+ // ...
43
+ add,
44
+ // ...
45
+ } : MathJsInstance
46
+
47
+
48
+ // dependencies
49
+ export const {
50
+ // ...
51
+ addDependencies,
52
+ // ...
53
+ } : Record<string, FactoryFunctionMap>
54
+ ```