Calcular determinante de matrizes

Publicado por Jefferson dos Santos Felix 27/04/2004

[ Hits: 62.853 ]

Download jucald.h




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.

  



Esconder código-fonte

/*---------------------------------------------------------------------------
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


Scripts recomendados

Jogo para adivinhar o numero

inputAst

Sorteio

Produto de duas matrizes alocadas dinamicamente

Cálculo de divisores de um número.


  

Comentários
[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......

te+.......

[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...........

espero ter contribuído.............te+.........


[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...

jEfF_[Feliks]

[5] Comentário enviado por ad em 09/11/2004 - 13:40h

isso ai kandrade compilou blz! esse é o cara!
valeu!

[6] Comentário enviado por demiscarlos em 10/06/2007 - 14:07h

Olá amigos, eu to com problemas com esse determinante ae para a seguinte matriz com alocação dinâmica, alguem pode me ajudar?

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <dos.h>

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)



printf("\nValores correspondentes\n");
printf("\nLinha-Coluna\n");
for(i=0;i<x;i++)
for(j=0;j<y;j++)
{
printf("[%d] [%d] =>",i+1,j+1);
printf(" %d\n",m[i][j]=rand()%5);
delay(10);
//scanf("%d",&mat1[i][j]);
}


printf("\n\n A MATRIZ \n\n");
//impressao de valores
for(i=0;i<x;i++)
{
for(j=0;j<y;j++)
{
printf("[%d]\t",m[i][j]);
printf(" ");
}
printf("\n");
}

/* printf("\n\n A MATRIZ TRANSPOSTA \n\n");
//impressao de valores
for(i=0;i<x;i++)
{
for(j=0;j<y;j++)
{

printf("[%d]\t",mat1[j][i]);
printf(" ");
}
printf("\n");
}

*/
//O DETERMINANTE

printf("Determinante: %d\n",determ(*m, ordem));

m = Liberar_matriz_real (x, y, m);
//free(mat1);
getch();
return 0;
}

[7] Comentário enviado por rodrigopocos em 06/04/2008 - 00:53h

Alguem pode me ajudar?

Eu adicionei as funções, porém está retornando determinate 0

Vlw!

[8] Comentário enviado por niccioli em 28/04/2008 - 16:02h

Olá pessoal

Tenho uma matriz Inversa A-1

-2 5 2
-1 1 0
2 3 -1

Não consigo fazer, faz mais de 33 anos que aprendi, por favor alguém pode ajudar.

Obrigado


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts