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.
- package/HISTORY.md +54 -2
- package/README.md +1 -1
- package/lib/browser/math.js +1 -1
- package/lib/browser/math.js.LICENSE.txt +2 -2
- package/lib/browser/math.js.map +1 -1
- package/lib/cjs/entry/dependenciesAny/dependenciesEigs.generated.js +4 -0
- package/lib/cjs/entry/pureFunctionsAny.generated.js +2 -0
- package/lib/cjs/expression/embeddedDocs/function/arithmetic/round.js +2 -2
- package/lib/cjs/expression/embeddedDocs/function/matrix/eigs.js +2 -2
- package/lib/cjs/expression/node/AssignmentNode.js +1 -1
- package/lib/cjs/expression/node/FunctionAssignmentNode.js +1 -1
- package/lib/cjs/function/algebra/derivative.js +8 -31
- package/lib/cjs/function/arithmetic/gcd.js +4 -5
- package/lib/cjs/function/arithmetic/mod.js +2 -9
- package/lib/cjs/function/arithmetic/round.js +59 -16
- package/lib/cjs/function/matrix/eigs/complexEigs.js +73 -68
- package/lib/cjs/function/matrix/eigs/{realSymetric.js → realSymmetric.js} +57 -51
- package/lib/cjs/function/matrix/eigs.js +118 -45
- package/lib/cjs/function/probability/pickRandom.js +2 -2
- package/lib/cjs/header.js +2 -2
- package/lib/cjs/type/number.js +2 -2
- package/lib/cjs/utils/number.js +1 -1
- package/lib/cjs/utils/snapshot.js +6 -6
- package/lib/cjs/version.js +1 -1
- package/lib/esm/entry/dependenciesAny/dependenciesEigs.generated.js +4 -0
- package/lib/esm/entry/pureFunctionsAny.generated.js +2 -0
- package/lib/esm/expression/embeddedDocs/function/arithmetic/round.js +2 -2
- package/lib/esm/expression/embeddedDocs/function/matrix/eigs.js +2 -2
- package/lib/esm/expression/node/AssignmentNode.js +1 -1
- package/lib/esm/expression/node/FunctionAssignmentNode.js +1 -1
- package/lib/esm/function/algebra/derivative.js +8 -31
- package/lib/esm/function/arithmetic/mod.js +2 -9
- package/lib/esm/function/arithmetic/round.js +40 -17
- package/lib/esm/function/matrix/eigs/complexEigs.js +73 -68
- package/lib/esm/function/matrix/eigs/{realSymetric.js → realSymmetric.js} +55 -51
- package/lib/esm/function/matrix/eigs.js +119 -47
- package/lib/esm/function/probability/pickRandom.js +2 -2
- package/lib/esm/type/number.js +2 -2
- package/lib/esm/utils/number.js +1 -1
- package/lib/esm/version.js +1 -1
- package/package.json +14 -14
- package/types/EXPLANATION.md +54 -0
- package/types/index.d.ts +6825 -6483
@@ -11,6 +11,8 @@ export function createComplexEigs(_ref) {
|
|
11
11
|
abs,
|
12
12
|
bignumber,
|
13
13
|
diag,
|
14
|
+
size,
|
15
|
+
reshape,
|
14
16
|
inv,
|
15
17
|
qr,
|
16
18
|
usolve,
|
@@ -31,11 +33,8 @@ export function createComplexEigs(_ref) {
|
|
31
33
|
*
|
32
34
|
* @returns {{ values: number[], vectors: number[][] }}
|
33
35
|
*/
|
34
|
-
function complexEigs(arr, N, prec, type
|
35
|
-
|
36
|
-
findVectors = true;
|
37
|
-
}
|
38
|
-
|
36
|
+
function complexEigs(arr, N, prec, type) {
|
37
|
+
var findVectors = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
|
39
38
|
// TODO check if any row/col are zero except the diagonal
|
40
39
|
|
41
40
|
// make sure corresponding rows and columns have similar magnitude
|
@@ -44,9 +43,9 @@ export function createComplexEigs(_ref) {
|
|
44
43
|
var R = balance(arr, N, prec, type, findVectors);
|
45
44
|
|
46
45
|
// R is the row transformation matrix
|
47
|
-
// arr = A' = R A R
|
46
|
+
// arr = A' = R A R^-1, A is the original matrix
|
48
47
|
// (if findVectors is false, R is undefined)
|
49
|
-
// (And so to return to original matrix: A = R
|
48
|
+
// (And so to return to original matrix: A = R^-1 arr R)
|
50
49
|
|
51
50
|
// TODO if magnitudes of elements vary over many orders,
|
52
51
|
// move greatest elements to the top left corner
|
@@ -56,7 +55,7 @@ export function createComplexEigs(_ref) {
|
|
56
55
|
// updates the transformation matrix R with new row operationsq
|
57
56
|
// MODIFIES arr by side effect!
|
58
57
|
reduceToHessenberg(arr, N, prec, type, findVectors, R);
|
59
|
-
// still true that original A = R
|
58
|
+
// still true that original A = R^-1 arr R)
|
60
59
|
|
61
60
|
// find eigenvalues
|
62
61
|
var {
|
@@ -67,17 +66,18 @@ export function createComplexEigs(_ref) {
|
|
67
66
|
// values is the list of eigenvalues, C is the column
|
68
67
|
// transformation matrix that transforms arr, the hessenberg
|
69
68
|
// matrix, to upper triangular
|
70
|
-
// (So U = C
|
69
|
+
// (So U = C^-1 arr C and the relationship between current arr
|
71
70
|
// and original A is unchanged.)
|
72
71
|
|
73
|
-
var vectors;
|
74
72
|
if (findVectors) {
|
75
|
-
|
76
|
-
|
73
|
+
var eigenvectors = findEigenvectors(arr, N, C, R, values, prec, type);
|
74
|
+
return {
|
75
|
+
values,
|
76
|
+
eigenvectors
|
77
|
+
};
|
77
78
|
}
|
78
79
|
return {
|
79
|
-
values
|
80
|
-
vectors
|
80
|
+
values
|
81
81
|
};
|
82
82
|
}
|
83
83
|
|
@@ -117,9 +117,8 @@ export function createComplexEigs(_ref) {
|
|
117
117
|
var rowNorm = realzero;
|
118
118
|
for (var j = 0; j < N; j++) {
|
119
119
|
if (i === j) continue;
|
120
|
-
|
121
|
-
|
122
|
-
rowNorm = addScalar(rowNorm, c);
|
120
|
+
colNorm = addScalar(colNorm, abs(arr[j][i]));
|
121
|
+
rowNorm = addScalar(rowNorm, abs(arr[i][j]));
|
123
122
|
}
|
124
123
|
if (!equal(colNorm, 0) && !equal(rowNorm, 0)) {
|
125
124
|
// find integer power closest to balancing the matrix
|
@@ -127,21 +126,21 @@ export function createComplexEigs(_ref) {
|
|
127
126
|
// so that we don't lose any precision due to round-off)
|
128
127
|
|
129
128
|
var f = realone;
|
130
|
-
var
|
129
|
+
var c = colNorm;
|
131
130
|
var rowDivRadix = divideScalar(rowNorm, radix);
|
132
131
|
var rowMulRadix = multiplyScalar(rowNorm, radix);
|
133
|
-
while (smaller(
|
134
|
-
|
132
|
+
while (smaller(c, rowDivRadix)) {
|
133
|
+
c = multiplyScalar(c, radixSq);
|
135
134
|
f = multiplyScalar(f, radix);
|
136
135
|
}
|
137
|
-
while (larger(
|
138
|
-
|
136
|
+
while (larger(c, rowMulRadix)) {
|
137
|
+
c = divideScalar(c, radixSq);
|
139
138
|
f = divideScalar(f, radix);
|
140
139
|
}
|
141
140
|
|
142
141
|
// check whether balancing is needed
|
143
142
|
// condition = (c + rowNorm) / f < 0.95 * (colNorm + rowNorm)
|
144
|
-
var condition = smaller(divideScalar(addScalar(
|
143
|
+
var condition = smaller(divideScalar(addScalar(c, rowNorm), f), multiplyScalar(addScalar(colNorm, rowNorm), 0.95));
|
145
144
|
|
146
145
|
// apply balancing similarity transformation
|
147
146
|
if (condition) {
|
@@ -153,13 +152,13 @@ export function createComplexEigs(_ref) {
|
|
153
152
|
if (i === _j) {
|
154
153
|
continue;
|
155
154
|
}
|
156
|
-
arr[i][_j] = multiplyScalar(arr[i][_j],
|
157
|
-
arr[_j][i] = multiplyScalar(arr[_j][i],
|
155
|
+
arr[i][_j] = multiplyScalar(arr[i][_j], g);
|
156
|
+
arr[_j][i] = multiplyScalar(arr[_j][i], f);
|
158
157
|
}
|
159
158
|
|
160
159
|
// keep track of transformations
|
161
160
|
if (findVectors) {
|
162
|
-
Rdiag[i] = multiplyScalar(Rdiag[i],
|
161
|
+
Rdiag[i] = multiplyScalar(Rdiag[i], g);
|
163
162
|
}
|
164
163
|
}
|
165
164
|
}
|
@@ -167,7 +166,7 @@ export function createComplexEigs(_ref) {
|
|
167
166
|
}
|
168
167
|
|
169
168
|
// return the diagonal row transformation matrix
|
170
|
-
return diag(Rdiag);
|
169
|
+
return findVectors ? diag(Rdiag) : null;
|
171
170
|
}
|
172
171
|
|
173
172
|
/**
|
@@ -266,7 +265,7 @@ export function createComplexEigs(_ref) {
|
|
266
265
|
|
267
266
|
// The Francis Algorithm
|
268
267
|
// The core idea of this algorithm is that doing successive
|
269
|
-
// A' =
|
268
|
+
// A' = QtAQ transformations will eventually converge to block-
|
270
269
|
// upper-triangular with diagonal blocks either 1x1 or 2x2.
|
271
270
|
// The Q here is the one from the QR decomposition, A = QR.
|
272
271
|
// Since the eigenvalues of a block-upper-triangular matrix are
|
@@ -288,7 +287,7 @@ export function createComplexEigs(_ref) {
|
|
288
287
|
// N×N matrix describing the overall transformation done during the QR algorithm
|
289
288
|
var Qtotal = findVectors ? diag(Array(N).fill(one)) : undefined;
|
290
289
|
|
291
|
-
//
|
290
|
+
// nxn matrix describing the QR transformations done since last convergence
|
292
291
|
var Qpartial = findVectors ? diag(Array(n).fill(one)) : undefined;
|
293
292
|
|
294
293
|
// last eigenvalue converged before this many steps
|
@@ -300,7 +299,12 @@ export function createComplexEigs(_ref) {
|
|
300
299
|
|
301
300
|
// Perform the factorization
|
302
301
|
|
303
|
-
var k =
|
302
|
+
var k = arr[n - 1][n - 1]; // TODO this is apparently a somewhat
|
303
|
+
// old-fashioned choice; ideally set close to an eigenvalue, or
|
304
|
+
// perhaps better yet switch to the implicit QR version that is sometimes
|
305
|
+
// specifically called the "Francis algorithm" that is alluded to
|
306
|
+
// in the following TODO. (Or perhaps we switch to an independently
|
307
|
+
// optimized third-party package for the linear algebra operations...)
|
304
308
|
|
305
309
|
for (var i = 0; i < n; i++) {
|
306
310
|
arr[i][i] = subtract(arr[i][i], k);
|
@@ -414,17 +418,17 @@ export function createComplexEigs(_ref) {
|
|
414
418
|
// this way it is easier to find eigenvectors
|
415
419
|
var uniqueValues = [];
|
416
420
|
var multiplicities = [];
|
417
|
-
for (var
|
418
|
-
var i = indexOf(uniqueValues,
|
421
|
+
for (var lambda of values) {
|
422
|
+
var i = indexOf(uniqueValues, lambda, equal);
|
419
423
|
if (i === -1) {
|
420
|
-
uniqueValues.push(
|
424
|
+
uniqueValues.push(lambda);
|
421
425
|
multiplicities.push(1);
|
422
426
|
} else {
|
423
427
|
multiplicities[i] += 1;
|
424
428
|
}
|
425
429
|
}
|
426
430
|
|
427
|
-
// find eigenvectors by solving U −
|
431
|
+
// find eigenvectors by solving U − lambdaE = 0
|
428
432
|
// TODO replace with an iterative eigenvector algorithm
|
429
433
|
// (this one might fail for imprecise eigenvalues)
|
430
434
|
|
@@ -432,41 +436,35 @@ export function createComplexEigs(_ref) {
|
|
432
436
|
var len = uniqueValues.length;
|
433
437
|
var b = Array(N).fill(zero);
|
434
438
|
var E = diag(Array(N).fill(one));
|
435
|
-
|
436
|
-
// eigenvalues for which usolve failed (due to numerical error)
|
437
|
-
var failedLambdas = [];
|
438
439
|
var _loop = function _loop() {
|
439
|
-
var
|
440
|
-
var S = subtract(U, multiply(
|
440
|
+
var lambda = uniqueValues[_i4];
|
441
|
+
var S = subtract(U, multiply(lambda, E)); // the characteristic matrix
|
441
442
|
|
442
443
|
var solutions = usolveAll(S, b);
|
443
444
|
solutions.shift(); // ignore the null vector
|
444
445
|
|
445
446
|
// looks like we missed something, try inverse iteration
|
447
|
+
// But if that fails, just presume that the original matrix truly
|
448
|
+
// was defective.
|
446
449
|
while (solutions.length < multiplicities[_i4]) {
|
447
450
|
var approxVec = inverseIterate(S, N, solutions, prec, type);
|
448
|
-
if (approxVec
|
449
|
-
// no more vectors were found
|
450
|
-
failedLambdas.push(λ);
|
451
|
+
if (approxVec === null) {
|
451
452
|
break;
|
452
|
-
}
|
453
|
+
} // no more vectors were found
|
453
454
|
solutions.push(approxVec);
|
454
455
|
}
|
455
456
|
|
456
457
|
// Transform back into original array coordinates
|
457
458
|
var correction = multiply(inv(R), C);
|
458
459
|
solutions = solutions.map(v => multiply(correction, v));
|
459
|
-
vectors.push(...solutions.map(v =>
|
460
|
+
vectors.push(...solutions.map(v => ({
|
461
|
+
value: lambda,
|
462
|
+
vector: flatten(v)
|
463
|
+
})));
|
460
464
|
};
|
461
465
|
for (var _i4 = 0; _i4 < len; _i4++) {
|
462
466
|
_loop();
|
463
467
|
}
|
464
|
-
if (failedLambdas.length !== 0) {
|
465
|
-
var err = new Error('Failed to find eigenvectors for the following eigenvalues: ' + failedLambdas.join(', '));
|
466
|
-
err.values = values;
|
467
|
-
err.vectors = vectors;
|
468
|
-
throw err;
|
469
|
-
}
|
470
468
|
return vectors;
|
471
469
|
}
|
472
470
|
|
@@ -475,7 +473,7 @@ export function createComplexEigs(_ref) {
|
|
475
473
|
* @return {[number,number]}
|
476
474
|
*/
|
477
475
|
function eigenvalues2x2(a, b, c, d) {
|
478
|
-
//
|
476
|
+
// lambda_+- = 1/2 trA +- 1/2 sqrt( tr^2 A - 4 detA )
|
479
477
|
var trA = addScalar(a, d);
|
480
478
|
var detA = subtract(multiplyScalar(a, d), multiplyScalar(b, c));
|
481
479
|
var x = multiplyScalar(trA, 0.5);
|
@@ -485,7 +483,7 @@ export function createComplexEigs(_ref) {
|
|
485
483
|
|
486
484
|
/**
|
487
485
|
* For an 2x2 matrix compute the transformation matrix S,
|
488
|
-
* so that SAS
|
486
|
+
* so that SAS^-1 is an upper triangular matrix
|
489
487
|
* @return {[[number,number],[number,number]]}
|
490
488
|
* @see https://math.berkeley.edu/~ogus/old/Math_54-05/webfoils/jordan.pdf
|
491
489
|
* @see http://people.math.harvard.edu/~knill/teaching/math21b2004/exhibits/2dmatrices/index.html
|
@@ -509,23 +507,22 @@ export function createComplexEigs(_ref) {
|
|
509
507
|
}
|
510
508
|
|
511
509
|
// matrix is not diagonalizable
|
512
|
-
// compute
|
513
|
-
// N₁₂ = 0 ⇒ S = ( N⃗₁, I⃗₁ )
|
514
|
-
// N₁₂ ≠ 0 ⇒ S = ( N⃗₂, I⃗₂ )
|
515
|
-
|
510
|
+
// compute diagonal elements of N = A - lambdaI
|
516
511
|
var na = subtract(a, l1);
|
517
|
-
var nb = subtract(b, l1);
|
518
|
-
var nc = subtract(c, l1);
|
519
512
|
var nd = subtract(d, l1);
|
520
|
-
|
521
|
-
|
513
|
+
|
514
|
+
// col(N,2) = 0 implies S = ( col(N,1), e_1 )
|
515
|
+
// col(N,2) != 0 implies S = ( col(N,2), e_2 )
|
516
|
+
|
517
|
+
if (smaller(abs(b), prec) && smaller(abs(nd), prec)) {
|
518
|
+
return [[na, one], [c, zero]];
|
522
519
|
} else {
|
523
|
-
return [[
|
520
|
+
return [[b, zero], [nd, one]];
|
524
521
|
}
|
525
522
|
}
|
526
523
|
|
527
524
|
/**
|
528
|
-
* Enlarge the matrix from
|
525
|
+
* Enlarge the matrix from nxn to NxN, setting the new
|
529
526
|
* elements to 1 on diagonal and 0 elsewhere
|
530
527
|
*/
|
531
528
|
function inflateMatrix(arr, N) {
|
@@ -602,15 +599,21 @@ export function createComplexEigs(_ref) {
|
|
602
599
|
|
603
600
|
// you better choose a random vector before I count to five
|
604
601
|
var i = 0;
|
605
|
-
|
602
|
+
for (; i < 5; ++i) {
|
606
603
|
b = randomOrthogonalVector(N, orthog, type);
|
607
|
-
|
604
|
+
try {
|
605
|
+
b = usolve(A, b);
|
606
|
+
} catch (_unused) {
|
607
|
+
// That direction didn't work, likely because the original matrix
|
608
|
+
// was defective. But still make the full number of tries...
|
609
|
+
continue;
|
610
|
+
}
|
608
611
|
if (larger(norm(b), largeNum)) {
|
609
612
|
break;
|
610
613
|
}
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
+
}
|
615
|
+
if (i >= 5) {
|
616
|
+
return null; // couldn't find any orthogonal vector in the image
|
614
617
|
}
|
615
618
|
|
616
619
|
// you better converge before I count to ten
|
@@ -660,8 +663,10 @@ export function createComplexEigs(_ref) {
|
|
660
663
|
* Project vector v to the orthogonal complement of an array of vectors
|
661
664
|
*/
|
662
665
|
function orthogonalComplement(v, orthog) {
|
666
|
+
var vectorShape = size(v);
|
663
667
|
for (var w of orthog) {
|
664
|
-
|
668
|
+
w = reshape(w, vectorShape); // make sure this is just a vector computation
|
669
|
+
// v := v − (w, v)/|w|^2 w
|
665
670
|
v = subtract(v, multiply(divideScalar(dot(w, v), dot(w, w)), w));
|
666
671
|
}
|
667
672
|
return v;
|
@@ -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
|
41
|
-
|
42
|
-
|
43
|
-
Sij
|
44
|
-
|
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 =
|
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),
|
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
|
69
|
-
|
70
|
-
|
71
|
-
Sij
|
72
|
-
|
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 =
|
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),
|
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 =
|
118
|
-
var Skj =
|
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 =
|
135
|
-
var Skj =
|
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 =
|
155
|
-
var Akj =
|
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 =
|
191
|
-
var Akj =
|
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
|
254
|
-
|
255
|
-
|
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
|
-
|
268
|
-
|
269
|
-
|
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
|
-
|
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
|
}
|