A jucald.h contém uma função para cálculo de determinante de matrizes de qualquer dimensão. Utiliza função recursiva, e dá uma aula de como funcionam ponteiros para matrizes.
/*---------------------------------------------------------------------------
jucald.h
Autor: Jefferson dos Santos Felix, Abril 2004
Este header contem uma funcao que efetua o calculo de determinante de matrizes
de qualquer dimensao. Ela utiliza o principio de que a determinante de uma
matriz eh a soma das determinantes de matrizes menores, baseadas na matriz
principal. Como se pode notar, trata-se de uma funcao recursiva, por isso o
nome (hehe): Jucald (sigla de Jucald, Um CALculador de Determinantes).
Sintaxe da funcao:
long determ(int *m, int s);
- m: matriz
- s: a sua dimensao (sxs)
A funcao determ() retorna o valor da determinante (em inteiro longo).
Obs: Alteracoes poderao ser feitas livremente no codigo se houver a necessidade
de se utilizar numeros reais (float) na matriz.
Exemplo de programa que usa jucald.h com uma matriz 3x3:
---------------------------------------------------------------------------
// exemplo.c
#include <stdio.h>
#include "jucald.h"
int main(void)
{
int m[3][3], x, y;
for(x = 0; x < 3; x++)
for(y = 0; y < 3; y++)
{
printf("MATRIZ[%d][%d]: ", x+1, y+1);
scanf("%d", &m[x][y]);
}
printf("Determinante: %d\n", determ(*m, 3));
return 0;
}
---------------------------------------------------------------------------
Observacao:
-----------
Lembramos que a funcao determ() pede um ponteiro *m e matrizes geralmente sao
ponteiros do tipo **m. Para corrigir possiveis warnings na compilacao, a
matriz deve ser declarada na funcao como foi feito no exemplo acima,
entretanto o programa deve funcionar tambem como abaixo:
....
int m[3][3];
long d;
....
d = determ(m, 3);
....
A diferenca eh que este procedimento gera um warning na maioria dos
compiladores C.
*/
#ifndef __JUCALD_H
#define __JUCALD_H
long determ(int *m, int s);
int dellc(int *m, int *m2, int lin, int col, int s);
long determ(int *m, int s)
{
long detbuf = 0; // Armazena a determinante parcial
int *m2;
int c;
int h, i;
if(s == 0)
return 0;
if(s == 1)
return *m;
m2 = (int *)calloc(s*s, sizeof(int));
for(c = 0; c < s; c++)
{
dellc(m, m2, 0, c, s); // Elimina a linha 0 e a coluna c da matriz m e
// armazena em m2
if(!(c%2))
detbuf+= determ(m2, s-1) * *(m+c); //Se for par soma determinante de m2
else
detbuf-= determ(m2, s-1) * *(m+c); //Se impar subtrai a determ. de m2
}
return detbuf;
}
int dellc(int *m, int *m2, int lin, int col, int s)
{
int cont;
// Copia a Matriz m para m2
for(cont = 0; cont < s*s; cont++)
*(m2+cont) = *(m+cont);
// Exclui a linha lin ( A ultima linha eh excluida automaticamente atraves
// da expressao s*(s-1) )
for(cont = 0; cont < s*(s-1); cont++)
if(cont>=(lin*s))
*(m2+cont) = *(m2+cont+s);
//Exclui a coluna col ( A ultima coluna eh excluida automaticamente atraves
// da expressao (s-1)*(s-1) )
for(cont = 0; cont < (s-1)*(s-1); cont++)
if(!((cont-col)%s))
*(m2+cont) = *(m2+cont+1);
return 0;
}
#endif
[1] Comentário enviado por ad em 04/11/2004 - 13:20h
olá! eu compilei o seu código e numa matriz de 3x3 com os elementos a1,1=2 / a1,2=2 / a1,3=0 / a2,1=1 / a2,2=1 / a2,3=1 / a3,1=4 / a3,2=-3 / a3,3=0 o determinante pelo seu prog. da um valor errado quando na verdade deveria dar 2. E testei várias outras matrizes e fui comparando com o livro e tb da pau!
Não é uma crítica! Achei muito legal a recursividade e só gostaria de saber onde está acontecendo a falha! Obrigado adson@expertid.com.br
[2] Comentário enviado por kandrade em 08/11/2004 - 06:39h
olá Jefferson......achei muito interessante seu código.....e como nosso amigo Adson falou ele não está 100% correto........dá uma olhadinha + cuidadosa na sua função que deleta uma coluna e uma linha........mais precisamente na parte que deleta uma coluna......
[3] Comentário enviado por kandrade em 08/11/2004 - 08:01h
Jefferson......sua função se tornou um pouco complicada......existe formas mais fáceis de resolver a questão de deletar uma coluna e uma linha de uma matriz............mas de qualquer forma achei muito interessante seu código.............ai vai uma possível solução para o erro na função dellc...........
int dellc(int *m, int *m2, int lin, int col, int s)
{
int cont,i=0,f=0;
// Copia a Matriz m para m2
for(cont = 0; cont < s*s; cont++)
*(m2+cont) = *(m+cont);
// Exclui a linha lin ( A ultima linha eh excluida automaticamente atraves
// da expressao s*(s-1) )
for(cont = 0; cont < s*(s-1); cont++)
if(cont>=(lin*s))
*(m2+cont) = *(m2+cont+s);
//Exclui a coluna col ( A ultima coluna eh excluida automaticamente atraves
// da expressao (s-1)*(s-1) )
for(cont = 0; cont < s*(s-1); cont++)
if(((cont+f)%s)==col)
{
i=cont;
while(i<s*(s-1))
{
*(m2+i) = *(m2+i+1);
i++;
}
f+=1;
}
return 0;
}
na verdade eu deixei os comentarios......mas essa função deleta a primeira linha.........e a coluna c passada por parametro pela função determ...........
[4] Comentário enviado por jeffersonsfelix em 08/11/2004 - 12:21h
valeu pessoal pela dica. a verdade é que eu adaptei esse código de um anterior que eu havia feito que calculava determinante de matrizes de tamanho fixo, e o processo de exclusão de linha e coluna era mais fácil.... e nem havia testado as alterações...
valeu pelas implementações...
int determ(int *m, int s);
int dellc(int *m, int *m2, int lin, int col, int s);
int determ(int *m, int s)
{
int detbuf = 0; // Armazena a determinante parcial
int *m2;
int c;
int h, i;
if(s == 0)
return 0;
if(s == 1)
return *m;
m2 = (int *)calloc(s*s, sizeof(int));
for(c = 0; c < s; c++)
{
dellc(m, m2, 0, c, s); // Elimina a linha 0 e a coluna c da matriz m e
// armazena em m2
if(!(c%2))
detbuf+= determ(m2, s-1) * *(m+c); //Se for par soma determinante de m2
else
detbuf-= determ(m2, s-1) * *(m+c); //Se impar subtrai a determ. de m2
}
return detbuf;
}
int dellc(int *m, int *m2, int lin, int col, int s)
{
int cont,i=0,f=0;
// Copia a Matriz m para m2
for(cont = 0; cont < s*s; cont++)
*(m2+cont) = *(m+cont);
// Exclui a linha lin ( A ultima linha eh excluida automaticamente atraves
// da expressao s*(s-1) )
for(cont = 0; cont < s*(s-1); cont++)
if(cont>=(lin*s))
*(m2+cont) = *(m2+cont+s);
//Exclui a coluna col ( A ultima coluna eh excluida automaticamente atraves
// da expressao (s-1)*(s-1) )
for(cont = 0; cont < s*(s-1); cont++)
if(((cont+f)%s)==col)
{
i=cont;
while(i<s*(s-1))
{
*(m2+i) = *(m2+i+1);
i++;
}
f+=1;
}
return 0;
}
int **Alocar_matriz_real (int m, int n)
{
int **v; /* ponteiro para a matriz */
int i; /* variavel auxiliar */
if (m < 1 || n < 1) { /* verifica parametros recebidos */
printf ("** Erro: Parametro invalido **\n");
return (NULL);
}
/* aloca as linhas da matriz */
v =(int**) calloc (m, sizeof(int *)); // Um vetor de m ponteiros para float
if (v == NULL) {
printf ("** Erro: Memoria Insuficiente **");
return (NULL);
}
/* aloca as colunas da matriz */
for ( i = 0; i < m; i++ ) {
v[i] =(int*) calloc (n, sizeof(int)); /* m vetores de n floats */
if (v[i] == NULL) {
printf ("** Erro: Memoria Insuficiente **");
return (NULL);
}
}
return (v); /* retorna o ponteiro para a matriz */
}
int **Liberar_matriz_real (int m, int n, int **v)
{
int i; /* variavel auxiliar */
if (v == NULL) return (NULL);
if (m < 1 || n < 1) { /* verifica parametros recebidos */
printf ("** Erro: Parametro invalido **\n");
return (v);
}
for (i=0; i<m; i++) free (v[i]); /* libera as linhas da matriz */
free (v); /* libera a matriz (vetor de ponteiros) */
return (NULL); /* retorna um ponteiro nulo */
}
int main (void)
{
clrscr();
int x,y,aux,i,j,tam,a,b,ordem;
int **m;
printf("Entre com a ordem da Matriz:\n");
scanf("%d",&x);
y=x;
ordem=y;
m = Alocar_matriz_real (x, y);
printf("\n\nOrdem Desejada %d x %d :\n\n",x,y);
if(m==NULL)