Aprendiendo Sobre Las Librerías Ginac

por | 16 abril, 2009

Hola, bueno aquí estoy para daros la vara una vez más, esta vez voy ha hablaros sobre unas librería matemáticas escritas en C++ que se llaman GiNaC. Las descubrí el otro día en los repositorios de Mandriva, me fui a su web, las vi, me bajé el tutorial en pdf, me interesaron bastante y aquí estoy escribiendo sobre ellas en el blog

Bueno, estas librerías me gustaron por muchas razones, la principal es que ya llevan implementado en su última versión un parser, y vosotros diréis: “¿Y ezo qué es quillooo?” Pues bien, el parser es una especie de librerías que nos permiten crear nuestro propio lenguaje lexicográfico, en el caso de las Ginac el lenguaje creado con parser es el matemático. Os pongo un fácil ejemplo para que lo entendáis:

Suponed que yo hago un programa para calcular las raíces de una función. Lo mejor es que el programa pida al usuario que introduzca la expresión matemática de dicha función, por ejemplo supongamos que el usuario introduce la función cos(x-5)+5*x. Pues bien, resulta que ni C ni C++ saben interpretar eso como una función, sólo podemos decirle que es una cadena (string o CString), pero el paso de que interprete dicha expresión matemática como lo que es no tiene ni idea. Una forma de solventar el problema es definir un lenguaje matemático con sus correspondientes reglas de porecedencia y demás, ahí entra en juego librerías llamadas Parser, como la conocida muParser, con la cual podríamos definir nuestro propio lenguaje. Esto conlleva mucho tiempo, pero todo ello ya viene implementado con GiNaC, así que con unas cuantas líneas de código en nuestro programa lo solventamos. Tranquilos que ahora luego os pongo ejemplos en C++ de ello.

Esto está cojonudo pero desgraciadamente está implementado en las versiones más recientes de las librerías, y claro, como siempre pasa con la programación científica y las mates, la versión más reciente de GiNaC, la 1.5.1, no  viene empaquetada ni en Mandriva ni en Ubuntu. Pero tranquilos… ya me he hecho un rpm para Mandriva de la versión 1.5.1, si la queréis pongo enlace de descarga:

DESCARGAR GINAC 1.5.1 MANDRIVA 2009.1

Para Ubuntu aún no he tenido tiempo de debianizarlas, pero si alguien las quiere para probarlas que me lo pida por aquí y lo hago.

Otra de las cosas buenas que tiene es que se apoyan sobre las librerías CLN, que son otras librerías matemáticas hechas exprofesso para definir diferentes tipos de variables numéricas, con diferentes precisiones. Con GiNaC podemos trabajar con tensores, lleva algunos definidos por sí; tanto tensores covariantes como contravariantes, y la verdad es que no es nada complicado; ya os enseñaré algo un día de estos.

También se puede trabajar con matrices, derivadas, vectores, listas, números complejos, etc… Con las integrales anda un poco flojo el tema, por ahora sólo calcula integrales polinómicas definidas, pero dicen que esperan implementarlo pronto; aunque a mi eso me da un poco lo mismo. Tiene un montón de funciones más que todavía no conozco y que podéis consultar en el manual en formato pdf o ps que os podéis descargar desde su web.

Para compilar y ejecutar nuestros programas hay que hacer lo siguiente:

g++ miprograma.cpp -o miprograma -lcln -lginac

./miprograma

Yo lo que hago es escribirlos, compilarlos y ejecutarlos desde Geany, es muy cómodo y sencillo de usar. Lo único que hay que hacer antes en Geany para que nos compile bien es ir a la opción Construir->Selecciona Inclusiones y Argumentos y rellenar la ventana que os aparece como os pongo en la siguiente imagen:

Geany

Vale, con esto creo que ya podemos pasar a ver unos cuantos ejemplos, sencillitos que acabamos de empezar con esto.

