Skip to content

Commit a24450a

Browse files
piyushk77appgurueu
andauthored
feat: add determinant algorithm (TheAlgorithms#1438)
* feat: add determinant calculating algorithm * test: add self-tests for determinant algorithm * chore: add wikipedia info link * fix: change initialization to zero * fix: add error throw and general code improvements * fix: add error try and catch * fix: seperate the test loops of error cases * clean up a bit --------- Co-authored-by: Lars Müller <[email protected]>
1 parent 13161bd commit a24450a

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

Maths/Determinant.js

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/**
2+
* Given a square matrix, find its determinant using Laplace Expansion.
3+
* Time Complexity : O(n!)
4+
*
5+
* For more info: https://en.wikipedia.org/wiki/Determinant
6+
*
7+
* @param {number[[]]} matrix - Two dimensional array of integers.
8+
* @returns {number} - An integer equal to the determinant.
9+
*
10+
* @example
11+
* const squareMatrix = [
12+
* [2,3,4,6],
13+
* [5,8,9,0],
14+
* [7,4,3,9],
15+
* [4,0,2,1]
16+
* ];
17+
*
18+
* const result = determinant(squareMatrix);
19+
* // The function should return 858 as the resultant determinant.
20+
*/
21+
22+
const subMatrix = (matrix, i, j) => {
23+
let matrixSize = matrix[0].length
24+
if (matrixSize === 1) {
25+
return matrix[0][0]
26+
}
27+
let subMatrix = []
28+
for (let x = 0; x < matrixSize; x++) {
29+
if (x === i) {
30+
continue
31+
}
32+
subMatrix.push([])
33+
for (let y = 0; y < matrixSize; y++) {
34+
if (y === j) {
35+
continue
36+
}
37+
subMatrix[subMatrix.length - 1].push(matrix[x][y])
38+
}
39+
}
40+
return subMatrix
41+
}
42+
43+
const isMatrixSquare = (matrix) => {
44+
let numRows = matrix.length
45+
for (let i = 0; i < numRows; i++) {
46+
if (numRows !== matrix[i].length) {
47+
return false
48+
}
49+
}
50+
return true
51+
}
52+
53+
const determinant = (matrix) => {
54+
if (
55+
!Array.isArray(matrix) ||
56+
matrix.length === 0 ||
57+
!Array.isArray(matrix[0])
58+
) {
59+
throw new Error('Input is not a valid 2D matrix.')
60+
}
61+
if (!isMatrixSquare(matrix)) {
62+
throw new Error('Square matrix is required.')
63+
}
64+
let numCols = matrix[0].length
65+
if (numCols === 1) {
66+
return matrix[0][0]
67+
}
68+
let result = 0
69+
let setIndex = 0
70+
for (let i = 0; i < numCols; i++) {
71+
result +=
72+
Math.pow(-1, i) *
73+
matrix[setIndex][i] *
74+
determinant(subMatrix(matrix, setIndex, i))
75+
}
76+
return result
77+
}
78+
export { determinant }

Maths/test/Determinant.test.js

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { expect } from 'vitest'
2+
import { determinant } from '../Determinant'
3+
describe('Determinant', () => {
4+
test.each([
5+
[
6+
[
7+
[8, 1, 6],
8+
[1, 2, 3],
9+
[4, 7, 5]
10+
],
11+
-87
12+
],
13+
[
14+
[
15+
[2, 1, 0, 2],
16+
[1, 2, 4, 3],
17+
[0, 4, 7, 5],
18+
[4, 7, 9, 8]
19+
],
20+
25
21+
],
22+
[
23+
[
24+
[5, 9],
25+
[3, 7]
26+
],
27+
8
28+
],
29+
[
30+
[
31+
[7, 5, 1, 4, 3],
32+
[6, 8, 7, 9, 6],
33+
[9, 8, 0, 4, 7],
34+
[0, 3, 4, 7, 9],
35+
[3, 6, 2, 8, 8]
36+
],
37+
2476
38+
],
39+
[[[23]], 23]
40+
])(
41+
'Should return the determinant of the square matrix.',
42+
(matrix, expected) => {
43+
expect(determinant(matrix)).toEqual(expected)
44+
}
45+
)
46+
47+
test.each([
48+
[
49+
[
50+
[1, 6],
51+
[1, 2, 3],
52+
[4, 7, 5]
53+
],
54+
'Square matrix is required.'
55+
],
56+
[[1, 3, 2, [5, 8, 6], 3], 'Input is not a valid 2D matrix.']
57+
])(
58+
'Should return the error message.',
59+
(matrix, expected) => {
60+
expect(() => determinant(matrix)).toThrowError(expected)
61+
}
62+
)
63+
})

0 commit comments

Comments
 (0)