Cálculo de Determinante de Matriz Quadrada 2x2 e 3x3. HELP!

Olá pessoal
Estou querendo fazer um método em java para calcular a determinante de uma matriz 2x2 / 3x3.
Antes de postar minha dúvida fiz várias buscas pelo google e pelo GUJ, mas não encontrei nada que me ajude.
O mais próximo que encontrei que me ajudou foi um algoritimo em português estruturado, mas que ao que parece está errado.
O algoritimo que achei é o seguinte:

Programa Determinante Matriz Quadrada Ordem ?n?
Programa DeterminanteMatrizN;
Inicio;
      { Definição de Variáveis e Tipos Globais }
      Tipo       Mat = Matriz[1..n,1..n] de Inteiros;
      Mat:       M;
      Inteiro:   Det, n, x, y;
{ Modulo para Calculo de Determinante de Matriz Quadrada de ordem N}
Modulo Determinante(Inteiro: Det, n; Matriz[1..n,1..n] de Inteiros: M; Inteiro: L, C;);
  Inicio;
      { Definição de Variáveis Locais }
      Tipo       Mat = Matriz[1..n-1,1..n-1] de inteiros;
      Tipo       Vet = vetor[1..n] de inteiros;
      Vet:       D1, D2;
      Mat:       MA;
      Inteiro:   X1, X2, Y1, Y2, Det2, Cof;
      Inteiro:   Det1, Det2, x, y, z, w, n;
      Escolha
            Caso n = 1:                           { Determinante Matriz ordem 1}
                 Det ← M[1,1];
            Caso n>1 e n<4:                       { Determinante Matriz ordem 2 ou 3}
                 Det1 ← 0;
                 Det2 ← 0;
                 Para x = 0 até n-1
                        D1[x+1] ← 1;
                        D2[x+1] ← 1;
                        Para y = 1 até n
                               z ← x + y;
                               Se ( z > n ) então                  { Se coluna > n }
                                     z ← z ? n;                    { pega a partir da col 1 }
                               FimSe;
                               D1[x+1] ← D1[x+1] * M[y,z];         { Diagonal Principal }
                               w ← n ? z + 1;
                               D2[x+1] ← D2[x+1] * M[y,w];         { Diagonal Secundária }
                        FimPara;
                        Det1 ← Det1 + D1[x+1];                     { Diagonal Principal }
                        Det2 ← Det2 + D2[x+1];                     { Diagonal Secundária }
                 FimPara;
                 Det ← Det1 ? Det2;
           Caso Contrário:                    { Determinante Matriz ordem > 3}
                 Se L > 0 então                     { Reduz a matriz ... }
                       X2 ← 0;
                       Para X1 = 1 até n
                            X2 ← X2 + 1;
                            Se X1 <> L então        { ... tirando a linha L ... }
                                  Y2 ← 0;
                                  Para Y1 = 1 até n
                                         Y2 ← Y2 + 1;
                                         Se Y2 <> C então          { ... e a coluna C ... }
                                              MA[X2, Y2] ← M[X1,Y1];
                                         FimSe;
                                  FimPara;
                            FimSe;
                       FimPara;
                       d ← n ? 1;                   { ... e diminui a ordem da matriz. }
                 Senão      { para a primeira vez }
                       MA ← M;
                       d ← n;
                 FimSe;
                 Det ← 0;                           { Calcula Determinante por Laplace }
                 Para X2= 1 até d
                       Determinante(Det2, d, MA, 1, X2);         { Det. da matriz reduzida}
                       Cof ← POT(-1,1+X2) * Det2;                { Calculo do Cofator }
                       Det ← Det + M[1,X2] * Cof;                { Teorema de Laplace }
                 FimPara;
           FimEscolha;
  Fim;
     { Programa Principal, Carrega a Matriz e Calcula o Determinante }
     { Dimensão da matriz }
     Leia(n);
     { Carrega a matriz }
     Para x = 1 até n
           Para y = 1 até n
                 Leia(M[x,y]);
           FimPara;
     FimPara;
     { Calcula Determinante }
     Determinante(Det, n, M, 0, 0);
     Escreve(?O Determinante é :?, Det);
Fim.

Mas ele dá erro ao executar, tanto com matriz 2x2 quanto 3x3. Dá erro de "index out of bounds".

Para matriz 2x2 eu consegui fazer, mas para 3x3 não consegui chegar a nenhuma conclusão.
Até tem um método que faz o calculo manualmente, mas não consigo pensar em uma lógica para transformá-lo em algo mais prático.
Segue o método de cálculo manual e o que eu tentei fazer que não deu certo:

    public static float matrizCalculaDeterminanteManual(float[][] matriz)
throws Exception {
if (!ckMatrizQuadradaValido(matriz))
   throw new Exception("Matriz de tamanho inválido");
float determinante = 0;
if (matriz.length == 2) {
   determinante = (matriz[0][0] * matriz[1][1]) - (matriz[0][1] * matriz[1][0]);
} if (matriz.length == 3) {
   float principal =  (matriz[0][0] * matriz[1][1] * matriz[2][2]);
   float secundaria =  (matriz[2][0] * matriz[1][1] * matriz[0][2]);
   principal += (matriz[0][1] * matriz[1][2] * matriz[2][0]);
   secundaria += (matriz[2][1] * matriz[1][2] * matriz[0][0]);    
   principal += (matriz[0][2] * matriz[1][0] * matriz[2][1]);
   secundaria += (matriz[2][2] * matriz[1][0] * matriz[0][1]);
determinante = principal - secundaria;
} else {
   throw new Exception("Matrizez de ordem maior do que 3 não são suportadas por enquanto");
}
return determinante;
    }
