mathjs 11.12.0 → 12.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
  }