mathjs 11.12.0 → 12.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 (43) hide show
  1. package/HISTORY.md +54 -2
  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/dependenciesEigs.generated.js +4 -0
  7. package/lib/cjs/entry/pureFunctionsAny.generated.js +2 -0
  8. package/lib/cjs/expression/embeddedDocs/function/arithmetic/round.js +2 -2
  9. package/lib/cjs/expression/embeddedDocs/function/matrix/eigs.js +2 -2
  10. package/lib/cjs/expression/node/AssignmentNode.js +1 -1
  11. package/lib/cjs/expression/node/FunctionAssignmentNode.js +1 -1
  12. package/lib/cjs/function/algebra/derivative.js +8 -31
  13. package/lib/cjs/function/arithmetic/gcd.js +4 -5
  14. package/lib/cjs/function/arithmetic/mod.js +2 -9
  15. package/lib/cjs/function/arithmetic/round.js +59 -16
  16. package/lib/cjs/function/matrix/eigs/complexEigs.js +73 -68
  17. package/lib/cjs/function/matrix/eigs/{realSymetric.js → realSymmetric.js} +57 -51
  18. package/lib/cjs/function/matrix/eigs.js +118 -45
  19. package/lib/cjs/function/probability/pickRandom.js +2 -2
  20. package/lib/cjs/header.js +2 -2
  21. package/lib/cjs/type/number.js +2 -2
  22. package/lib/cjs/utils/number.js +1 -1
  23. package/lib/cjs/utils/snapshot.js +6 -6
  24. package/lib/cjs/version.js +1 -1
  25. package/lib/esm/entry/dependenciesAny/dependenciesEigs.generated.js +4 -0
  26. package/lib/esm/entry/pureFunctionsAny.generated.js +2 -0
  27. package/lib/esm/expression/embeddedDocs/function/arithmetic/round.js +2 -2
  28. package/lib/esm/expression/embeddedDocs/function/matrix/eigs.js +2 -2
  29. package/lib/esm/expression/node/AssignmentNode.js +1 -1
  30. package/lib/esm/expression/node/FunctionAssignmentNode.js +1 -1
  31. package/lib/esm/function/algebra/derivative.js +8 -31
  32. package/lib/esm/function/arithmetic/mod.js +2 -9
  33. package/lib/esm/function/arithmetic/round.js +40 -17
  34. package/lib/esm/function/matrix/eigs/complexEigs.js +73 -68
  35. package/lib/esm/function/matrix/eigs/{realSymetric.js → realSymmetric.js} +55 -51
  36. package/lib/esm/function/matrix/eigs.js +119 -47
  37. package/lib/esm/function/probability/pickRandom.js +2 -2
  38. package/lib/esm/type/number.js +2 -2
  39. package/lib/esm/utils/number.js +1 -1
  40. package/lib/esm/version.js +1 -1
  41. package/package.json +14 -14
  42. package/types/EXPLANATION.md +54 -0
  43. package/types/index.d.ts +6825 -6483
