domingo, 24 de mayo de 2015

Librerías científicas en lenguaje C - Debian

Después de mucho tiempo de no publicar por varias razones; trabajo, familia, maestría, ocio; vuelvo a publicar un tema que para mí es interesante y ahora más debido a que la maestría que estoy cursando actualmente (Maestría en Telecomunicaciones - UNI) exige cálculos matemáticos avanzados. Es bien sabido que estos cálculos son resueltos por el software MatLab, pero cada año se va haciendo más pesado y es por la gran cantidad de módulos y software especializado que viene de serie. Pero siguiendo la filosofía UNIX "Un programa que haga una cosa, pero que la haga bien", no creo necesario "piratear" (ya que no tengo el dinero para pagar la costosa licencia) para realizar cálculos específicos. Ojo no estoy diciendo que MatLab sea malo, sino que no veo la necesidad de instalar 15 GB de cosas que no voy a utilizar. Además que mi modesta portátil sufre un poco para levantar el programa.
Para matlab existe la alternativa bandera en el mundo del software libre: GNU/Octave. Este poderoso software, además de ser opensource, es potencialmente compatible con muchos comandos que se usan en matlab y posee una sintaxis 100% compatible. De este programa hablaré más adelante ya que merece una publicación diferenciada.

Ahora hablaré de una librería cuya existencia descubrí por casualidad realizando la siguiente consulta en la terminal:

kiko@debian8:~$ apt-cache search scientific | grep lib | sort
Me arrojó entre muchas librerías, unas que me llamaron la atención por su descripción:
libgsl0-dev - GNU Scientific Library (GSL) -- development package
liblapack-dev - Library of linear algebra routines 3
libblas3 - Basic Linear Algebra Reference implementations
libatlas3-base - Automatically Tuned Linear Algebra Software

Especial atención me llamó la librería GSL. Investigando un poco y leyendo su documentación oficial que se encuentra en http://www.gnu.org/software/gsl/manual/ veo que es una poderosa librería que justamente usa las librerías lapack, blas, atlas para realizar cálculos numéricos, cálculo de complejos y cálculo matricial; todo desde programación en C (que es mi preferido pero no soy ningún gurú, apenas aficionado novato).
Para instalar la librería, ejecutamos: sudo aptitude install libgsl0-dev

Veamos un ejemplo simple dada una función de segundo grado con una variable, le asignamos un valor a su variable para obtener el resultado.
La ecuación es la siguiente:
                                       
                                           
/*
el archivo tiene por nombre ecuacion.c y darle permisos de ejecución: 
chmod 700 ecuacion.c
para compilar usar: gcc -Wall -o ecuacion.o ecuacion.c -lgsl -lgslcblas
para ejecutar: ./ecuacion.o
debe arrojar este resultado: y=52
*/
#include <stdio.h>
#include <gsl/gsl_poly.h>
float x, resultado; 
int main (int argc, char *argv[])
{
        double coeficientes[] = { 7, 6, 3 };
        printf("Ingrese el valor en el que se desea evaluar la función -----> x = ");
        scanf("%f", &x);
        printf("El valor ingresado es: x = %f\n", x);

        resultado = gsl_poly_eval (coeficientes, 3, x);
        printf ("La función a evaluar es -----> y = 3*x2 + 6*x + 7\n");
        printf ("El resultado : y = 3*x2 + 6*x + 7 = %f\n", resultado);
  return 0;
}
Si notamos en la variable "coeficientes", se debe definir los coeficientes de la ecuación empezando por el término independiente continuando hacia el coeficiente de mayor grado.

Ponemos otro ejemplo simple (aunque la programación no tanto ya que me llevó horas leyendo su manual y aún me falta muchas horas más) para que se entienda más a lo que me refiero.
Vamos a calcular las variables de un sistema de ecuaciones lineales de primer grado de 4 variables usando la librería gsl.
Usaremos el ejercicio 1 de la siguiente página: http://profe-alexz.blogspot.com/2012/08/metodo-gauss-sistema-ecuaciones-4x4.html

[ 1 -1 0  0 ] [x] = [-6]
[ 0  1 1  0 ] [y] = [ 3]
[ 0  0 1  2 ] [z] = [ 4]
[ 2  0 0 -3 ] [t] = [ 5]

/*
el archivo tiene por nombre abcd.c y darle permisos de ejecución: chmod 700 xyzt.c
para compilar usar: gcc -Wall -o abcd.o abcd.c -lgsl -lgslcblas
para ejecutar: ./xyzt.o
debe arrojar este resultado: a=31; b=37; c=-34; d=19
*/
#include <stdio.h>
#include <gsl/gsl_linalg.h>
 
int main (int argc, char *argv[])
{
double a_data[] = { 1, -1, 0,  0,
                                0,  1, 1,  0,
                                0,  0, 1,  2,
                                2,  0, 0, -3 };
double b_data[] = { -6, 3, 4, 5 };

gsl_matrix_view m = gsl_matrix_view_array (a_data, 4, 4);
gsl_vector_view b = gsl_vector_view_array (b_data, 4);
gsl_vector *x = gsl_vector_alloc (4);
int s;
gsl_permutation * p = gsl_permutation_alloc (4);
gsl_linalg_LU_decomp (&m.matrix, p, &s);
gsl_linalg_LU_solve (&m.matrix, p, &b.vector, x);
printf ("El valor de cada variable es = \n");
gsl_vector_fprintf (stdout, x, "%g");
gsl_permutation_free (p);
gsl_vector_free (x);
return 0;
}

Al momento de compilar se debe llamar a las librerías gsl y gsclbas que es donde se encuentran definidas todas las entradas que permiten ejecutar las operaciones.
Como se puede apreciar, no hay necesidad de instalar 15GB de matlab, sólo 3MB que es lo que ocupa la librería gsl y sus dependencias.
Lo que sí tenemos que invertir es tiempo en leer su extenso manual donde se define y explica cada comando.

Bueno, espero les haya animado este nano-resumen sobre las librerías de computación científica a investigar.

En la maestría uso python y sus diversos módulos: numpy, scipy, matplotlib, sympy, etc para realizar cálculos avanzados como por ejemplo la más aplicada en mi carrera, La transformada de fourier y todo lo relacionado a ello, pero también al igual que GNU/Octave, tendrá una entrada especial en un posterior post.

Por lo pronto sigo practicando con esta potente librería GSL y acabo de descubrir que hay otra librería especial para trabajar con FFT en C (la verdad que ahora entiendo porque la comunidad científica usa software GNU).
Iré poniendo mis resultados conforme vaya avanzando.
Los invito a instalar las librerías y ejecutar el código para que se vayan familiarizando.

Nos vemos.

--
JPC