Currently, I am in the process of developing a raytracer using Javascript/Canvas and following "The Ray Tracer Challenge" by Jamis Buck. Initially, my code successfully computed the determinant of a 3x3 matrix but encountered issues with a 4x4 matrix. As a result, I decided to discard the faulty code and replace it with converted C code. Surprisingly, even though the original C version works perfectly fine, the ported Javascript code fails to produce the correct determinant for a 4x4 input matrix.
I'm puzzled and seeking guidance on what could be going wrong or what essential aspect I might be overlooking.
(The functional C code is provided at the end.)
"use strict";
// HELPER FUNCTION
function initArray(rows, cols) {
var result = [];
for (var r = 0; r < rows; r++) {
result[r] = [];
for (var c = 0; c < cols; c++) {
result[r][c] = 0;
}
}
return result;
}
//--------------------------------
// DETERMINANT
// Function to get cofactor of mat[p][q] in temp[][]. n is current
// dimension of mat[][]
function getCofactor(mat, temp, p, q, n)
{
var i = 0, j = 0;
// Looping for each element of the matrix
for (var row = 0; row < n; row++)
{
for (var col = 0; col < n; col++)
{
// Copying into temporary matrix only those element
// which are not in given row and column
if (row != p && col != q)
{
temp[i][j++] = mat[row][col];
// Row is filled, so increase row index and
// reset col index
if (j == n - 1)
{
j = 0;
i++;
}
}
}
}
return temp;
}
/* Recursive function for finding determinant of matrix.
n is current dimension of mat[][]. */
function determinantOfMatrix(mat, n)
{
var D = 0; // Initialize result
// Base case : if matrix contains single element
if (n == 1)
return mat[0][0];
var temp = initArray(4, 4); // To store cofactors
var sign = 1; // To store sign multiplier
// Iterate for each element of first row
for (var f = 0; f < n; f++)
{
// Getting Cofactor of mat[0][f]
temp = getCofactor(mat, temp, 0, f, n);
D += sign * mat[0][f] * determinantOfMatrix(temp, n - 1);
// terms are to be added with alternate sign
sign = -sign;
}
return D;
}
// Finally, this is how I test it:
function test7() {
var m = initArray(4, 4);
m[0][0] = -2, m[0][1] = -8, m[0][2] = 3, m[0][3] = 5;
m[1][0] = -3, m[1][1] = 1, m[1][2] = 7, m[1][3] = 3;
m[2][0] = 1, m[2][1] = 2, m[2][2] = -9, m[2][3] = 6;
m[3][0] = 6, m[3][1] = 7, m[3][2] = 7, m[3][3] = -9;
var determinant = determinantOfMatrix(m, 4 /*m.length*/);
alert("determinant = " + determinant); // SHOULD BE -4071
}
//------------------------ BELOW IS THE C CODE, WHICH WORKS --------
#include <stdio.h>
// Dimension of input square matrix
#define N 4
// Function to get cofactor of mat[p][q] in temp[][]. n is current
// dimension of mat[][]
void getCofactor(int mat[N][N], int temp[N][N], int p, int q, int n)
{
int i = 0, j = 0;
// Looping for each element of the matrix
for (int row = 0; row < n; row++)
{
for (int col = 0; col < n; col++)
{
// Copying into temporary matrix only those element
// which are not in given row and column
if (row != p && col != q)
{
temp[i][j++] = mat[row][col];
// Row is filled, so increase row index and
// reset col index
if (j == n - 1)
{
j = 0;
i++;
}
}
}
}
}
/* Recursive function for finding determinant of matrix.
n is current dimension of mat[][]. */
int determinantOfMatrix(int mat[N][N], int n)
{
int D = 0; // Initialize result
// Base case: if matrix contains a single element
if (n == 1)
return mat[0][0];
int temp[N][N]; // To store cofactors
int sign = 1; // To store sign multiplier
// Iterate for each element of the first row
for (int f = 0; f < n; f++)
{
// Getting Cofactor of mat[0][f]
getCofactor(mat, temp, 0, f, n);
D += sign * mat[0][f] * determinantOfMatrix(temp, n - 1);
// The terms are to be added with an alternate sign
sign = -sign;
}
return D;
}
// Driver program to test the above functions
int main()
{
int mat[N][N] = {{-2, -8, 3, 5},
{-3, 1, 7, 3},
{1, 2, -9, 6},
{-6, 7, 7, -9}
};
printf("Determinant of the matrix is: %d", determinantOfMatrix(mat, N));
return 0;
}