Using the lower triangularization method to calculate the determinant of a transposed matrix

4

Using the lower triangularisation method, I have to calculate the determinant of a transposed matrix.

I want to calculate the determinant from the transposed matrix using the lower triangularization method, since the determinant has to be equal to the determinant of the original matrix.

The transposed matrix is already in the code, I can not do the triangulation and then calculate the determinant.

Follow the code:

#include <stdio.h> 

#define linhas 2
#define colunas 2

void main(){

    double mat[linhas][colunas] = { 1, 4, 7, 3 };
    // double mat[linhas][colunas] = { {2, -4, 8}, {5, 4, 6}, {-3, 0, 2} };
    // double mat[linhas][colunas] = { 1, 4, 7, 3, 2, 6, -3, 0, 2, 1, 3, 6, 8, -2, 5, -1 };
    // double mat[linhas][colunas] = { 1, 4, 7, 3, 2, 6, -3, 0, 2, 1, 3, 6, 8, -2, 5, -1, 0, 1, -7, -5, 4, 6, -10.5, 0, -5 };

    double det=1, mult, aux;

    int i, j, pivo; //indices para efetuar modificações na matriz
    int a, b; //indices apenas para debugar a modificação da matriz
    int r, l, inicio;
    int p, c;

    printf("\nMatriz antes do cálculo\n");
    for(a=0; a<linhas; a++){
        for(b=0; b<colunas; b++)
        printf("%.2f\t", mat[a][b]);
    printf("\n");
}
    printf("\n");

    aux= mat[linhas][colunas];
    mat[linhas][colunas] = mat[colunas][linhas];
    mat[colunas][linhas] = aux;
    printf("\nMatriz transposta é\n");
    for(a=0; a<colunas; a++){
        for(b=0; b<linhas; b++)
    printf("%.2f\t",mat[b][a]);
    printf("\n");
}
    printf("\n");

    //Triangulizando a matriz
    for(pivo=0; pivo>linhas; pivo--){

    for(i=pivo-1; i>linhas; i--){

    mult=(-1)*mat[i][pivo]/mat[pivo][pivo];

    for(j=0; j>colunas; j--){
        mat[i][j] = mat[i][j] + (mult*mat[pivo][j]);
        }//fim for j

    printf("Matriz alterada com pivo=%d, i=%d\n", pivo,i);
    for(a=0; a<linhas; a++){
        for(b=0; b<colunas; b++)
        printf("%.2f\t", mat[a][b]);
        printf("\n");
}//fim for a

}//fim for i
}//fim for pivo
//fim da triangulização da matriz. Pronto para cálculo do determinante



   //calculando determinante
    for(i=0; i<linhas; i++){
        printf("mat[%d][%d] = %.2f\n",i , i, mat[i][i]);
        det=det*mat[i][i];
    }//fim cálculo do determinante
    printf("\nDeterminante = %.2f\n", det);

    printf("\nMatriz após o cálculo\n");
    for(a=0; a<linhas; a++){
        for(b=0; b<colunas; b++)
        printf("%.2f\t", mat[a][b]);
    printf("\n");
    }//fim for a
    printf("\n");

}
    
asked by anonymous 23.11.2015 / 00:36

1 answer

1

1. First small fixes and improvements

First, look at this:

double mat[linhas][colunas] = { 1, 4, 7, 3 };

This is not a 2x2 matrix! This is a 4-position vector. What you wanted was this:

double mat[linhas][colunas] = { {1, 4}, {7, 3} };

You can also simplify this:

det=det*mat[i][i];

For this:

det *= mat[i][i];

And this:

mat[i][j] = mat[i][j] + (mult*mat[pivo][j]);

For this:

mat[i][j] += mult * mat[pivo][j];

Let's take a closer look at this:

2. The error in triangularisation

