ml-matrix 6.1.2 → 6.4.1

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.
@@ -0,0 +1,135 @@
1
+ import WrapperMatrix2D from '../wrap/WrapperMatrix2D';
2
+ import Matrix from '../matrix';
3
+
4
+ export default class nipals {
5
+ constructor(X, options = {}) {
6
+ X = WrapperMatrix2D.checkMatrix(X);
7
+ let { Y } = options;
8
+ const {
9
+ scaleScores = false,
10
+ maxIterations = 1000,
11
+ terminationCriteria = 1e-10,
12
+ } = options;
13
+
14
+ let u;
15
+ if (Y) {
16
+ if (Array.isArray(Y) && typeof Y[0] === 'number') {
17
+ Y = Matrix.columnVector(Y);
18
+ } else {
19
+ Y = WrapperMatrix2D.checkMatrix(Y);
20
+ }
21
+ if (!Y.isColumnVector() || Y.rows !== X.rows) {
22
+ throw new Error('Y must be a column vector of length X.rows');
23
+ }
24
+ u = Y;
25
+ } else {
26
+ u = X.getColumnVector(0);
27
+ }
28
+
29
+ let diff = 1;
30
+ let t, q, w, tOld;
31
+
32
+ for (
33
+ let counter = 0;
34
+ counter < maxIterations && diff > terminationCriteria;
35
+ counter++
36
+ ) {
37
+ w = X.transpose()
38
+ .mmul(u)
39
+ .div(
40
+ u
41
+ .transpose()
42
+ .mmul(u)
43
+ .get(0, 0),
44
+ );
45
+ w = w.div(w.norm());
46
+
47
+ t = X.mmul(w).div(
48
+ w
49
+ .transpose()
50
+ .mmul(w)
51
+ .get(0, 0),
52
+ );
53
+
54
+ if (counter > 0) {
55
+ diff = t
56
+ .clone()
57
+ .sub(tOld)
58
+ .pow(2)
59
+ .sum();
60
+ }
61
+ tOld = t.clone();
62
+
63
+ if (Y) {
64
+ q = Y.transpose()
65
+ .mmul(t)
66
+ .div(
67
+ t
68
+ .transpose()
69
+ .mmul(t)
70
+ .get(0, 0),
71
+ );
72
+ q = q.div(q.norm());
73
+
74
+ u = Y.mmul(q).div(
75
+ q
76
+ .transpose()
77
+ .mmul(q)
78
+ .get(0, 0),
79
+ );
80
+ } else {
81
+ u = t;
82
+ }
83
+ }
84
+
85
+ if (Y) {
86
+ let p = X.transpose()
87
+ .mmul(t)
88
+ .div(
89
+ t
90
+ .transpose()
91
+ .mmul(t)
92
+ .get(0, 0),
93
+ );
94
+ p = p.div(p.norm());
95
+ let xResidual = X.clone().sub(t.clone().mmul(p.transpose()));
96
+ let residual = u
97
+ .transpose()
98
+ .mmul(t)
99
+ .div(
100
+ t
101
+ .transpose()
102
+ .mmul(t)
103
+ .get(0, 0),
104
+ );
105
+ let yResidual = Y.clone().sub(
106
+ t
107
+ .clone()
108
+ .mulS(residual.get(0, 0))
109
+ .mmul(q.transpose()),
110
+ );
111
+
112
+ this.t = t;
113
+ this.p = p.transpose();
114
+ this.w = w.transpose();
115
+ this.q = q;
116
+ this.u = u;
117
+ this.s = t.transpose().mmul(t);
118
+ this.xResidual = xResidual;
119
+ this.yResidual = yResidual;
120
+ this.betas = residual;
121
+ } else {
122
+ this.w = w.transpose();
123
+ this.s = t
124
+ .transpose()
125
+ .mmul(t)
126
+ .sqrt();
127
+ if (scaleScores) {
128
+ this.t = t.clone().div(this.s.get(0, 0));
129
+ } else {
130
+ this.t = t;
131
+ }
132
+ this.xResidual = X.sub(t.mmul(w.transpose()));
133
+ }
134
+ }
135
+ }
package/src/dc/qr.js CHANGED
@@ -7,14 +7,14 @@ export default class QrDecomposition {
7
7
  constructor(value) {
8
8
  value = WrapperMatrix2D.checkMatrix(value);
9
9
 
10
- var qr = value.clone();
11
- var m = value.rows;
12
- var n = value.columns;
13
- var rdiag = new Float64Array(n);
14
- var i, j, k, s;
10
+ let qr = value.clone();
11
+ let m = value.rows;
12
+ let n = value.columns;
13
+ let rdiag = new Float64Array(n);
14
+ let i, j, k, s;
15
15
 
16
16
  for (k = 0; k < n; k++) {
17
- var nrm = 0;
17
+ let nrm = 0;
18
18
  for (i = k; i < m; i++) {
19
19
  nrm = hypotenuse(nrm, qr.get(i, k));
20
20
  }
@@ -47,8 +47,8 @@ export default class QrDecomposition {
47
47
  solve(value) {
48
48
  value = Matrix.checkMatrix(value);
49
49
 
50
- var qr = this.QR;
51
- var m = qr.rows;
50
+ let qr = this.QR;
51
+ let m = qr.rows;
52
52
 
53
53
  if (value.rows !== m) {
54
54
  throw new Error('Matrix row dimensions must agree');
@@ -57,10 +57,10 @@ export default class QrDecomposition {
57
57
  throw new Error('Matrix is rank deficient');
58
58
  }
59
59
 
60
- var count = value.columns;
61
- var X = value.clone();
62
- var n = qr.columns;
63
- var i, j, k, s;
60
+ let count = value.columns;
61
+ let X = value.clone();
62
+ let n = qr.columns;
63
+ let i, j, k, s;
64
64
 
65
65
  for (k = 0; k < n; k++) {
66
66
  for (j = 0; j < count; j++) {
@@ -89,8 +89,8 @@ export default class QrDecomposition {
89
89
  }
90
90
 
91
91
  isFullRank() {
92
- var columns = this.QR.columns;
93
- for (var i = 0; i < columns; i++) {
92
+ let columns = this.QR.columns;
93
+ for (let i = 0; i < columns; i++) {
94
94
  if (this.Rdiag[i] === 0) {
95
95
  return false;
96
96
  }
@@ -99,10 +99,10 @@ export default class QrDecomposition {
99
99
  }
100
100
 
101
101
  get upperTriangularMatrix() {
102
- var qr = this.QR;
103
- var n = qr.columns;
104
- var X = new Matrix(n, n);
105
- var i, j;
102
+ let qr = this.QR;
103
+ let n = qr.columns;
104
+ let X = new Matrix(n, n);
105
+ let i, j;
106
106
  for (i = 0; i < n; i++) {
107
107
  for (j = 0; j < n; j++) {
108
108
  if (i < j) {
@@ -118,11 +118,11 @@ export default class QrDecomposition {
118
118
  }
119
119
 
120
120
  get orthogonalMatrix() {
121
- var qr = this.QR;
122
- var rows = qr.rows;
123
- var columns = qr.columns;
124
- var X = new Matrix(rows, columns);
125
- var i, j, k, s;
121
+ let qr = this.QR;
122
+ let rows = qr.rows;
123
+ let columns = qr.columns;
124
+ let X = new Matrix(rows, columns);
125
+ let i, j, k, s;
126
126
 
127
127
  for (k = columns - 1; k >= 0; k--) {
128
128
  for (i = 0; i < rows; i++) {
@@ -136,7 +136,7 @@ export default class QrDecomposition {
136
136
  s += qr.get(i, k) * X.get(i, j);
137
137
  }
138
138
 
139
- s = -s / qr[k][k];
139
+ s = -s / qr.get(k, k);
140
140
 
141
141
  for (i = k; i < rows; i++) {
142
142
  X.set(i, j, X.get(i, j) + s * qr.get(i, k));
package/src/dc/svd.js CHANGED
@@ -7,33 +7,33 @@ export default class SingularValueDecomposition {
7
7
  constructor(value, options = {}) {
8
8
  value = WrapperMatrix2D.checkMatrix(value);
9
9
 
10
- var m = value.rows;
11
- var n = value.columns;
10
+ let m = value.rows;
11
+ let n = value.columns;
12
12
 
13
13
  const {
14
14
  computeLeftSingularVectors = true,
15
15
  computeRightSingularVectors = true,
16
- autoTranspose = false
16
+ autoTranspose = false,
17
17
  } = options;
18
18
 
19
- var wantu = Boolean(computeLeftSingularVectors);
20
- var wantv = Boolean(computeRightSingularVectors);
19
+ let wantu = Boolean(computeLeftSingularVectors);
20
+ let wantv = Boolean(computeRightSingularVectors);
21
21
 
22
- var swapped = false;
23
- var a;
22
+ let swapped = false;
23
+ let a;
24
24
  if (m < n) {
25
25
  if (!autoTranspose) {
26
26
  a = value.clone();
27
27
  // eslint-disable-next-line no-console
28
28
  console.warn(
29
- 'Computing SVD on a matrix with more columns than rows. Consider enabling autoTranspose'
29
+ 'Computing SVD on a matrix with more columns than rows. Consider enabling autoTranspose',
30
30
  );
31
31
  } else {
32
32
  a = value.transpose();
33
33
  m = a.rows;
34
34
  n = a.columns;
35
35
  swapped = true;
36
- var aux = wantu;
36
+ let aux = wantu;
37
37
  wantu = wantv;
38
38
  wantv = aux;
39
39
  }
@@ -41,21 +41,21 @@ export default class SingularValueDecomposition {
41
41
  a = value.clone();
42
42
  }
43
43
 
44
- var nu = Math.min(m, n);
45
- var ni = Math.min(m + 1, n);
46
- var s = new Float64Array(ni);
47
- var U = new Matrix(m, nu);
48
- var V = new Matrix(n, n);
44
+ let nu = Math.min(m, n);
45
+ let ni = Math.min(m + 1, n);
46
+ let s = new Float64Array(ni);
47
+ let U = new Matrix(m, nu);
48
+ let V = new Matrix(n, n);
49
49
 
50
- var e = new Float64Array(n);
51
- var work = new Float64Array(m);
50
+ let e = new Float64Array(n);
51
+ let work = new Float64Array(m);
52
52
 
53
- var si = new Float64Array(ni);
53
+ let si = new Float64Array(ni);
54
54
  for (let i = 0; i < ni; i++) si[i] = i;
55
55
 
56
- var nct = Math.min(m - 1, n);
57
- var nrt = Math.max(0, Math.min(n - 2, m));
58
- var mrc = Math.max(nct, nrt);
56
+ let nct = Math.min(m - 1, n);
57
+ let nrt = Math.max(0, Math.min(n - 2, m));
58
+ let mrc = Math.max(nct, nrt);
59
59
 
60
60
  for (let k = 0; k < mrc; k++) {
61
61
  if (k < nct) {
@@ -202,9 +202,9 @@ export default class SingularValueDecomposition {
202
202
  }
203
203
  }
204
204
 
205
- var pp = p - 1;
206
- var iter = 0;
207
- var eps = Number.EPSILON;
205
+ let pp = p - 1;
206
+ let iter = 0;
207
+ let eps = Number.EPSILON;
208
208
  while (p > 0) {
209
209
  let k, kase;
210
210
  for (k = p - 2; k >= -1; k--) {
@@ -295,7 +295,7 @@ export default class SingularValueDecomposition {
295
295
  Math.abs(s[p - 2]),
296
296
  Math.abs(e[p - 2]),
297
297
  Math.abs(s[k]),
298
- Math.abs(e[k])
298
+ Math.abs(e[k]),
299
299
  );
300
300
  const sp = s[p - 1] / scale;
301
301
  const spm1 = s[p - 2] / scale;
@@ -396,7 +396,7 @@ export default class SingularValueDecomposition {
396
396
  }
397
397
 
398
398
  if (swapped) {
399
- var tmp = V;
399
+ let tmp = V;
400
400
  V = U;
401
401
  U = tmp;
402
402
  }
@@ -409,10 +409,10 @@ export default class SingularValueDecomposition {
409
409
  }
410
410
 
411
411
  solve(value) {
412
- var Y = value;
413
- var e = this.threshold;
414
- var scols = this.s.length;
415
- var Ls = Matrix.zeros(scols, scols);
412
+ let Y = value;
413
+ let e = this.threshold;
414
+ let scols = this.s.length;
415
+ let Ls = Matrix.zeros(scols, scols);
416
416
 
417
417
  for (let i = 0; i < scols; i++) {
418
418
  if (Math.abs(this.s[i]) <= e) {
@@ -422,13 +422,13 @@ export default class SingularValueDecomposition {
422
422
  }
423
423
  }
424
424
 
425
- var U = this.U;
426
- var V = this.rightSingularVectors;
425
+ let U = this.U;
426
+ let V = this.rightSingularVectors;
427
427
 
428
- var VL = V.mmul(Ls);
429
- var vrows = V.rows;
430
- var urows = U.rows;
431
- var VLU = Matrix.zeros(vrows, urows);
428
+ let VL = V.mmul(Ls);
429
+ let vrows = V.rows;
430
+ let urows = U.rows;
431
+ let VLU = Matrix.zeros(vrows, urows);
432
432
 
433
433
  for (let i = 0; i < vrows; i++) {
434
434
  for (let j = 0; j < urows; j++) {
@@ -448,11 +448,11 @@ export default class SingularValueDecomposition {
448
448
  }
449
449
 
450
450
  inverse() {
451
- var V = this.V;
452
- var e = this.threshold;
453
- var vrows = V.rows;
454
- var vcols = V.columns;
455
- var X = new Matrix(vrows, this.s.length);
451
+ let V = this.V;
452
+ let e = this.threshold;
453
+ let vrows = V.rows;
454
+ let vcols = V.columns;
455
+ let X = new Matrix(vrows, this.s.length);
456
456
 
457
457
  for (let i = 0; i < vrows; i++) {
458
458
  for (let j = 0; j < vcols; j++) {
@@ -462,11 +462,11 @@ export default class SingularValueDecomposition {
462
462
  }
463
463
  }
464
464
 
465
- var U = this.U;
465
+ let U = this.U;
466
466
 
467
- var urows = U.rows;
468
- var ucols = U.columns;
469
- var Y = new Matrix(vrows, urows);
467
+ let urows = U.rows;
468
+ let ucols = U.columns;
469
+ let Y = new Matrix(vrows, urows);
470
470
 
471
471
  for (let i = 0; i < vrows; i++) {
472
472
  for (let j = 0; j < urows; j++) {
@@ -490,10 +490,10 @@ export default class SingularValueDecomposition {
490
490
  }
491
491
 
492
492
  get rank() {
493
- var tol = Math.max(this.m, this.n) * this.s[0] * Number.EPSILON;
494
- var r = 0;
495
- var s = this.s;
496
- for (var i = 0, ii = s.length; i < ii; i++) {
493
+ let tol = Math.max(this.m, this.n) * this.s[0] * Number.EPSILON;
494
+ let r = 0;
495
+ let s = this.s;
496
+ for (let i = 0, ii = s.length; i < ii; i++) {
497
497
  if (s[i] > tol) {
498
498
  r++;
499
499
  }
package/src/dc/util.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export function hypotenuse(a, b) {
2
- var r = 0;
2
+ let r = 0;
3
3
  if (Math.abs(a) > Math.abs(b)) {
4
4
  r = b / a;
5
5
  return Math.abs(a) * Math.sqrt(1 + r * r);
@@ -5,7 +5,7 @@ import MatrixSelectionView from './views/selection';
5
5
  export function determinant(matrix) {
6
6
  matrix = Matrix.checkMatrix(matrix);
7
7
  if (matrix.isSquare()) {
8
- var a, b, c, d;
8
+ let a, b, c, d;
9
9
  if (matrix.columns === 2) {
10
10
  // 2 x 2 matrix
11
11
  a = matrix.get(0, 0);
@@ -16,7 +16,7 @@ export function determinant(matrix) {
16
16
  return a * d - b * c;
17
17
  } else if (matrix.columns === 3) {
18
18
  // 3 x 3 matrix
19
- var subMatrix0, subMatrix1, subMatrix2;
19
+ let subMatrix0, subMatrix1, subMatrix2;
20
20
  subMatrix0 = new MatrixSelectionView(matrix, [1, 2], [1, 2]);
21
21
  subMatrix1 = new MatrixSelectionView(matrix, [1, 2], [0, 2]);
22
22
  subMatrix2 = new MatrixSelectionView(matrix, [1, 2], [0, 1]);
package/src/index.js CHANGED
@@ -14,15 +14,16 @@ export { correlation } from './correlation';
14
14
 
15
15
  export {
16
16
  default as SingularValueDecomposition,
17
- default as SVD
17
+ default as SVD,
18
18
  } from './dc/svd.js';
19
19
  export {
20
20
  default as EigenvalueDecomposition,
21
- default as EVD
21
+ default as EVD,
22
22
  } from './dc/evd.js';
23
23
  export {
24
24
  default as CholeskyDecomposition,
25
- default as CHO
25
+ default as CHO,
26
26
  } from './dc/cholesky.js';
27
27
  export { default as LuDecomposition, default as LU } from './dc/lu.js';
28
28
  export { default as QrDecomposition, default as QR } from './dc/qr.js';
29
+ export { default as Nipals, default as NIPALS } from './dc/nipals.js';
package/src/inspect.js CHANGED
@@ -19,9 +19,9 @@ function inspectData(matrix, indent) {
19
19
  const maxI = Math.min(rows, maxRows);
20
20
  const maxJ = Math.min(columns, maxColumns);
21
21
  const result = [];
22
- for (var i = 0; i < maxI; i++) {
22
+ for (let i = 0; i < maxI; i++) {
23
23
  let line = [];
24
- for (var j = 0; j < maxJ; j++) {
24
+ for (let j = 0; j < maxJ; j++) {
25
25
  line.push(formatNumber(matrix.get(i, j)));
26
26
  }
27
27
  result.push(`${line.join(' ')}`);
@@ -2,8 +2,8 @@ import Matrix from './matrix';
2
2
  import SingularValueDecomposition from './dc/svd';
3
3
 
4
4
  function xrange(n, exception) {
5
- var range = [];
6
- for (var i = 0; i < n; i++) {
5
+ let range = [];
6
+ for (let i = 0; i < n; i++) {
7
7
  if (i !== exception) {
8
8
  range.push(i);
9
9
  }
@@ -16,13 +16,13 @@ function dependenciesOneRow(
16
16
  matrix,
17
17
  index,
18
18
  thresholdValue = 10e-10,
19
- thresholdError = 10e-10
19
+ thresholdError = 10e-10,
20
20
  ) {
21
21
  if (error > thresholdError) {
22
22
  return new Array(matrix.rows + 1).fill(0);
23
23
  } else {
24
- var returnArray = matrix.addRow(index, [0]);
25
- for (var i = 0; i < returnArray.rows; i++) {
24
+ let returnArray = matrix.addRow(index, [0]);
25
+ for (let i = 0; i < returnArray.rows; i++) {
26
26
  if (Math.abs(returnArray.get(i, 0)) < thresholdValue) {
27
27
  returnArray.set(i, 0, 0);
28
28
  }
@@ -35,20 +35,20 @@ export function linearDependencies(matrix, options = {}) {
35
35
  const { thresholdValue = 10e-10, thresholdError = 10e-10 } = options;
36
36
  matrix = Matrix.checkMatrix(matrix);
37
37
 
38
- var n = matrix.rows;
39
- var results = new Matrix(n, n);
38
+ let n = matrix.rows;
39
+ let results = new Matrix(n, n);
40
40
 
41
- for (var i = 0; i < n; i++) {
42
- var b = Matrix.columnVector(matrix.getRow(i));
43
- var Abis = matrix.subMatrixRow(xrange(n, i)).transpose();
44
- var svd = new SingularValueDecomposition(Abis);
45
- var x = svd.solve(b);
46
- var error = Matrix.sub(b, Abis.mmul(x))
41
+ for (let i = 0; i < n; i++) {
42
+ let b = Matrix.columnVector(matrix.getRow(i));
43
+ let Abis = matrix.subMatrixRow(xrange(n, i)).transpose();
44
+ let svd = new SingularValueDecomposition(Abis);
45
+ let x = svd.solve(b);
46
+ let error = Matrix.sub(b, Abis.mmul(x))
47
47
  .abs()
48
48
  .max();
49
49
  results.setRow(
50
50
  i,
51
- dependenciesOneRow(error, x, i, thresholdValue, thresholdError)
51
+ dependenciesOneRow(error, x, i, thresholdValue, thresholdError),
52
52
  );
53
53
  }
54
54
  return results;