@@ -21,6 +21,8 @@ function createComplexEigs(_ref) {
21
21
  abs = _ref.abs,
22
22
  bignumber = _ref.bignumber,
23
23
  diag = _ref.diag,
24
+ size = _ref.size,
25
+ reshape = _ref.reshape,
24
26
  inv = _ref.inv,
25
27
  qr = _ref.qr,
26
28
  usolve = _ref.usolve,
@@ -40,11 +42,8 @@ function createComplexEigs(_ref) {
40
42
  *
41
43
  * @returns {{ values: number[], vectors: number[][] }}
42
44
  */
43
- function complexEigs(arr, N, prec, type, findVectors) {
44
- if (findVectors === undefined) {
45
- findVectors = true;
46
- }
47
-
45
+ function complexEigs(arr, N, prec, type) {
46
+ var findVectors = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
48
47
  // TODO check if any row/col are zero except the diagonal
49
48
 
50
49
  // make sure corresponding rows and columns have similar magnitude
@@ -53,9 +52,9 @@ function createComplexEigs(_ref) {
53
52
  var R = balance(arr, N, prec, type, findVectors);
54
53
 
55
54
  // R is the row transformation matrix
56
- // arr = A' = R A R⁻¹, A is the original matrix
55
+ // arr = A' = R A R^-1, A is the original matrix
57
56
  // (if findVectors is false, R is undefined)
58
- // (And so to return to original matrix: A = R⁻¹ arr R)
57
+ // (And so to return to original matrix: A = R^-1 arr R)
59
58
 
60
59
  // TODO if magnitudes of elements vary over many orders,
61
60
  // move greatest elements to the top left corner
@@ -65,7 +64,7 @@ function createComplexEigs(_ref) {
65
64
  // updates the transformation matrix R with new row operationsq
66
65
  // MODIFIES arr by side effect!
67
66
  reduceToHessenberg(arr, N, prec, type, findVectors, R);
68
- // still true that original A = R⁻¹ arr R)
67
+ // still true that original A = R^-1 arr R)
69
68
 
70
69
  // find eigenvalues
71
70
  var _iterateUntilTriangul = iterateUntilTriangular(arr, N, prec, type, findVectors),
@@ -75,17 +74,18 @@ function createComplexEigs(_ref) {
75
74
  // values is the list of eigenvalues, C is the column
76
75
  // transformation matrix that transforms arr, the hessenberg
77
76
  // matrix, to upper triangular
78
- // (So U = C⁻¹ arr C and the relationship between current arr
77
+ // (So U = C^-1 arr C and the relationship between current arr
79
78
  // and original A is unchanged.)
80
79
 
81
- var vectors;
82
80
  if (findVectors) {
83
- vectors = findEigenvectors(arr, N, C, R, values, prec, type);
84
- vectors = matrixFromColumns.apply(void 0, (0, _toConsumableArray2["default"])(vectors));
81
+ var eigenvectors = findEigenvectors(arr, N, C, R, values, prec, type);
82
+ return {
83
+ values: values,
84
+ eigenvectors: eigenvectors
85
+ };
85
86
  }
86
87
  return {
87
- values: values,
88
- vectors: vectors
88
+ values: values
89
89
  };
90
90
  }
91
91
 
@@ -125,9 +125,8 @@ function createComplexEigs(_ref) {
125
125
  var rowNorm = realzero;
126
126
  for (var j = 0; j < N; j++) {
127
127
  if (i === j) continue;
128
- var c = abs(arr[i][j]); // should be real
129
- colNorm = addScalar(colNorm, c);
130
- rowNorm = addScalar(rowNorm, c);
128
+ colNorm = addScalar(colNorm, abs(arr[j][i]));
129
+ rowNorm = addScalar(rowNorm, abs(arr[i][j]));
131
130
  }
132
131
  if (!equal(colNorm, 0) && !equal(rowNorm, 0)) {
133
132
  // find integer power closest to balancing the matrix
@@ -135,21 +134,21 @@ function createComplexEigs(_ref) {
135
134
  // so that we don't lose any precision due to round-off)
136
135
 
137
136
  var f = realone;
138
- var _c = colNorm;
137
+ var c = colNorm;
139
138
  var rowDivRadix = divideScalar(rowNorm, radix);
140
139
  var rowMulRadix = multiplyScalar(rowNorm, radix);
141
- while (smaller(_c, rowDivRadix)) {
142
- _c = multiplyScalar(_c, radixSq);
140
+ while (smaller(c, rowDivRadix)) {
141
+ c = multiplyScalar(c, radixSq);
143
142
  f = multiplyScalar(f, radix);
144
143
  }
145
- while (larger(_c, rowMulRadix)) {
146
- _c = divideScalar(_c, radixSq);
144
+ while (larger(c, rowMulRadix)) {
145
+ c = divideScalar(c, radixSq);
147
146
  f = divideScalar(f, radix);
148
147
  }
149
148
 
150
149
  // check whether balancing is needed
151
150
  // condition = (c + rowNorm) / f < 0.95 * (colNorm + rowNorm)
152
- var condition = smaller(divideScalar(addScalar(_c, rowNorm), f), multiplyScalar(addScalar(colNorm, rowNorm), 0.95));
151
+ var condition = smaller(divideScalar(addScalar(c, rowNorm), f), multiplyScalar(addScalar(colNorm, rowNorm), 0.95));
153
152
 
154
153
  // apply balancing similarity transformation
155
154
  if (condition) {
@@ -161,13 +160,13 @@ function createComplexEigs(_ref) {
161
160
  if (i === _j) {
162
161
  continue;
163
162
  }
164
- arr[i][_j] = multiplyScalar(arr[i][_j], f);
165
- arr[_j][i] = multiplyScalar(arr[_j][i], g);
163
+ arr[i][_j] = multiplyScalar(arr[i][_j], g);
164
+ arr[_j][i] = multiplyScalar(arr[_j][i], f);
166
165
  }
167
166
 
168
167
  // keep track of transformations
169
168
  if (findVectors) {
170
- Rdiag[i] = multiplyScalar(Rdiag[i], f);
169
+ Rdiag[i] = multiplyScalar(Rdiag[i], g);
171
170
  }
172
171
  }
173
172
  }
@@ -175,7 +174,7 @@ function createComplexEigs(_ref) {
175
174
  }
176
175
 
177
176
  // return the diagonal row transformation matrix
178
- return diag(Rdiag);
177
+ return findVectors ? diag(Rdiag) : null;
179
178
  }
180
179
 
181
180
  /**
@@ -274,7 +273,7 @@ function createComplexEigs(_ref) {
274
273
 
275
274
  // The Francis Algorithm
276
275
  // The core idea of this algorithm is that doing successive
277
- // A' = Q⁺AQ transformations will eventually converge to block-
276
+ // A' = QtAQ transformations will eventually converge to block-
278
277
  // upper-triangular with diagonal blocks either 1x1 or 2x2.
279
278
  // The Q here is the one from the QR decomposition, A = QR.
280
279
  // Since the eigenvalues of a block-upper-triangular matrix are
@@ -296,7 +295,7 @@ function createComplexEigs(_ref) {
296
295
  // N×N matrix describing the overall transformation done during the QR algorithm
297
296
  var Qtotal = findVectors ? diag(Array(N).fill(one)) : undefined;
298
297
 
299
- // n×n matrix describing the QR transformations done since last convergence
298
+ // nxn matrix describing the QR transformations done since last convergence
300
299
  var Qpartial = findVectors ? diag(Array(n).fill(one)) : undefined;
301
300
 
302
301
  // last eigenvalue converged before this many steps
@@ -308,7 +307,12 @@ function createComplexEigs(_ref) {
308
307
 
309
308
  // Perform the factorization
310
309
 
311
- var k = 0; // TODO set close to an eigenvalue
310
+ var k = arr[n - 1][n - 1]; // TODO this is apparently a somewhat
311
+ // old-fashioned choice; ideally set close to an eigenvalue, or
312
+ // perhaps better yet switch to the implicit QR version that is sometimes
313
+ // specifically called the "Francis algorithm" that is alluded to
314
+ // in the following TODO. (Or perhaps we switch to an independently
315
+ // optimized third-party package for the linear algebra operations...)
312
316
 
313
317
  for (var i = 0; i < n; i++) {
314
318
  arr[i][i] = subtract(arr[i][i], k);
@@ -427,17 +431,17 @@ function createComplexEigs(_ref) {
427
431
  _step;
428
432
  try {
429
433
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
430
- var λ = _step.value;
431
- var _i4 = indexOf(uniqueValues, λ, equal);
434
+ var lambda = _step.value;
435
+ var _i4 = indexOf(uniqueValues, lambda, equal);
432
436
  if (_i4 === -1) {
433
- uniqueValues.push(λ);
437
+ uniqueValues.push(lambda);
434
438
  multiplicities.push(1);
435
439
  } else {
436
440
  multiplicities[_i4] += 1;
437
441
  }
438
442
  }
439
443
 
440
- // find eigenvectors by solving U − λE = 0
444
+ // find eigenvectors by solving U − lambdaE = 0
441
445
  // TODO replace with an iterative eigenvector algorithm
442
446
  // (this one might fail for imprecise eigenvalues)
443
447
  } catch (err) {
@@ -449,24 +453,21 @@ function createComplexEigs(_ref) {
449
453
  var len = uniqueValues.length;
450
454
  var b = Array(N).fill(zero);
451
455
  var E = diag(Array(N).fill(one));
452
-
453
- // eigenvalues for which usolve failed (due to numerical error)
454
- var failedLambdas = [];
455
456
  var _loop = function _loop() {
456
- var λ = uniqueValues[i];
457
- var S = subtract(U, multiply(λ, E)); // the characteristic matrix
457
+ var lambda = uniqueValues[i];
458
+ var S = subtract(U, multiply(lambda, E)); // the characteristic matrix
458
459
 
459
460
  var solutions = usolveAll(S, b);
460
461
  solutions.shift(); // ignore the null vector
461
462
 
462
463
  // looks like we missed something, try inverse iteration
464
+ // But if that fails, just presume that the original matrix truly
465
+ // was defective.
463
466
  while (solutions.length < multiplicities[i]) {
464
467
  var approxVec = inverseIterate(S, N, solutions, prec, type);
465
- if (approxVec == null) {
466
- // no more vectors were found
467
- failedLambdas.push(λ);
468
+ if (approxVec === null) {
468
469
  break;
469
- }
470
+ } // no more vectors were found
470
471
  solutions.push(approxVec);
471
472
  }
472
473
 
@@ -476,18 +477,15 @@ function createComplexEigs(_ref) {
476
477
  return multiply(correction, v);
477
478
  });
478
479
  vectors.push.apply(vectors, (0, _toConsumableArray2["default"])(solutions.map(function (v) {
479
- return flatten(v);
480
+ return {
481
+ value: lambda,
482
+ vector: flatten(v)
483
+ };
480
484
  })));
481
485
  };
482
486
  for (var i = 0; i < len; i++) {
483
487
  _loop();
484
488
  }
485
- if (failedLambdas.length !== 0) {
486
- var err = new Error('Failed to find eigenvectors for the following eigenvalues: ' + failedLambdas.join(', '));
487
- err.values = values;
488
- err.vectors = vectors;
489
- throw err;
490
- }
491
489
  return vectors;
492
490
  }
493
491
 
@@ -496,7 +494,7 @@ function createComplexEigs(_ref) {
496
494
  * @return {[number,number]}
497
495
  */
498
496
  function eigenvalues2x2(a, b, c, d) {
499
- // λ± = ½ trA ± ½ ( tr²A - 4 detA )
497
+ // lambda_+- = 1/2 trA +- 1/2 sqrt( tr^2 A - 4 detA )
500
498
  var trA = addScalar(a, d);
501
499
  var detA = subtract(multiplyScalar(a, d), multiplyScalar(b, c));
502
500
  var x = multiplyScalar(trA, 0.5);
@@ -506,7 +504,7 @@ function createComplexEigs(_ref) {
506
504
 
507
505
  /**
508
506
  * For an 2x2 matrix compute the transformation matrix S,
509
- * so that SAS⁻¹ is an upper triangular matrix
507
+ * so that SAS^-1 is an upper triangular matrix
510
508
  * @return {[[number,number],[number,number]]}
511
509
  * @see https://math.berkeley.edu/~ogus/old/Math_54-05/webfoils/jordan.pdf
512
510
  * @see http://people.math.harvard.edu/~knill/teaching/math21b2004/exhibits/2dmatrices/index.html
@@ -530,23 +528,22 @@ function createComplexEigs(_ref) {
530
528
  }
531
529
 
532
530
  // matrix is not diagonalizable
533
- // compute off-diagonal elements of N = A - λI
534
- // N₁₂ = 0 ⇒ S = ( N⃗₁, I⃗₁ )
535
- // N₁₂ ≠ 0 ⇒ S = ( N⃗₂, I⃗₂ )
536
-
531
+ // compute diagonal elements of N = A - lambdaI
537
532
  var na = subtract(a, l1);
538
- var nb = subtract(b, l1);
539
- var nc = subtract(c, l1);
540
533
  var nd = subtract(d, l1);
541
- if (smaller(abs(nb), prec)) {
542
- return [[na, one], [nc, zero]];
534
+
535
+ // col(N,2) = 0 implies S = ( col(N,1), e_1 )
536
+ // col(N,2) != 0 implies S = ( col(N,2), e_2 )
537
+
538
+ if (smaller(abs(b), prec) && smaller(abs(nd), prec)) {
539
+ return [[na, one], [c, zero]];
543
540
  } else {
544
- return [[nb, zero], [nd, one]];
541
+ return [[b, zero], [nd, one]];
545
542
  }
546
543
  }
547
544
 
548
545
  /**
549
- * Enlarge the matrix from n×n to N×N, setting the new
546
+ * Enlarge the matrix from nxn to NxN, setting the new
550
547
  * elements to 1 on diagonal and 0 elsewhere
551
548
  */
552
549
  function inflateMatrix(arr, N) {
@@ -633,15 +630,21 @@ function createComplexEigs(_ref) {
633
630
 
634
631
  // you better choose a random vector before I count to five
635
632
  var i = 0;
636
- while (true) {
633
+ for (; i < 5; ++i) {
637
634
  b = randomOrthogonalVector(N, orthog, type);
638
- b = usolve(A, b);
635
+ try {
636
+ b = usolve(A, b);
637
+ } catch (_unused) {
638
+ // That direction didn't work, likely because the original matrix
639
+ // was defective. But still make the full number of tries...
640
+ continue;
641
+ }
639
642
  if (larger(norm(b), largeNum)) {
640
643
  break;
641
644
  }
642
- if (++i >= 5) {
643
- return null;
644
- }
645
+ }
646
+ if (i >= 5) {
647
+ return null; // couldn't find any orthogonal vector in the image
645
648
  }
646
649
 
647
650
  // you better converge before I count to ten
@@ -697,12 +700,14 @@ function createComplexEigs(_ref) {
697
700
  * Project vector v to the orthogonal complement of an array of vectors
698
701
  */
699
702
  function orthogonalComplement(v, orthog) {
703
+ var vectorShape = size(v);
700
704
  var _iterator3 = _createForOfIteratorHelper(orthog),
701
705
  _step3;
702
706
  try {
703
707
  for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
704
708
  var w = _step3.value;
705
- // v := v − (w, v)/∥w∥² w
709
+ w = reshape(w, vectorShape); // make sure this is just a vector computation
710
+ // v := v − (w, v)/|w|^2 w
706
711
  v = subtract(v, multiply(divideScalar(dot(w, v), dot(w, w)), w));
707
712
  }
708
713
  } catch (err) {
@@ -27,25 +27,29 @@ function createRealSymmetric(_ref) {
27
27
  function main(arr, N) {
28
28
  var prec = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : config.epsilon;
29
29
  var type = arguments.length > 3 ? arguments[3] : undefined;
30
+ var computeVectors = arguments.length > 4 ? arguments[4] : undefined;
30
31
  if (type === 'number') {
31
- return diag(arr, prec);
32
+ return diag(arr, prec, computeVectors);
32
33
  }
33
34
  if (type === 'BigNumber') {
34
- return diagBig(arr, prec);
35
+ return diagBig(arr, prec, computeVectors);
35
36
  }
36
37
  throw TypeError('Unsupported data type: ' + type);
37
38
  }
38
39
 
39
40
  // diagonalization implementation for number (efficient)
40
- function diag(x, precision) {
41
+ function diag(x, precision, computeVectors) {
41
42
  var N = x.length;
42
43
  var e0 = Math.abs(precision / N);
43
44
  var psi;
44
- var Sij = new Array(N);
45
- // Sij is Identity Matrix
46
- for (var i = 0; i < N; i++) {
47
- Sij[i] = createArray(N, 0);
48
- Sij[i][i] = 1.0;
45
+ var Sij;
46
+ if (computeVectors) {
47
+ Sij = new Array(N);
48
+ // Sij is Identity Matrix
49
+ for (var i = 0; i < N; i++) {
50
+ Sij[i] = Array(N).fill(0);
51
+ Sij[i][i] = 1.0;
52
+ }
49
53
  }
50
54
  // initial error
51
55
  var Vab = getAij(x);
@@ -54,26 +58,29 @@ function createRealSymmetric(_ref) {
54
58
  var j = Vab[0][1];
55
59
  psi = getTheta(x[_i][_i], x[j][j], x[_i][j]);
56
60
  x = x1(x, psi, _i, j);
57
- Sij = Sij1(Sij, psi, _i, j);
61
+ if (computeVectors) Sij = Sij1(Sij, psi, _i, j);
58
62
  Vab = getAij(x);
59
63
  }
60
- var Ei = createArray(N, 0); // eigenvalues
64
+ var Ei = Array(N).fill(0); // eigenvalues
61
65
  for (var _i2 = 0; _i2 < N; _i2++) {
62
66
  Ei[_i2] = x[_i2][_i2];
63
67
  }
64
- return sorting((0, _object.clone)(Ei), (0, _object.clone)(Sij));
68
+ return sorting((0, _object.clone)(Ei), Sij, computeVectors);
65
69
  }
66
70
 
67
71
  // diagonalization implementation for bigNumber
68
- function diagBig(x, precision) {
72
+ function diagBig(x, precision, computeVectors) {
69
73
  var N = x.length;
70
74
  var e0 = abs(precision / N);
71
75
  var psi;
72
- var Sij = new Array(N);
73
- // Sij is Identity Matrix
74
- for (var i = 0; i < N; i++) {
75
- Sij[i] = createArray(N, 0);
76
- Sij[i][i] = 1.0;
76
+ var Sij;
77
+ if (computeVectors) {
78
+ Sij = new Array(N);
79
+ // Sij is Identity Matrix
80
+ for (var i = 0; i < N; i++) {
81
+ Sij[i] = Array(N).fill(0);
82
+ Sij[i][i] = 1.0;
83
+ }
77
84
  }
78
85
  // initial error
79
86
  var Vab = getAijBig(x);
@@ -82,15 +89,15 @@ function createRealSymmetric(_ref) {
82
89
  var j = Vab[0][1];
83
90
  psi = getThetaBig(x[_i3][_i3], x[j][j], x[_i3][j]);
84
91
  x = x1Big(x, psi, _i3, j);
85
- Sij = Sij1Big(Sij, psi, _i3, j);
92
+ if (computeVectors) Sij = Sij1Big(Sij, psi, _i3, j);
86
93
  Vab = getAijBig(x);
87
94
  }
88
- var Ei = createArray(N, 0); // eigenvalues
95
+ var Ei = Array(N).fill(0); // eigenvalues
89
96
  for (var _i4 = 0; _i4 < N; _i4++) {
90
97
  Ei[_i4] = x[_i4][_i4];
91
98
  }
92
99
  // return [clone(Ei), clone(Sij)]
93
- return sorting((0, _object.clone)(Ei), (0, _object.clone)(Sij));
100
+ return sorting((0, _object.clone)(Ei), Sij, computeVectors);
94
101
  }
95
102
 
96
103
  // get angle
@@ -118,8 +125,8 @@ function createRealSymmetric(_ref) {
118
125
  var N = Sij.length;
119
126
  var c = Math.cos(theta);
120
127
  var s = Math.sin(theta);
121
- var Ski = createArray(N, 0);
122
- var Skj = createArray(N, 0);
128
+ var Ski = Array(N).fill(0);
129
+ var Skj = Array(N).fill(0);
123
130
  for (var k = 0; k < N; k++) {
124
131
  Ski[k] = c * Sij[k][i] - s * Sij[k][j];
125
132
  Skj[k] = s * Sij[k][i] + c * Sij[k][j];
@@ -135,8 +142,8 @@ function createRealSymmetric(_ref) {
135
142
  var N = Sij.length;
136
143
  var c = cos(theta);
137
144
  var s = sin(theta);
138
- var Ski = createArray(N, bignumber(0));
139
- var Skj = createArray(N, bignumber(0));
145
+ var Ski = Array(N).fill(bignumber(0));
146
+ var Skj = Array(N).fill(bignumber(0));
140
147
  for (var k = 0; k < N; k++) {
141
148
  Ski[k] = subtract(multiplyScalar(c, Sij[k][i]), multiplyScalar(s, Sij[k][j]));
142
149
  Skj[k] = addScalar(multiplyScalar(s, Sij[k][i]), multiplyScalar(c, Sij[k][j]));
@@ -155,8 +162,8 @@ function createRealSymmetric(_ref) {
155
162
  var s = bignumber(sin(theta));
156
163
  var c2 = multiplyScalar(c, c);
157
164
  var s2 = multiplyScalar(s, s);
158
- var Aki = createArray(N, bignumber(0));
159
- var Akj = createArray(N, bignumber(0));
165
+ var Aki = Array(N).fill(bignumber(0));
166
+ var Akj = Array(N).fill(bignumber(0));
160
167
  // 2cs Hij
161
168
  var csHij = multiply(bignumber(2), c, s, Hij[i][j]);
162
169
  // Aii
@@ -191,8 +198,8 @@ function createRealSymmetric(_ref) {
191
198
  var s = Math.sin(theta);
192
199
  var c2 = c * c;
193
200
  var s2 = s * s;
194
- var Aki = createArray(N, 0);
195
- var Akj = createArray(N, 0);
201
+ var Aki = Array(N).fill(0);
202
+ var Akj = Array(N).fill(0);
196
203
  // Aii
197
204
  var Aii = c2 * Hij[i][i] - 2 * c * s * Hij[i][j] + s2 * Hij[j][j];
198
205
  var Ajj = s2 * Hij[i][i] + 2 * c * s * Hij[i][j] + c2 * Hij[j][j];
@@ -251,12 +258,15 @@ function createRealSymmetric(_ref) {
251
258
  }
252
259
 
253
260
  // sort results
254
- function sorting(E, S) {
261
+ function sorting(E, S, computeVectors) {
255
262
  var N = E.length;
256
263
  var values = Array(N);
257
- var vectors = Array(N);
258
- for (var k = 0; k < N; k++) {
259
- vectors[k] = Array(N);
264
+ var vecs;
265
+ if (computeVectors) {
266
+ vecs = Array(N);
267
+ for (var k = 0; k < N; k++) {
268
+ vecs[k] = Array(N);
269
+ }
260
270
  }
261
271
  for (var i = 0; i < N; i++) {
262
272
  var minID = 0;
@@ -268,30 +278,26 @@ function createRealSymmetric(_ref) {
268
278
  }
269
279
  }
270
280
  values[i] = E.splice(minID, 1)[0];
271
- for (var _k5 = 0; _k5 < N; _k5++) {
272
- vectors[_k5][i] = S[_k5][minID];
273
- S[_k5].splice(minID, 1);
281
+ if (computeVectors) {
282
+ for (var _k5 = 0; _k5 < N; _k5++) {
283
+ vecs[i][_k5] = S[_k5][minID];
284
+ S[_k5].splice(minID, 1);
285
+ }
274
286
  }
275
287
  }
288
+ if (!computeVectors) return {
289
+ values: values
290
+ };
291
+ var eigenvectors = vecs.map(function (vector, i) {
292
+ return {
293
+ value: values[i],
294
+ vector: vector
295
+ };
296
+ });
276
297
  return {
277
298
  values: values,
278
- vectors: vectors
299
+ eigenvectors: eigenvectors
279
300
  };
280
301
  }
281
-
282
- /**
283
- * Create an array of a certain size and fill all items with an initial value
284
- * @param {number} size
285
- * @param {number} value
286
- * @return {number[]}
287
- */
288
- function createArray(size, value) {
289
- // TODO: as soon as all browsers support Array.fill, use that instead (IE doesn't support it)
290
- var array = new Array(size);
291
- for (var i = 0; i < size; i++) {
292
- array[i] = value;
293
- }
294
- return array;
295
- }
296
302
  return main;
297
303
  }