sábado, 8 de marzo de 2014

Álgebra lineal


Álgebra Lineal


Veamos como se resuelve el problema de autovalores de una matríz de 2x2, sabemos de antemano que los autovalores de esta matriz se encuentran a través de la ecuación cuadrática

Det(AλI)=0
Edit Plugin:html
cuyas raices están dadas por:

λ1,2=Tr(A)2±[Tr(A)]24Det(A)2
Edit Plugin:html
Donde Tra es la traza de la matriz y Det su determinante.
Veamos el algoritmo:
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<time.h>

int det2(int A[2][2])
{
    return A[0][0]*A[1][1]-A[0][1]*A[1][0];
}

int tra2(int A[2][2])
{
    return A[0][0]+A[1][1];
}

double* autovalores(int A[][2])
{
    static double lambda[2];
    int tra=tra2(A);
    lambda[0]= (tra+sqrt(tra*tra-4*det2(A)))/2;
    lambda[1]= (tra-sqrt(tra*tra-4*det2(A)))/2;

    return lambda;
}


int main()
{
    srand(time(NULL));
    int a[2][2];
    int i,j;
    double *lambda;
    for(i=0;i<2;i++) {
        for(j=0;j<2;j++) {
     a[i][j]=rand()%10-5;
            printf("%d ",a[i][j]);
 }
 printf("\n");
    }

    lambda=autovalores(a);
    printf("Los autovalores son %f y %f\n",lambda[0], lambda[1]);

    return 0;
}
Edit Plugin:code
Para evaluar la raiz hemos usado la librería matemática que no se enlaza por defecto cuando vamos a compilar. Esto es, para compilar debemos hacer:
gcc autovalores.c -o autovalores -lm
Edit Plugin:code

Pregunta
  • ¿Qué consideraciones debemos tener para que el algoritmo soporte complejos?

Existen librerías que realizan estas tareas de manera efectiva y con una implementación relativamente sencilla. Las más comunes en el ámbito científico (y libres) son BLAS(Basic Linear Algebra Subroutines) para C y LAPACK(Linear Algebra PACKage) para frotran. Existen otras pocas no libres como MKL desarrollada por intel.
Veamos un ejemplo de como invertir una matriz con la ayuda de las librerías BLAS y su interfaz con gsl:
#include <stdio.h>
#include <gsl/gsl_linalg.h>

int main ()
{
  double mat[] = { 1, -1, -2,
                   0, 2, 0,
                   -2,1,-1,};
  double inv[9];

  gsl_matrix_view m = gsl_matrix_view_array (mat, 3, 3);
  gsl_matrix_view inverse = gsl_matrix_view_array (inv, 3, 3);
  
  int signum;

  gsl_permutation * p = gsl_permutation_alloc(3);

  printf("Matriz inicial\n");
  gsl_matrix_fprintf (stdout, &m.matrix, "%g");

  gsl_linalg_LU_decomp(&m.matrix, p, &signum);

  printf("Matriz LU\n");
  gsl_matrix_fprintf (stdout, &m.matrix, "%g");

  printf("Matriz LU\n");
  gsl_matrix_fprintf (stdout, &m.matrix, "%g");

  gsl_linalg_LU_invert(&m.matrix, p, &inverse.matrix);

  printf("Inversa\n");
  gsl_matrix_fprintf (stdout, &inverse.matrix, "%g");

  gsl_permutation_free (p);
  return 0;
}
Edit Plugin:code

Al igual que cuando invocamos la librería matemática, para obtener el ejecutable debemos enlazar las librerías de gsl haciendo:
$ gcc inversa.c -lgsl -lgslcblas
Edit Plugin:code
para mayor información sobre el uso de esta librería nos podemos referir a la documentación de gsl(external link)

Ejercicios

1 comentario: