UNPKG

ml-matrix

Version:

Matrix manipulation and computation library

88 lines (72 loc) 2.04 kB
import Matrix from '../matrix'; import WrapperMatrix2D from '../wrap/WrapperMatrix2D'; export default class CholeskyDecomposition { constructor(value) { value = WrapperMatrix2D.checkMatrix(value); if (!value.isSymmetric()) { throw new Error('Matrix is not symmetric'); } let a = value; let dimension = a.rows; let l = new Matrix(dimension, dimension); let positiveDefinite = true; let i, j, k; for (j = 0; j < dimension; j++) { let d = 0; for (k = 0; k < j; k++) { let s = 0; for (i = 0; i < k; i++) { s += l.get(k, i) * l.get(j, i); } s = (a.get(j, k) - s) / l.get(k, k); l.set(j, k, s); d = d + s * s; } d = a.get(j, j) - d; positiveDefinite &&= d > 0; l.set(j, j, Math.sqrt(Math.max(d, 0))); for (k = j + 1; k < dimension; k++) { l.set(j, k, 0); } } this.L = l; this.positiveDefinite = positiveDefinite; } isPositiveDefinite() { return this.positiveDefinite; } solve(value) { value = WrapperMatrix2D.checkMatrix(value); let l = this.L; let dimension = l.rows; if (value.rows !== dimension) { throw new Error('Matrix dimensions do not match'); } if (this.isPositiveDefinite() === false) { throw new Error('Matrix is not positive definite'); } let count = value.columns; let B = value.clone(); let i, j, k; for (k = 0; k < dimension; k++) { for (j = 0; j < count; j++) { for (i = 0; i < k; i++) { B.set(k, j, B.get(k, j) - B.get(i, j) * l.get(k, i)); } B.set(k, j, B.get(k, j) / l.get(k, k)); } } for (k = dimension - 1; k >= 0; k--) { for (j = 0; j < count; j++) { for (i = k + 1; i < dimension; i++) { B.set(k, j, B.get(k, j) - B.get(i, j) * l.get(i, k)); } B.set(k, j, B.get(k, j) / l.get(k, k)); } } return B; } get lowerTriangularMatrix() { return this.L; } }