domingo, 28 de abril de 2013

Calculo matriz INVERSA en C/C++

El siguiente programa es semejante al desarrollado anteriormente en Pascal. Comparte gran parte de la estructura con el programa que resuelve sistemas mediante Gauss (Entrada) Se calcula la matriz inversa, realizando las mismas operaciones que se realizan para diagonalizar la matriz, sobre la matriz unidad. Finalmente, después de todas las transformaciones sobre la matriz identidad, obtenemos la matriz inversa. Este método es el más simple a la hora de obtener la matriz inversa.
Hay que recordar que para que una matriz se pueda invertir, tiene que ser no singular, es decir, con determinante distinto de cero.

Puedes comprobar si la matriz tiene determinante nulo con el código del enlace siguiente.
DETERMINANTE

CODIGO:


#include <stdio.h>

int const Tam=100;
void PideDatos(int *Dim, float Sist[][Tam]);
void EscribeDatos(int Dim, float Sist[][Tam]);
void Invierte(int Dim, float Sist[][Tam], float Inv[][Tam]);


int main(void)
{
int C,Dimension;
float Sistema[Tam][Tam],Inversa[Tam][Tam];
PideDatos(&Dimension,Sistema);
printf("\n\n\nLa matriz introducida es la siguiente: \n\n");
EscribeDatos(Dimension,Sistema);
Invierte(Dimension,Sistema,Inversa);
printf("\n\n\nLa inversa de la matriz es: \n\n");
EscribeDatos(Dimension,Inversa);

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


void PideDatos(int *Dim,float Sist[][Tam])
{
int A,B;
    printf("\n\n ||CALCULA INVERSA||");
printf("\n\n\n Introduce el tamano de la matriz:");
scanf("%d",&*Dim);
printf("\n\n Introducir cada componente de la matriz A:");
for(A=1;A<=*Dim;A++) for(B=1;B<=*Dim;B++){
printf("\n Termino A(%d,%d):",A,B); scanf("%f",&Sist[A][B]);}
}

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

void Invierte(int Dim, float Sist[][Tam], float Inv[][Tam])
{
int NoCero,Col,C1,C2,A;
float Pivote,V1,V2;

/*Se inicializa la matriz inversa, como la matriz identidad:*/
for(C1=1;C1<=Dim;C1++) for(C2=1;C2<=Dim;C2++)
   if (C1==C2) Inv[C1][C2]=1; else Inv[C1][C2]=0;

for(Col=1;Col<=Dim;Col++){
NoCero=0;A=Col;
while(NoCero==0){
if((Sist[A][Col]>0.0000001)||((Sist[A][Col]<-0.0000001))){
NoCero=1;}
else A++;}
Pivote=Sist[A][Col];
for(C1=1;C1<=Dim;C1++){
V1=Sist[A][C1];
Sist[A][C1]=Sist[Col][C1];
Sist[Col][C1]=V1/Pivote;
V2=Inv[A][C1];
Inv[A][C1]=Inv[Col][C1];
Inv[Col][C1]=V2/Pivote;
            }
for(C2=Col+1;C2<=Dim;C2++){
V1=Sist[C2][Col];
for(C1=1;C1<=Dim;C1++){
Sist[C2][C1]=Sist[C2][C1]-V1*Sist[Col][C1];
                Inv[C2][C1]=Inv[C2][C1]-V1*Inv[Col][C1];}
}}

/*Aqui ya esta triangularizada, con 1s en diagonal, ahora se diagonaliza*/
for(Col=Dim;Col>=1;Col--) for(C1=(Col-1);C1>=1;C1--)
    {
        V1=Sist[C1][Col]; 
        for(C2=1;C2<=Dim;C2++){
   Sist[C1][C2]=Sist[C1][C2]-V1*Sist[Col][C2];
   Inv[C1][C2]=Inv[C1][C2]-V1*Inv[Col][C2];
   }}
}




Un Saludo.

20 comentarios:

  1. Respuestas
    1. Gracias por el comentario! Espero que te haya sido útil

      Eliminar
  2. muchas gracias brother me e dado golpes contra la pared y ya pude examinar el cod que propones para realizar im propio programa gracias!

    ResponderEliminar
  3. pero como funcionaria para matrices no cuadradas? y usa apuntaDORES VDD?

    ResponderEliminar
    Respuestas
    1. Hola Manuel,
      Ante la pregunta de si funciona con matrices que no son cuadradas, la respuesta es que no. La verdad que me equivoqué a la hora de hacer el programa y utilicé únicamente una variable para definir la dimensión en vez de utilizar dos, una para las columnas y otra para las filas. Intentare corregirlo y lo volveré a subir. Si que se utilizan punteros, pero solo para las funciones para trabajar con parámetros por referencia.

      Un saludo

      Eliminar
    2. corrigelo de una vez qu lo necesito para dentro de 5 min mierda

      Eliminar
  4. Oye, una pregunta, en tu codigo "pivote" ¿a que se refiere?

    ResponderEliminar
    Respuestas
    1. Buenos días Adan,
      La variable pivote hace referencia a la componente de la matriz que e utiliza para hacer ceros todas las demás componentes de la misma columna que tiene por abajo, en cada uno de las etapas del bucle for. Es por eso que si el pivote es nulo, se busca la siguiente fila que tenga un pivote distinto de cero.

      Eliminar
  5. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  6. De nada. Me alegra saber que os son útiles.

    ResponderEliminar
  7. gracias me va a servir para saber como hacer mas y en que me equivoke

    ResponderEliminar
  8. Disculpa, me podrias dar una explicación asi breve sobre cuando inicializas la matriz inversa como la matriz identidad, esque me pierdo en esa parte

    ResponderEliminar
  9. Disculpa, me podrias dar una explicación asi breve sobre cuando inicializas la matriz inversa como la matriz identidad, esque me pierdo en esa parte

    ResponderEliminar
  10. Sé que tiene mucho que publicaste esto, pero de verdad te lo agradezco mucho, tengo que calcular inversas de matrices muy grandes y al final siempre me queda duda si no me he equivocado en un cálculo o algo, tu programa me ayuda a comprobar mis resultados finales y la verdad me quitas un peso ENORME de encima, gracias gracias!

    ResponderEliminar
  11. Gracias por tu aporte, me ha sido de mucha utilidad

    ResponderEliminar
  12. Hola buenas hay alguien que me pueda ayudar en este momento ??

    ResponderEliminar