Pular para o conteúdo

Calcular determinante de matrizes

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.
Jefferson dos Santos Felix jeffersonsfelix
Hits: 63.914 Categoria: C/C++ Subcategoria: Miscelânea
  • Download
  • Nova versão
  • Indicar
  • Denunciar

Descrição

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.
Download jucald.h Enviar nova versão

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

Listas Encadeadas

Descompactador Simples

Função para validação de datas

Divisores de um inteiro positivo em C++

Chuva de janelas

#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

Entre na sua conta para comentar.