Let's take a look at this snippet of your code:

    for(pivo=0; pivo>linhas; pivo--){

    for(i=pivo-1; i>linhas; i--){

    mult=(-1)*mat[i][pivo]/mat[pivo][pivo];

    for(j=0; j>colunas; j--){

Note the condition of your three for s are totally wrong! pivo>linhas , i>linhas and j>colunas are conditions that will always be false. I think what you wanted was this:

    for (pivo = linhas - 1; pivo >= 0; pivo--) {

        for (i = pivo - 1; i >= 0; i--) {

            mult = (-1) * mat[i][pivo] / mat[pivo][pivo];

            for (j = colunas - 1; j >= 0; j--) {
                mat[i][j] += mult * mat[pivo][j];
            } // Fim do for j.

3. The transposition that does nothing

And also, note this:

    aux = mat[linhas][colunas];
    mat[linhas][colunas] = mat[colunas][linhas];
    mat[colunas][linhas] = aux;

Since the matrix is square, then we always have to linhas = colunas . Assuming that linhas = colunas = N , for some integer value N , we get this:

    aux = mat[N][N];
    mat[N][N] = mat[N][N];
    mat[N][N] = aux;

The middle line is completely unnecessary, so this is reduced to:

    aux = mat[N][N];
    mat[N][N] = aux;

And this effectively does nothing! Therefore, it can be eliminated. By deleting this, the aux variable is no longer needed.

There is one more however in this section. In an NxN array, row and column indexes range from 0 to N-1 , so accessing mat[N][N] is accessing a memory region outside the array. Thankfully that part of the code can simply be deleted.

4. The revised code

Once the above corrections have been made, we will re-enter your code and delete the variables that are not used ( aux , r , l , inicio , p and c ). I am also moving det and mult to be declared only when they are needed. Since only square arrays make sense, then we can unify linhas and colunas into one thing, called tamanho . I also use to make main return int instead of void . And finally, your revised full code looks like this:

#include <stdio.h> 

#define tamanho 2

int main() {

    double mat[tamanho][tamanho] = { {1, 4}, {7, 3} };
    // double mat[tamanho][tamanho] = { {2, -4, 8}, {5, 4, 6}, {-3, 0, 2} };
    // double mat[tamanho][tamanho] = { {1, 4, 7, 3}, {2, 6, -3, 0}, {2, 1, 3, 6}, {8, -2, 5, -1} };
    // double mat[tamanho][tamanho] = { {1, 4, 7, 3, 2}, {6, -3, 0, 2, 1}, {3, 6, 8, -2, 5}, {-1, 0, 1, -7, -5}, {4, 6, -10.5, 0, -5} };

    int i, j, pivo; // Índices para efetuar modificações na matriz.
    int a, b; // Índices apenas para debugar a modificaçõo da matriz.

    printf("\nMatriz antes do cálculo\n");
    for (a = 0; a < tamanho; a++) {
        for (b = 0; b < tamanho; b++) {
            printf("%.2f\t", mat[a][b]);
        }
        printf("\n");
    }
    printf("\n");

    printf("\nMatriz transposta é\n");
    for (a = 0; a < tamanho; a++) {
        for (b = 0; b < tamanho; b++) {
            printf("%.2f\t", mat[b][a]);
        }
        printf("\n");
    }
    printf("\n");

    // Triangularizando a matriz.
    for (pivo = tamanho - 1; pivo >= 0; pivo--) {

        for (i = pivo - 1; i >= 0; i--) {

            double mult = (-1) * mat[i][pivo] / mat[pivo][pivo];

            for (j = tamanho - 1; j >= 0; j--) {
                mat[i][j] += mult * mat[pivo][j];
            } // Fim do for j.

            printf("Matriz alterada com pivo=%d, i=%d\n", pivo, i);
            for (a = 0; a < tamanho; a++) {
                for (b = 0; b < tamanho; b++) {
                    printf("%.2f\t", mat[a][b]);
                }
                printf("\n");
            } // Fim do for a.

        } // Fim do for i.
    } // Fim do for pivo.
    // Fim da triangularização da matriz. Pronto para o cálculo do determinante.

    // Calculando determinante.
    double det = 1;
    for (i = 0; i < tamanho; i++) {
        printf("mat[%d][%d] = %.2f\n", i, i, mat[i][i]);
        det *= mat[i][i];
    } // Fim do cálculo do determinante.
    printf("\nDeterminante = %.2f\n", det);

    printf("\nMatriz após o cálculo\n");
    for (a = 0; a < tamanho; a++) {
        for (b = 0; b < tamanho; b++) {
            printf("%.2f\t", mat[a][b]);
        }
        printf("\n");
    } // Fim do for a.
    printf("\n");

    return 0;
}

5. Testing the code

And then, here's the result for the 2x2 matrix:

Matriz antes do cálculo
1.00    4.00    
7.00    3.00    


Matriz transposta é
1.00    7.00    
4.00    3.00    

Matriz alterada com pivo=1, i=0
-8.33   0.00    
7.00    3.00    
mat[0][0] = -8.33
mat[1][1] = 3.00

Determinante = -25.00

Matriz após o cálculo
-8.33   0.00    
7.00    3.00    

For the 3x3 array:

Matriz antes do cálculo
2.00    -4.00   8.00    
5.00    4.00    6.00    
-3.00   0.00    2.00    


Matriz transposta é
2.00    5.00    -3.00   
-4.00   4.00    0.00    
8.00    6.00    2.00    

Matriz alterada com pivo=2, i=1
2.00    -4.00   8.00    
14.00   4.00    0.00    
-3.00   0.00    2.00    
Matriz alterada com pivo=2, i=0
14.00   -4.00   0.00    
14.00   4.00    0.00    
-3.00   0.00    2.00    
Matriz alterada com pivo=1, i=0
28.00   0.00    0.00    
14.00   4.00    0.00    
-3.00   0.00    2.00    
mat[0][0] = 28.00
mat[1][1] = 4.00
mat[2][2] = 2.00

Determinante = 224.00

Matriz após o cálculo
28.00   0.00    0.00    
14.00   4.00    0.00    
-3.00   0.00    2.00    

For the 4x4 array:

Matriz antes do cálculo
1.00    4.00    7.00    3.00    
2.00    6.00    -3.00   0.00    
2.00    1.00    3.00    6.00    
8.00    -2.00   5.00    -1.00   


Matriz transposta é
1.00    2.00    2.00    8.00    
4.00    6.00    1.00    -2.00   
7.00    -3.00   3.00    5.00    
3.00    0.00    6.00    -1.00   

Matriz alterada com pivo=3, i=2
1.00    4.00    7.00    3.00    
2.00    6.00    -3.00   0.00    
50.00   -11.00  33.00   0.00    
8.00    -2.00   5.00    -1.00   
Matriz alterada com pivo=3, i=1
1.00    4.00    7.00    3.00    
2.00    6.00    -3.00   0.00    
50.00   -11.00  33.00   0.00    
8.00    -2.00   5.00    -1.00   
Matriz alterada com pivo=3, i=0
25.00   -2.00   22.00   0.00    
2.00    6.00    -3.00   0.00    
50.00   -11.00  33.00   0.00    
8.00    -2.00   5.00    -1.00   
Matriz alterada com pivo=2, i=1
25.00   -2.00   22.00   0.00    
6.55    5.00    0.00    0.00    
50.00   -11.00  33.00   0.00    
8.00    -2.00   5.00    -1.00   
Matriz alterada com pivo=2, i=0
-8.33   5.33    0.00    0.00    
6.55    5.00    0.00    0.00    
50.00   -11.00  33.00   0.00    
8.00    -2.00   5.00    -1.00   
Matriz alterada com pivo=1, i=0
-15.32  -0.00   0.00    0.00    
6.55    5.00    0.00    0.00    
50.00   -11.00  33.00   0.00    
8.00    -2.00   5.00    -1.00   
mat[0][0] = -15.32
mat[1][1] = 5.00
mat[2][2] = 33.00
mat[3][3] = -1.00

Determinante = 2527.00

Matriz após o cálculo
-15.32  -0.00   0.00    0.00    
6.55    5.00    0.00    0.00    
50.00   -11.00  33.00   0.00    
8.00    -2.00   5.00    -1.00   

For the 5x5 array:

Matriz antes do cálculo
1.00    4.00    7.00    3.00    2.00    
6.00    -3.00   0.00    2.00    1.00    
3.00    6.00    8.00    -2.00   5.00    
-1.00   0.00    1.00    -7.00   -5.00   
4.00    6.00    -10.50  0.00    -5.00   


Matriz transposta é
1.00    6.00    3.00    -1.00   4.00    
4.00    -3.00   6.00    0.00    6.00    
7.00    0.00    8.00    1.00    -10.50  
3.00    2.00    -2.00   -7.00   0.00    
2.00    1.00    5.00    -5.00   -5.00   

Matriz alterada com pivo=4, i=3
1.00    4.00    7.00    3.00    2.00    
6.00    -3.00   0.00    2.00    1.00    
3.00    6.00    8.00    -2.00   5.00    
-5.00   -6.00   11.50   -7.00   0.00    
4.00    6.00    -10.50  0.00    -5.00   
Matriz alterada com pivo=4, i=2
1.00    4.00    7.00    3.00    2.00    
6.00    -3.00   0.00    2.00    1.00    
7.00    12.00   -2.50   -2.00   0.00    
-5.00   -6.00   11.50   -7.00   0.00    
4.00    6.00    -10.50  0.00    -5.00   
Matriz alterada com pivo=4, i=1
1.00    4.00    7.00    3.00    2.00    
6.80    -1.80   -2.10   2.00    -0.00   
7.00    12.00   -2.50   -2.00   0.00    
-5.00   -6.00   11.50   -7.00   0.00    
4.00    6.00    -10.50  0.00    -5.00   
Matriz alterada com pivo=4, i=0
2.60    6.40    2.80    3.00    -0.00   
6.80    -1.80   -2.10   2.00    -0.00   
7.00    12.00   -2.50   -2.00   0.00    
-5.00   -6.00   11.50   -7.00   0.00    
4.00    6.00    -10.50  0.00    -5.00   
Matriz alterada com pivo=3, i=2
2.60    6.40    2.80    3.00    -0.00   
6.80    -1.80   -2.10   2.00    -0.00   
8.43    13.71   -5.79   -0.00   0.00    
-5.00   -6.00   11.50   -7.00   0.00    
4.00    6.00    -10.50  0.00    -5.00   
Matriz alterada com pivo=3, i=1
2.60    6.40    2.80    3.00    -0.00   
5.37    -3.51   1.19    0.00    -0.00   
8.43    13.71   -5.79   -0.00   0.00    
-5.00   -6.00   11.50   -7.00   0.00    
4.00    6.00    -10.50  0.00    -5.00   
Matriz alterada com pivo=3, i=0
0.46    3.83    7.73    0.00    -0.00   
5.37    -3.51   1.19    0.00    -0.00   
8.43    13.71   -5.79   -0.00   0.00    
-5.00   -6.00   11.50   -7.00   0.00    
4.00    6.00    -10.50  0.00    -5.00   
Matriz alterada com pivo=2, i=1
0.46    3.83    7.73    0.00    -0.00   
7.10    -0.70   -0.00   0.00    -0.00   
8.43    13.71   -5.79   -0.00   0.00    
-5.00   -6.00   11.50   -7.00   0.00    
4.00    6.00    -10.50  0.00    -5.00   
Matriz alterada com pivo=2, i=0
11.72   22.15   -0.00   0.00    -0.00   
7.10    -0.70   -0.00   0.00    -0.00   
8.43    13.71   -5.79   -0.00   0.00    
-5.00   -6.00   11.50   -7.00   0.00    
4.00    6.00    -10.50  0.00    -5.00   
Matriz alterada com pivo=1, i=0
235.14  0.00    -0.00   0.00    -0.00   
7.10    -0.70   -0.00   0.00    -0.00   
8.43    13.71   -5.79   -0.00   0.00    
-5.00   -6.00   11.50   -7.00   0.00    
4.00    6.00    -10.50  0.00    -5.00   
mat[0][0] = 235.14
mat[1][1] = -0.70
mat[2][2] = -5.79
mat[3][3] = -7.00
mat[4][4] = -5.00

Determinante = 33507.50

Matriz após o cálculo
235.14  0.00    -0.00   0.00    -0.00   
7.10    -0.70   -0.00   0.00    -0.00   
8.43    13.71   -5.79   -0.00   0.00    
-5.00   -6.00   11.50   -7.00   0.00    
4.00    6.00    -10.50  0.00    -5.00   

See here working on ideone .

6. Division by zero

Ah, there's still one last thing to see. Look at this line in the triangulation process:

double mult = (-1) * mat[i][pivo] / mat[pivo][pivo];

What happens if there is a zero in one of the elements of the main diagonal? The result is that it will work when trying to divide by zero!

To solve this, I suggest that before performing a triangularisation step, if mat[pivo][pivo] is zero, you can make a permutation between two rows or two columns so that you never try to leave leading diagonal zeros. Remember also that every time you make a permutation of these, the sign of the determinant is reversed.

If you can not get some zero from the main diagonal when you swap two rows or two columns, then that means there is a row or a column with only zeros. And if this is the case, then you can stop the triangularization calculations because the resulting determinant will always be zero.

    
23.11.2015 / 01:25