title: Calculating the Determinant for a 4x4 matrix - (The RayTracer Challenge) - Javascript
body: <p>I am trying to write a raytracer in Javascript/Canvas, working from "The Ray Tracer Challenge" (Jamis Buck). I wrote code that successfully calculated the determinant of a 3x3 matrix, but it failed for a 4x4 matrix, so I deleted the code, and instead have the following code I converted from C code. (The compiled C version works.) It doesn't come up with the correct determinant for a 4x4 input matrix, even though it is ported from C, where it DOES work.</p>
  
  <p>What am I doing wrong? What am I missing?</p>
  
  <p>(I have included the original, working, C code at the bottom.)</p>
  
  <pre><code>"use strict";
  // HELPER FUNCTION
  
  function initArray(rows, cols)  {
  
  var result = [];
  
  for (var r = 0; r &lt; rows; r++)  {
  
      result[r] = [];
  
      for (var c = 0; c &lt; 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 &lt; n; row++) 
  { 
      for (var col = 0; col &lt; n; col++) 
      { 
          // Copying into temporary matrix only those element 
          // which are not in given row and column 
          if (row != p &amp;&amp; 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 &lt; 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;
  
  /* 4x4 TEST MATRIX
  
      -2,    -8,    3,    5
      -3,     1,    7,    3
       1,     2,   -9,    6
       6,     7,    7,   -9
  
  */
  
  var determinant = determinantOfMatrix(m, 4 /*m.length*/);
  
  alert("determinant = " + determinant); // SHOULD BE -4071
  }
  </code></pre>
  
  <p>//---------------------- BELOW IS THE C CODE, WHICH WORKS --------</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  // 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 &lt; n; row++) 
  { 
      for (int col = 0; col &lt; n; col++) 
      { 
          // Copying into temporary matrix only those element 
          // which are not in given row and column 
          if (row != p &amp;&amp; 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 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 first row 
  for (int f = 0; f &lt; n; f++) 
  { 
      // Getting Cofactor of mat[0][f] 
      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; 
  } 
  
  
  // Driver program to test 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; 
  } 
  </code></pre>