// ----------------------------------------------------------------------------------------------------------------------------------------------
    public static float matrizCalculaDeterminante(float[][] matriz)
throws Exception {
if (!ckMatrizQuadradaValido(matriz))
   throw new Exception("Matriz de tamanho inválido");
int ordem = matriz.length;
float determinante = 0;
float det1 = 1;
float det2 = 1;
float[] diagonalPrincipal = new float[ordem];
float[] diagonalSecundaria = new float[ordem];
switch (ordem) {
   case 1: {
determinante = matriz[0][0];
       break;
   }
   case 2: {
for (int coluna = 0; coluna < ordem; coluna++) {
   diagonalPrincipal[coluna] = 1;
   diagonalSecundaria[coluna] = 1;
   for (int linhaPrincipal = 0; linhaPrincipal < ordem; linhaPrincipal++) {
int linhaSecundaria = (ordem-1) - linhaPrincipal; 
if (linhaPrincipal == coluna)
   diagonalPrincipal[coluna] = diagonalPrincipal[coluna] * matriz[linhaPrincipal][coluna]; // diagonal principal
if (linhaSecundaria == ((ordem-1)-coluna))
   diagonalSecundaria[coluna] = diagonalSecundaria[coluna] * matriz[linhaSecundaria][coluna]; // diagonal secundaria
   }
   det1 = det1 * diagonalPrincipal[coluna]; // diagonal principal
   det2 = det2 * diagonalSecundaria[coluna]; // diagonal secundaria
}
determinante = det1 - det2;
break;
   }
   case 3: {
for (int coluna = 0; coluna < ordem; coluna++) {
   diagonalPrincipal[coluna] = 1;
   diagonalSecundaria[coluna] = 1;
   for (int linhaPrincipal = 0; linhaPrincipal < ordem; linhaPrincipal++) {
int linhaSecundaria = (ordem-1) - linhaPrincipal; 
if (linhaPrincipal == coluna)
   diagonalPrincipal[coluna] = diagonalPrincipal[coluna] * matriz[linhaPrincipal][coluna]; // diagonal principal
if (linhaSecundaria == ((ordem-1)-coluna))
   diagonalSecundaria[coluna] = diagonalSecundaria[coluna] * matriz[linhaSecundaria][coluna]; // diagonal secundaria
   }
   det1 = det1 * diagonalPrincipal[coluna]; // diagonal principal
   det2 = det2 * diagonalSecundaria[coluna]; // diagonal secundaria
}
determinante = det1 - det2;
break;
   }
   default: {// maior que 3
throw new Exception("Matrizez de ordem maior do que 3 não são suportadas por enquanto");
//break;
   }
        }


return determinante;
    }

Acho que nosso maior problema aqui é matemática, não?

Se não me engano, os cálculos que eu fazia ano passado eram:
2x2:
diagonal esquerda pra direita somada com o inverso da diagonal direita pra esquerda
3x3:
faz uma matriz 5x3, copiando as 3 primeiras colunas, e a 4a e 5a eram a 1a e a 2a (de novo)
realiza a operação da 2x2 seis vezes (três esquerda pra direita somadas, somada com o inverso das três direita pra esquerda, somadas)

eu nem cheguei a testar esse código por não ter mais o livro de matemática com os exemplos, se não funcionar dá um toque ai ‘-’

    private static int determinanteQuadrado (int matriz[][]){
        int determinante = 0;

        if (matriz.length == 2)
            determinante = (matriz[0][0] * matriz[1][1]) + (-1 * (matriz[1][0] * matriz[0][1]));
        else if (matriz.length == 3){
            // define nova matriz que vou usar regra de Sarrus
            int sarrus[][] = new int [5][3];
            int ltr, rtl; // left to right, right to left (tá dentro da matemática de Sarrus)

            // criar matriz de sarrus
            for (int i = 0; i < 5; i ++){
                if (i < 3)
                    System.arraycopy(matriz[i], 0, sarrus[i], 0, 3); // copia as 3 primeiras colunas
                else
                    System.arraycopy(matriz[i - 3], 0, sarrus[i], 0, 3); // copia as 2 últimas colunas
            }

            ltr = sarrus[0][0] * sarrus[1][1] * sarrus[2][2];
            ltr += sarrus[1][0] * sarrus[2][1] * sarrus [3][2];
            ltr += sarrus[2][0] * sarrus[3][2] * sarrus[4][2];

            rtl = -1 * sarrus[2][0] * sarrus[1][1] * sarrus[0][2];
            rtl += -1 * sarrus[3][0] * sarrus[2][1] * sarrus[1][2];
            rtl += -1 * sarrus[4][0] * sarrus[3][1] * sarrus[2][2];

            determinante = ltr + rtl;
        }

        return determinante;
    }

eu só percebi depois que seu código eram com float, mas transformar ai tá fácil n.n

Mephy,

Obrigado pela resposta.
Na verdade o que eu estou procurando, é uma forma de transformar o algorimo que está em português estruturado em java ou linguagem C.
A parte que resolve a matriz quadrada 3x3 é em sarrus, isso eu já sabia, mas este algoritimo resolve sem a criação das colunas adicionais. Eu queria é entender a lógica, mas está dificil.
Acredito que a minha dificuldade seja porque o algoritimo leva em consideração vetores e matrizes que iniciam em posição 1 ao invés de 0. Isso está dando um nó na minha cabeça para transformar/entender o algoritimo.

Se alguém tiver um temponho disponivel para tentar entender a logica do algoritimo que eu postei e transformá-lo em uma linguagem onde vetores e matrizes iniciam na posição 0 em vez de 1.

Agradecido desde já pela futura ajuda e agradeço ao Mephy pela tentativa.

Att,

Lex