martes, 30 de abril de 2013

Calculo Determinante de una Matriz en C/C++

Calcula el determinante de una matriz, previo escalonamiento (método de gauss-jordan), mediante la multiplicación de los términos de su diagonal.
El hecho de realizar permutaciones entre filas, o la suma y resta entre filas, no afecta al módulo del determinante de la matriz, pero si al signo (Fácilmente verificable).
El signo se ve afectado por cada permutación realizada para llegar a la matriz escalonada. Es decir, si el número de permutaciones realizadas es un número par, el producto de los términos de la diagonal será el determinante. Si por el contrario, las permutaciones realizadas son impares, el determinante será el producto de los términos de la diagonal pero cambiados de signo.
Este método es mucho más eficiente que el usado anteriormente en otros programas (Aquí en C y aquí en Pascal) que trabajaba con funciones recursivas y que estaban basados en el desarrollo de Laplace.




Aquí les dejo el código:


#include <stdio.h>

int const Tam=101;

void PideDatos(int *Dim, float Mat[][Tam]);
void EscribeDatos(int Dim, float Mat[][Tam]);
void CalcDet(int Dim, float Mat[][Tam]);


int main(void)
{
int C,Dimension;
float Matriz[Tam][Tam];
PideDatos(&Dimension,Matriz);
printf("\n\n\nCalcula DETERMINANTE: \n\n");
EscribeDatos(Dimension,Matriz);
CalcDet(Dimension,Matriz);

scanf("%d");
return(0);
}


void PideDatos(int *Dim,float Mat[][Tam])
{
int A,B;
printf("\n\n ||CALCULA DETERMINANTE ESCALONANDO MATRIZ||");
printf("\n\n\n Introduce la dimension de la matriz:");
scanf("%d",&*Dim);
printf("\n\n INTRODUCIR CADA COMPONENTE DE LA MATRIZ:");
for(A=1;A<=*Dim;A++) for(B=1;B<=*Dim;B++){
printf("\n Termino A(%d,%d):",A,B); scanf("%f",&Mat[A][B]);}
}

void EscribeDatos(int Dim, float Mat[][Tam])
{
int A,B;
for(A=1;A<=Dim;A++){
for(B=1;B<=(Dim);B++)
printf("%7.2f",Mat[A][B]);
printf("\n");
}}

void CalcDet(int Dim, float Mat[][Tam])
{
 int NoCero,Col,C1,C2,A,NoReg,Perm=0/*permutaciones*/;
 float Pivote,V1,Det=1;

 for(Col=1;Col<=Dim;Col++){
  NoCero=0;A=Col;
  while((NoCero==0)&&(A<=Dim)){
   if((Mat[A][Col]>0.0000001)||((Mat[A][Col]<-0.0000001))){
    NoCero=1;}
   else A++;}
  if (A>Dim) NoReg=1;
  if (A!=Col) Perm++;
  Pivote=Mat[A][Col];
  for(C1=1;C1<=(Dim);C1++){
   V1=Mat[A][C1];
   Mat[A][C1]=Mat[Col][C1];
   Mat[Col][C1]=V1;}
  for(C2=Col+1;C2<=Dim;C2++){
   V1=Mat[C2][Col];
   for(C1=Col;C1<=(Dim);C1++){
    Mat[C2][C1]=Mat[C2][C1]-((V1/Pivote)*Mat[Col][C1]);}}
 }
    for(C2=1;C2<=Dim;C2++) Det=Det*Mat[C2][C2];
 A=Perm;
 if ((A%2)==1) Det=-Det; /*Caso de permutaciones impares*/
 if (NoReg==1) Det=0;
    printf("El determinante de la matriz es:   %f", Det);

}



Y aquí el código para poner a prueba el programa. Se introduce el tamaño de la matriz, el programa genera todas las componentes de la matriz de manera aleatoria (Únicamente introduce 1s y 0s), y se calcula su determinante:

(Se ha dejado comentada la función para imprimir la matriz)

#include <stdio.h>
#include <stdlib.h> /*Para los números aleatorios*/

int const Tam=200;

void PideDatos(int *Dim, float Mat[][Tam]);
void EscribeDatos(int Dim, float Mat[][Tam]);
void CalcDet(int Dim, float Mat[][Tam]);


int main(void)
{
 int C,Dimension;
 float Matriz[Tam][Tam];
 PideDatos(&Dimension,Matriz);
 printf("\n\n\nCalcula DETERMINANTE: \n\n");
 EscribeDatos(Dimension,Matriz);
 CalcDet(Dimension,Matriz);

 scanf("%d");
 return(0);
}


void PideDatos(int *Dim,float Mat[][Tam])
{
 int A,B;
 printf("\n\n ||CALCULA DETERMINANTE ESCALONANDO MATRIZ||");
 printf("\n\n\n Introduce la dimension de la matriz:");
 scanf("%d",&*Dim);
 for(A=1;A<=*Dim;A++) for(B=1;B<=*Dim;B++)
  Mat[A][B]=rand()%2;
}

void EscribeDatos(int Dim, float Mat[][Tam])
{
 int A,B;
 for(A=1;A<=Dim;A++){
  for(B=1;B<=(Dim);B++)
   printf("%7.2f",Mat[A][B]);
  printf("\n");
 }}

void CalcDet(int Dim, float Mat[][Tam])
{
 int NoCero,Col,C1,C2,A,NoReg,Perm=0/*permutaciones*/;
 float Pivote,V1,Det=1;

 for(Col=1;Col<=Dim;Col++){
  NoCero=0;A=Col;
  while((NoCero==0)&&(A<=Dim)){
   if((Mat[A][Col]>0.0000001)||((Mat[A][Col]<-0.0000001))){
    NoCero=1;}
   else A++;}
  if (A>Dim) NoReg=1;
  if (A!=Col) Perm++;
  Pivote=Mat[A][Col];
  for(C1=1;C1<=(Dim);C1++){
   V1=Mat[A][C1];
   Mat[A][C1]=Mat[Col][C1];
   Mat[Col][C1]=V1;}
  for(C2=Col+1;C2<=Dim;C2++){
   V1=Mat[C2][Col];
   for(C1=Col;C1<=(Dim);C1++){
    Mat[C2][C1]=Mat[C2][C1]-((V1/Pivote)*Mat[Col][C1]);}}
 }
    for(C2=1;C2<=Dim;C2++) Det=Det*Mat[C2][C2];
 A=Perm;
 if ((A%2)==1) Det=-Det; /*Caso de permutaciones impares*/
 if (NoReg==1) Det=0;
    printf("El determinante de la matriz es:   %f", Det);

}



Un saludo.

No hay comentarios:

Publicar un comentario