Hola, siguiendo mi autoaprendizaje con las librerías matemáticas os dejo un sencillo y corto programa escrito en C++ para calcular el determinante y la inversa de una matriz cualquiera. Se sobreentiende que la matriz tiene determinante no nulo para poder calcular su matriz inversa.
Para poderlo hacer he utilizado GSL, en concreto, dos órdenes que se basan sobre la descomposición LU de una matriz.
Me explico, toda matriz cuadrada, llamémosla A, se puede descomponer de la siguiente forma:
PA=LU
Siendo P una matriz permutación, L una matriz triangular inferior en la que los elementos de su diagonal principal son todos uno; y U es una matriz triangular superior. (( L porque low es inferior y U porque upper es superior, en inglés ))
Así pues utilizando GSL tenemos la función:
gsl_linalg_LU_decomp(gsl_matrix *A, gsl_permutation *p, int *signum)
la cual nos calculará la descomposición LU de una matriz cuadrada no singular (( su determinante es no nulo )) A cualquiera, utilizando para ello una matriz permutación p que irá cambiando en las sucesivas iteraciones que realice la función, al igual que la variable entera signum. signum es el signo de la permutación, el cuasl toma el valor de (-1) n, siendo n el número de intercambios de la permutación.
Una vez calculada la descomposición LU ya podremos calcular el determinante y la matriz inversa de A con las funciones:
double gsl_linalg_LU_det (gsl_matrix *LU, int signum)
gsl_linalg_LU_invert (const gsl_matrix *LU, const gsl_permutation *p, gsl_matrix *inverse)
La primera es la que nos permite calcular el determinante, pasándole LU y signum; que los hemos calculado con la función gsl_linalg_LU_decomp. Y la segunda es la que nos permite calcular la inversa de A y guardarla en inverse, que es de tipo gsl_matrix
Para poder utilizar estas funciones bastará que en la cabecera de nuestro código introduzcamos el siguiente include:
#include <gsl/gsl_linalg.h>
Yo al programa le he llamado detinv.cpp (( vosotros llamadle como queráis, pero para C cambiad .cpp por .c )) , y el código es el siguiente:
-
#include <iostream>
-
#include <iomanip> //La utilizo para setw(int)
-
#include <gsl/gsl_linalg.h> //Librería gsl para calcular lo que queremos
-
-
using namespace std; //Instrucción para no tener que escribir std::cin
-
-
int main (int argc, char **argv)
-
{
-
size_t i,j,m; //size_t es un tipo específico de GSL, de tipo entero
-
// i,j son variables contador, m es el tamaño u orden de la matriz
-
int s; // s es la variable signum de las permutaciones
-
cout<<"\nIntroduce el orden de la matriz: ";
-
cin>>m;
-
// Declaramos las matrices A, p y invA de forma dinámica para así poder destruirlas
-
// cuando acabemos con ellas y así; liberar memoria. invA es la inversa y p es
-
// la permutación
-
gsl_matrix * A = gsl_matrix_alloc(m,m);
-
gsl_permutation * p = gsl_permutation_alloc(m);
-
gsl_matrix *invA = gsl_matrix_alloc(m,m);
-
cout<<"\nIntroduce los elementos de la matriz:"<<endl;
-
for(i=0; i<m*m; i++)
-
{
-
cout<<"A("<<i+1<<")"<<"=";
-
cin>>A->data[i];
-
}
-
gsl_linalg_LU_decomp (A, p, &s); //Calculo la descomposición LU
-
gsl_linalg_LU_invert(A,p,invA); // Calculo la inversa de A y la guardo en invA
-
// Calculamos y visualizamos por terminal el determinante de A
-
cout<<"\ndet(A) = "<<gsl_linalg_LU_det(A, s)<<endl;
-
// Visualizamos por terminal la inversa de A
-
cout<<"\nLa inversa de A es:"<<endl;
-
for(i=0; i<m; i++)
-
{
-
for(j=0;j<m; j++)
-
{
-
cout<<gsl_matrix_get(invA,i,j)<<setw(10);
-
}
-
cout<<endl;
-
}
-
// Liberamos memoria destruyendo la que ocupan A, p e invA
-
gsl_matrix_free(A);
-
gsl_matrix_free(invA);
-
gsl_permutation_free(p);
-
return(0);
-
}
Yo lo he escrito con gedit y lo he compilado y ejecutado con las siguientes órdenes:
g++ detinv.cpp -o detinv -lgsl -lgslcblas -lm
./detinv
Ahora sólo falta que me contéis cómo os ha ido el tema, espero que a alguien le sirva de ayuda. He de decir que los resultados de la inversa vienen en forma decimal y no en fracciones, espero pronto implementar una clase para que aparezca en forma de fracciones y publicarla en el blog, hace tiempo que la hice en Windows pero me temo que la perdí.
Os aconsejo que os leáis los siguientes enlaces para entenderlo mejor:
Código En C++ Para Multiplicar Matrices
Descomposición LU en la Wikipedia
La matriz Permutación En La Wikipedia
Saludos 
Tags: Ubuntu, Linux, Programación, Matemáticas



