title: Calculating matrix determinant
body: <p>I am trying to calculate the determinant of a matrix (of any size), for self coding / interview practice. My first attempt is using recursion and that leads me to the following implementation:  </p>
  
  <pre><code>import java.util.Scanner.*;
  public class Determinant {
  
      double A[][];
      double m[][];
      int N;
      int start;
      int last;
  
      public Determinant (double A[][], int N, int start, int last){
              this.A = A;
              this.N = N;
              this.start = start;
              this.last = last;
      }
  
      public double[][] generateSubArray (double A[][], int N, int j1){
              m = new double[N-1][];
              for (int k=0; k&lt;(N-1); k++)
                      m[k] = new double[N-1];
  
              for (int i=1; i&lt;N; i++){
                    int j2=0;
                    for (int j=0; j&lt;N; j++){
                        if(j == j1)
                              continue;
                        m[i-1][j2] = A[i][j];
                        j2++;
                    }
                }
              return m;
      }
      /*
       * Calculate determinant recursively
       */
      public double determinant(double A[][], int N){
          double res;
  
          // Trivial 1x1 matrix
          if (N == 1) res = A[0][0];
          // Trivial 2x2 matrix
          else if (N == 2) res = A[0][0]*A[1][1] - A[1][0]*A[0][1];
          // NxN matrix
          else{
              res=0;
              for (int j1=0; j1&lt;N; j1++){
                   m = generateSubArray (A, N, j1);
                   res += Math.pow(-1.0, 1.0+j1+1.0) * A[0][j1] * determinant(m, N-1);
              }
          }
          return res;
      }
  }
  </code></pre>
  
  <p>So far it is all good and it gives me a correct result. Now I would like to optimise my code by making use of multiple threads to calculate this determinant value. 
      I tried to parallelize it using the Java Fork/Join model. This is my approach:</p>
  
  <pre><code>@Override
  protected Double compute() {
       if (N &lt; THRESHOLD) {
           result = computeDeterminant(A, N);
           return result;
       }
  
       for (int j1 = 0; j1 &lt; N; j1++){
            m = generateSubArray (A, N, j1);
            ParallelDeterminants d = new ParallelDeterminants (m, N-1);
            d.fork();
            result += Math.pow(-1.0, 1.0+j1+1.0) * A[0][j1] * d.join();
       }
  
       return result;
  }
  
  public double computeDeterminant(double A[][], int N){
      double res;
  
      // Trivial 1x1 matrix
      if (N == 1) res = A[0][0];
      // Trivial 2x2 matrix
      else if (N == 2) res = A[0][0]*A[1][1] - A[1][0]*A[0][1];
      // NxN matrix
      else{
          res=0;
          for (int j1=0; j1&lt;N; j1++){
               m = generateSubArray (A, N, j1);
               res += Math.pow(-1.0, 1.0+j1+1.0) * A[0][j1] * computeDeterminant(m, N-1);
          }
      }
      return res;
  }
  
  /*
   * Main function
   */
  public static void main(String args[]){
      double res;
      ForkJoinPool pool = new ForkJoinPool();
      ParallelDeterminants d = new ParallelDeterminants();
      d.inputData();
      long starttime=System.nanoTime();
      res = pool.invoke (d);
      long EndTime=System.nanoTime();
  
      System.out.println("Seq Run = "+ (EndTime-starttime)/100000);
      System.out.println("the determinant valaue is  " + res);
  }
  </code></pre>
  
  <p>However after comparing the performance, I found that the performance of the Fork/Join approach is very bad, and the higher the matrix dimension, the slower it becomes (as compared to the first approach). Where is the overhead? Can anyone shed a light on how to improve this?</p>