From af651601e72b0a69ea18ec255c42bcccd430224b Mon Sep 17 00:00:00 2001 From: htoopyae Date: Thu, 18 Oct 2018 20:26:16 +0630 Subject: [PATCH] Linear Algebra: Determinal of Matrix Added --- .eslintrc | 3 +- src/algorithms/index.js | 4 +- src/algorithms/linear algebra/index.js | 5 ++ .../linear algebra/matrix_determinant.js | 66 +++++++++++++++++++ .../linear algebra/testMatrixDeterminant.js | 37 +++++++++++ 5 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 src/algorithms/linear algebra/index.js create mode 100644 src/algorithms/linear algebra/matrix_determinant.js create mode 100644 test/algorithms/linear algebra/testMatrixDeterminant.js diff --git a/.eslintrc b/.eslintrc index 262dafce..4aa0b3b1 100644 --- a/.eslintrc +++ b/.eslintrc @@ -8,6 +8,7 @@ "no-param-reassign": "off", "class-methods-use-this": "off", "no-bitwise": "off", - "no-continue": "off" + "no-continue": "off", + "no-plusplus": "off" } } diff --git a/src/algorithms/index.js b/src/algorithms/index.js index 2335cebb..21cefea8 100644 --- a/src/algorithms/index.js +++ b/src/algorithms/index.js @@ -3,11 +3,13 @@ const math = require('./math'); const string = require('./string'); const search = require('./search'); const sort = require('./sort'); +const linearAlgebra = require('./linear algebra'); module.exports = { geometry, math, string, search, - sort + sort, + linearAlgebra }; diff --git a/src/algorithms/linear algebra/index.js b/src/algorithms/linear algebra/index.js new file mode 100644 index 00000000..a5e231c7 --- /dev/null +++ b/src/algorithms/linear algebra/index.js @@ -0,0 +1,5 @@ +const matrixDeterminant = require('./matrix_determinant'); + +module.exports = { + matrixDeterminant +}; diff --git a/src/algorithms/linear algebra/matrix_determinant.js b/src/algorithms/linear algebra/matrix_determinant.js new file mode 100644 index 00000000..54e0b45c --- /dev/null +++ b/src/algorithms/linear algebra/matrix_determinant.js @@ -0,0 +1,66 @@ +/** + * Determinant of a square matrix + * @param {Array} mat input matrix + * @param {Number} n no. of rows + * @return {Number} determinant + */ +const create2dArr = (len) => { + const arr = []; + for (let i = 0; i < len; i++) { + arr.push([]); + } + return arr; +}; + +const getCoMatrix = (mat, p, q, len) => { + let i = 0; + let j = 0; + const coMatrix = create2dArr(len); + + for (let row = 0; row < len; row++) { + for (let col = 0; col < len; col++) { + // copy into temporary matrix + if (row !== p && col !== q) { + coMatrix[i][j++] = mat[row][col]; + + // one row filled, go to next one + if (j === len - 1) { + j = 0; + i++; + } + } + } + } + + return coMatrix; +}; + +const matrixDeterminant = (mat, len) => { + let D = 0; + // to store co matrices + let coMat; + // to toggle signs + let sign = 1; + + // check whether it is square or not + if (len !== mat[0].length) { + throw new Error('Not a square matrix!'); + } + + // base case: if matrix contains single element + if (len === 1) { return mat[0][0]; } + + // iterate for each element of first row + for (let f = 0; f < len; f++) { + // get co matrix + coMat = getCoMatrix(mat, 0, f, len); + D += sign * mat[0][f] * matrixDeterminant(coMat, len - 1); + + // toggle sign + sign = -sign; + } + + return D; +}; + +module.exports = matrixDeterminant; diff --git a/test/algorithms/linear algebra/testMatrixDeterminant.js b/test/algorithms/linear algebra/testMatrixDeterminant.js new file mode 100644 index 00000000..19e4f5de --- /dev/null +++ b/test/algorithms/linear algebra/testMatrixDeterminant.js @@ -0,0 +1,37 @@ +/* eslint-env mocha */ +const matrixDeterminant = require('../../../src').algorithms.linearAlgebra.matrixDeterminant; + +const assert = require('assert'); + +const matOK1 = [ + [1, 2, 3], + [8, 9, 4], + [7, 6, 5] +]; + +const matOK2 = [ + [1, 2, 3, 8], + [8, 9, 4, 1], + [7, 6, 5, 3], + [2, 4, 5, 6] +]; + +const matNotOK = [ + [1, 2], + [3, 4], + [5, 6] +]; + +describe('Determinant of Matrix', () => { + it('should throw an error if the matrix is not a square', () => { + assert.throws(() => matrixDeterminant(matNotOK, matNotOK.length)); + }); + + it('should return appropriate determinant for 3x3 matrix', () => { + assert.equal(matrixDeterminant(matOK1, matOK1.length), -48); + }); + + it('should return appropriate determinant for 4x4 matrix', () => { + assert.equal(matrixDeterminant(matOK2, matOK2.length), 347); + }); +});