Hola, me intereso mucho este ejemplo, disculpa es que soy nuevo en esto de linux, espero me puedas ayudar :
Tengo unos errores:
error: expected namespace-name before ‘;’ token
detinv.cpp: In function ‘int main(int, char**)’:
detinv.cpp:14: error: ‘lt’ no se declaró en este ámbito
detinv.cpp:14: error: ‘nIntroduce’ no se declaró en este ámbito
detinv.cpp:14: error: expected `;’ before ‘el’
detinv.cpp:15: error: ‘gt’ no se declaró en este ámbito
detinv.cpp:21: error: ‘gsl_matrix’ no se declaró en este ámbito
detinv.cpp:21: error: ‘A’ no se declaró en este ámbito
detinv.cpp:21: error: ‘gsl_matrix_alloc’ no se declaró en este ámbito
detinv.cpp:22: error: ‘gsl_permutation’ no se declaró en este ámbito
detinv.cpp:22: error: ‘p’ no se declaró en este ámbito
detinv.cpp:22: error: ‘gsl_permutation_alloc’ no se declaró en este ámbito
detinv.cpp:23: error: ‘invA’ no se declaró en este ámbito
detinv.cpp:25: error: expected `;’ before ‘los’
detinv.cpp:25: error: expected primary-expression before ‘’ token
detinv.cpp:26: error: expected primary-expression before ‘for’
detinv.cpp:26: error: expected `;’ before ‘for’
detinv.cpp:26: error: expected primary-expression before ‘>’ token
detinv.cpp:27: error: expected primary-expression before ‘{’ token
detinv.cpp:27: error: expected `;’ before ‘{’ token
detinv.cpp:31: error: ‘amp’ no se declaró en este ámbito
detinv.cpp:31: error: expected `;’ before ‘)’ token
detinv.cpp:32: error: ‘gsl_linalg_LU_invert’ no se declaró en este ámbito
detinv.cpp:35: error: ‘ndet’ no se declaró en este ámbito
detinv.cpp:35: error: expected primary-expression before ‘’ token
detinv.cpp:35: error: expected primary-expression before ‘’ token
detinv.cpp:35: error: expected primary-expression before ‘’ token
detinv.cpp:35: error: expected primary-expression before ‘’ token
detinv.cpp:38: error: ‘nLa’ no se declaró en este ámbito
detinv.cpp:38: error: expected `;’ before ‘inversa’
detinv.cpp:38: error: expected primary-expression before ‘’ token
detinv.cpp:38: error: expected primary-expression before ‘’ token
detinv.cpp:40: error: expected primary-expression before ‘for’
detinv.cpp:40: error: expected `;’ before ‘for’
detinv.cpp:40: error: expected primary-expression before ‘>’ token
detinv.cpp:41: error: expected primary-expression before ‘{’ token
detinv.cpp:41: error: expected `;’ before ‘{’ token
detinv.cpp:47: error: expected primary-expression before ‘’ token
detinv.cpp:47: error: expected primary-expression before ‘’ token
detinv.cpp:47: error: expected primary-expression before ‘<’ token
detinv.cpp:47: error: expected primary-expression before ‘/’ token
detinv.cpp:47: error: ‘inva’ no se declaró en este ámbito
detinv.cpp:47: error: ‘gsl_matrix_get’ no se declaró en este ámbito
detinv.cpp:47: error: expected primary-expression before ‘’ token
detinv.cpp:47: error: expected primary-expression before ‘’ token
detinv.cpp:50: error: ‘gsl_matrix_free’ no se declaró en este ámbito
detinv.cpp:52: error: ‘gsl_permutation_free’ no se declaró en este ámbito
uso el kate para crear programas.
Gracias por tu atencion: :-SS
detinv.cpp:41: error: expected primary-expression before ‘{’ token. que significa?
Mauricio seguramente te has dejado alguna llave por abrir o cerrar en algún sitio, revísalas.
=D> Gracias mano no sabes ke ayudota me diste con la tarea
VAYA NIVEL D C++ HAY EN SUDAMERICA
Me costó un poquito echarlo a andar (faltaba instalar libgsl0-dev; lo averigué Googleando) pero por fin compiló en Debian. Yo había hecho por mi cuenta, como ejercicio, mi propia rutina para invertir matrices pero es agradable saber que existe esta forma. Felicitaciones por tu blog.
Saludos
hola!!!
necesito este programita pero con funciones mas basicas???
donde lo puedo encontrar???
lola en el mismo artículo tienes la respuesta, mira los enlaces del final, y lee detenidamente el artículo
hola disculpa a mi tambien me marca muchos errores y no se porque..
mira me dice:
gsl/gsl_linalg.h: No such file or directory.
17 gsl_matrix’ undeclared (first use this function)
17`A’ undeclared (first use this function)
17 `gsl_matrix_alloc’ undeclared (first use this function)
y asi muchas…..
como otros 10 errores similares…
y no se que estoy haciendo mal @.@
tambien los estoy poniendo en C++ y locopie tal y como esta arriba
si me pudieras ayudar te lo agradeceria muchisimo
.de antemano muchas gracias
Hola, ¿en qué sistema operativo lo estás haciendo? ¿Has instalado antes las librerías gsl? Revisa todas las comillas del código, porque al hacer copy&paste no se hacen correctamente.
¿Lo estás compilando por terminal, con Geany o con algún otro IDE?
Saludos
Zeka, gracias por lo de libgsl0-dev, me pasó lo mismo en Debian Lenny. Es necesario instalar este paquete, ahí se encuentran todos los .h.