zildjian
 
#1 2 may 09, 17:19
#1 2 may 09, 17:19

Algoritmo para hallar inversa de una matriz

Pues lo dicho, necesito un algoritmo, o un pseudocódigo de él que me permita hallar la inversa de una matriz. No puedo utilizar el método Gauss-Jordan porque para ello tendría que calcular la descomposición LU de la matriz, cosa que no optimizaría para nada el programa (práctica de la uni) que estoy llevando a cabo.

Si sirve de algo, la matriz tiene una columna llena de unos, porque es para resolver un sistema sobredeterminado.

Salu2 y gracias por adelantado ^^

PD: Estoy trabajando en C

 
LOc0
 
LOc0
 
#2 2 may 09, 18:43
#2 2 may 09, 18:43

Es decir, la inversa se calcula con la matriz de adjuntos, trasponiéndola (cambiando filas por columnas) y después, dividiendo cada elemento por el determinante de la matriz inicial (si el determinante es cero entonces la matriz inicial no es invertible).

Para calcular el determinante de la matriz inicial, y los determinantes sucesivos:

Spoiler

/*
CALCULADOR de DETERMINANTES de orden n
Autor: Antonio López Vivar
Fecha: 1 de diciembre de 2003
Revisión: final 1.0
*/

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

//Prototipos
float Determinante (float **, int);
void Adjunta (float **, float **, int, int);

//Principal
void main()
{
    int n, i, f, c;
    float **matriz;
    char comando;

    for(i=0; i<3; i++)
    {
    printf("\n\n\tBienvenido al CaLcuLaDOR de DeTERminanTes de orden n marca MIKASA");

    sleep(500);
    system("cls");

    printf("\n\n\tBienvenido al CaLcuLaDOR de DeTERminanTes de orden n marca MIKASA");
    printf("\n\n\n\n\n\n\n\t\t\tUna utilidad de Antonio Lopez Vivar");

    sleep(500);
    system("cls");
    }

    do{
    do{
    system("cls");
    printf("\n\n\tNota--> Este programa utiliza una funcion recursiva. Abstenerse de introducir matrices de orden elevado (mayor de 10), puesto que el consumo de RAM puede ser bestial");

    printf("\n\n\tORDEN?>\t");

    scanf("%d", &n);
    }while(n<1);

    //Petición de memoria dinámica para la matriz
    matriz=(float**)calloc(n, sizeof(float*));
    if(matriz==NULL)
    printf("ERROR, FALTA MEMORIA PARA LA MATRIZ. Introduzca un orden MUCHO mas pequeño");
    else
    {
    for(i=0; i<n; i++)
        matriz[i]=(float*)calloc(n, sizeof(float));   

    //Lectura por teclado de la matriz
    for(f=0; f<n; f++)
        for(c=0; c<n; c++)
            {printf("\nIntroduce el elemento %d de la fila %d  --->\t", c+1, f+1);
             scanf("%f", &matriz[f][c]);
            }

    //Se muestra la matriz al usuario
    system("cls");
    printf("\n\n\n");
    for(f=0; f<n; f++)
        {
            printf("\t\t");
            for(c=0; c<n; c++)
                printf("%12.1f ", matriz[f][c]);

            printf("\n");
        }
     printf("\n\n\n\t\tCalculando el determinante, por favor espere...\n\t\t(Para abortar el calculo pulse CTRL+C)\n");
     printf("\n\n\n\n\n\t\t\tEl determinante es:");
     printf("\n\n\n\t\t\t\t%.1f\n\n\n\n\n\t\t", Determinante(matriz, n));

     //Se libera la memoria solicitada
     free(matriz);

     }
     printf("Pulsa INTRO para calcular OTRO determinante, o pulsa S para SALIR");
     fflush(stdin);
     comando=getch();
     }while(comando!='s' && comando!='S');

}

/*
Esta función recursiva se encarga del cálculo del determinante propiamente dicho.
Recibe:
   - La matriz (referencia).
   - Orden de la matriz (valor).

Devuelve:
   - El determinante (valor).
*/

float Determinante (float **mat, int orden)
{
    float det;
    int h;

    float **auxiliar;

    //Caso básico
    if(orden<=2)
        {
                if(orden==2)
                                det=mat[0][0]*mat[1][1]-(mat[1][0]*mat[0][1]);

                else
                                det=mat[0][0];
        }
    //Se calculan n determinantes de orden "n-1".
    else
        {
                //Petición de memoria dinámica para la matriz auxiliar
                    auxiliar=(float**)calloc(orden-1, sizeof(float*));
                        for(h=0; h<orden-1; h++)
                                auxiliar[h]=(float*)calloc(orden-1, sizeof(float));

                //Se usa un acumulador para ir sumando los determinantes de orden n-1
                det=0;

                for(h=0; h<orden; h++)
                {               Adjunta(mat, auxiliar, orden, h);
                                det+=pow(-1, h)*mat[h][0]*Determinante(auxiliar, orden-1);
                }

                //Se libera la memoria auxiliar solicitada
                free(auxiliar);
        }

        return(det);

}

/*
Esta función se encarga de calcular la matriz resultante de tachar la primera columna y alguna de las n filas de la matriz inicial.
Recibe:
   - La matriz inicial (referencia).
   - El orden de la matriz inicial(valor).
   - La fila que hay que tachar de la matriz inicial (valor).

Devuelve:
   - La matriz auxiliar que se usará para calcular los determinates de orden n-1 (referencia).
*/
void Adjunta (float **mat, float **aux, int orden, int pos)
{
    int fila, columna, j, i;

    for(j=0, fila=0; fila<orden-1; j++, fila++)
        {
                if(j==pos)
                                fila--;
                else
                        for(i=1, columna=0; columna<orden-1; i++, columna++)
                              aux[fila][columna]=mat[j][i];

         }                     
}

Nota: lo que en el código aparece como adjunta NO ES LA MATRIZ DE ADJUNTOS.

Este método recursivo se va haciendo muy ineficiente a medida que la matriz aumenta de tamaño. (Para calcular el determinante de la matriz inicial hay que calcular N determinates de orden N-1 y para calcular la matriz de adjuntos hay que calcular NxN determinantes de orden N-1)

La otra opción (la "güena") es GAUSS-JORDAN sin necesidad de calcular LU.

Salu2 ;)

 
HoTiTo
 
HoTiTo
 
#3 2 may 09, 21:04
#3 2 may 09, 21:04

Yo tuve una asignatura llamada Análisis Numérico que trataba en su mayoría de algoritmos matemáticos para hacer ese tipo de cosa. Fue bastante productiva pero también algo coñazo. Ahora mismo ya no me acuerdo, pero algunos había.

Busca por métodos numéricos.

 
zildjian
 
#4 2 may 09, 21:43
#4 2 may 09, 21:43

#3 De hecho, es para Análisis Numérico... xDDD También en la UPF?

 
HoTiTo
 
HoTiTo
 
#5 3 may 09, 00:04
#5 3 may 09, 00:04

Nono, ULPGC. Pero vamos, es una asignatura obligatoria, así que todos la tendrán xD

 
CaRaNaVo
 
online
CaRaNaVo 
 
#6 11 may 09, 22:34
#6 11 may 09, 22:34

hjajajaj #4 vas un poco tarde no? Estamos por la practica 5 ya y eso es de la 1 kreo recordar

 
Dod-Evers
 
#7 12 may 09, 19:11
#7 12 may 09, 19:11

En matlab:

inv(A).

Isi and fast.

Favoritos
0