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.