El primer código es un programa que calcula la primera y segunda derivada de una función, nos factoriza la segunda derivada y además nos calcula el mcd y el mcm de dos polinomios dados.

  1. #include <iostream>
  2. #include <ginac/ginac.h>
  3.  
  4. using namespace std;
  5. using namespace GiNaC;
  6.  
  7. int main(int argc, char** argv)
  8. {
  9.  symbol x("x"); //Con symbol declaramos la variable en la que vamos
  10.  // a trabajar, podemos declarar tantas como queramos
  11.  ex mifuncion, deriv1, deriv2, polinomio1, polinomio2;
  12.  // ex es un nuevo tipo de variable definida en GiNaC, es una
  13.  // abeviación del inglés expression, con ella declaramos expresiones
  14.  // matemáticas siguiendo las reglas naturales de lexicografía del
  15.  // lenguaje matemático.
  16.  
  17.  mifuncion = 3*x*cos(x*x-x)+Pi*x-5; //Declaro la expresión de mi
  18.  //función, siendo Pi la forma de declarar la cte. pitagórica.
  19.  polinomio1 = pow(x,2)-2*x+1;
  20.  polinomio2 = pow(x,2)-1;
  21.  deriv1 = mifuncion.diff(x); //Calculo la derivada 1ª. de mi función
  22.  deriv2 = mifuncion.diff(x,2); //Calculo la derivada 2ª.
  23.  
  24.  cout<<"Mi funcion es: "<<endl<<mifuncion<<endl;
  25.  cout<<"Y su primera derivada es: "<<endl<<deriv1<<endl;
  26.  cout<<"Y su segunda derivada es: "<<endl<<deriv2<<endl;
  27.  cout<<"Su segunda derivada en factores es: "<<endl<<factor(deriv2, factor_options::all)<<endl;
  28.  //Con factor puedo factorizar la expresión algebraica.
  29.  cout<<"\n Mi polinomio 1 es:"<<endl<
  30. <polinomio1<<endl;
  31.  cout<<"\n Mi polinomio 2 es:"<<endl<<polinomio2<<endl;
  32.  cout<<"El maximo comun divisor de los polinomios es: "<<endl<<gcd(polinomio1, polinomio2)<<endl;
  33.  cout<<"El mminimo comun multiplo de los polinomios es: "<<endl<<lcm(polinomio1, polinomio2)<<endl;
  34.  //Con gcd y lcm puedo calcular el mcd y el mcm tanto de expresiones algebraicas como de números.
  35.  return 0;
  36. }

En el código tenéis los respectivos comentarios. Sólo apuntar que los includes que hay que poner para que funcionen nuestros programas con GiNaC es lo siguiente:

  1. #include <ginac/ginac.h>
  2.  
  3. using namespace std;
  4. using namespace GiNaC;

Os pongo un pantallazo del resultado de nuestro código por terminal:

screenshot_003

Ahora veamos otro programita pero a diferencia del anterior pediremos que el usuario nos introduzca por terminal las expresiones algebraicas, en este caso introduciremos un polinomio por terminal y hallaremos su segunda derivada y su integral en el intervalo [0,2]. Aquí tenéis el código:

  1. #include <iostream>
  2. #include <ginac/ginac.h>
  3. #include <string>
  4.  
  5. using namespace std;
  6. using namespace GiNaC;
  7.  
  8. int main(int argc, char** argv)
  9. {
  10.  symbol x("x");
  11.  ex expr1, expr2, expr3;
  12.  parser mifuncion;
  13.  symtab tabla;
  14.  
  15.  cout<<"Introduce tu expresion"<<endl;
  16.  expr1 = mifuncion(cin);
  17.  tabla = mifuncion.get_syms();
  18.  x = tabla.find("x") != tabla.end() ?
  19.  ex_to<symbol>(tabla["x"]) : symbol("x");
  20.  
  21.  expr2 = integral(x,0,2,expr1).eval_integ();
  22.  expr3 = expr1.diff(x,2);
  23.  
  24.  cout<<"\nTu expresion es :"<<endl<<expr1<<endl;
  25.  cout<<"La integral en [0,2] de "<<expr1<<" es: "<<expr2<<endl;
  26.  cout<<"La derivada segunda de "<<expr1<<" es:"<<endl<<expr3<<endl;
  27.  return 0;
  28. }

Y aquí un pantallazo de los resultados del programa por terminal:

screenshot_004

Cuando acabéis de introducir la expresión por terminal debéis presionar las teclas CTRL+D en LinuX o CTRL+Z en Windows porque el código espera la señal de final de fichero, EOF.

Como veís con poco código conseguimos unos resultados  excelentes, que podemos mejorar ya que GiNaC nos brinda la posibilidad de poder hacer nuestras salidas en código LaTeX, lo cual nos hace tener una notación tipo profesional de nuestros programas con muy poco esfuerzo. Esto os lo explicaré en una próxima entrega que esta ya se esta haciendo un poco larga y seguro que os aburro :p

Saludos

4 pensamientos en “Aprendiendo Sobre Las Librerías Ginac

  1. ica

    Simplemente Geniales tus tutoriales los he estado practicando porque era justo los que buscaba, ojala tengas tiempo de debianizar el rpm porque yo trate con alien pero marcaba errores, sigue asi. Saludos

  2. ica

    Que ta Cristobal quisiera pedirte de favor si me pudieras pasar el archivo ginac.1.5.1.deb para ubuntu por que no puedo hacer correr estos programas debido a que tengo la version antigua del ginac.Saludos

  3. ica

    Ya por fin lo logre instalar desde los fuentes muchas gracias por compartir tu conocimiento a través de este blog. Saludos y seguimos en contacto.

Los comentarios están cerrados.