Archivos de Categoría: Programación

Usando Theano (Python Con Matemáticas)

Hola, hace un par de semanas me encontré con unas librerías matemáticas basadas en Python llamadasTheano, en honor a la mujer de Pitágoras. Me parecieron interesantes y las empaqueté para Mandriva; están disponibles en MIB, por si a alguien le interesa. Con ellas podemos definir, evaluar y optimizar expresiones matemáticas que involucren arrays multidimensionales de forma eficiente.

Lo cierto es que viene muy bien para definir funciones matemáticas de cualquier dimensión, pudiendo especificar los parámetros de las funciones. Otra característica que he encontrado muy interesante es que calcula las derivadas de las funciones con un código sencillo y claro.
Destacar que estas librerías son totalmente compatibles con Numpy, Scipy y las he usado sin problemas con Mathplotlib para dibujar las gráficas de funciones.
Tienen una característica, la cual no he utilizado aún, y es que si tienes una tarjeta Nvidia con soporte Cuda puedes obtener una mayor eficiencia en cálculos grandes, pero esto poco a poco ;-)
Bien, para que veáis cómo se usan con un ejemplo un poco más elaborado que los que vienen en su documentación he realizado un pequeño programa que dibuja la función logística y su recta tangente en un punto dado, para ello he usado Mathplotlib, de esa forma podéis aprender a dibujar funciones de forma sencilla, con soporte LateX en las figuras, creación de leyendas y guardado de las imágenes en formato .png. El código es el siguiente:

#!/usr/bin/python

from matplotlib import rc
from pylab import *
from theano import *
import theano.tensor as T
import numpy

rc('text', usetex=True)
rc('font', family='serif')

x = T.fvector('x')
x1 = T.fscalar('x1')
y = 1/(1 + T.exp(-x))
y1 = 1/(1 + T.exp(-x1))
logistic = function([x], y)
logistic1 = function([x1], y1)
grady = T.grad(y1, x1)
derivada = function([x1], grady)

a = float(input('Introduce el extremo izqdo. \n'))
b = float(input('Introduce el extremo drcho. \n'))
particion = float(input('Introduce la longitud de particion del intervalo. \n'))
pderiv = float(input('Introduce el punto donde hallar su recta tangente. \n'))

xval = arange(a,b,particion, dtype='float32')
z,w,w1=T.fscalars('z', 'w', 'w1')
rectatg2 = (x-z)*w+w1
rectatg3 = function([x, Param(z, default=pderiv), Param(w, default=derivada(pderiv)), Param(w1, default=logistic1(pderiv))], rectatg2)

figure(1)

plot(xval, logistic(xval), linewidth=1.5, color='r')
plot(xval, rectatg3(xval), linewidth=1.0, color='g')
ylim([0,1])

xlabel(r'\textbf{Abcisa}', fontsize=12)
ylabel(r'\textit{Ordenada}',fontsize=12)
title(r"Funcion logistica f(x) = $\displaystyle\frac{1}{1+e^{-x}}$", fontsize=12, color='r')
legend(('Funcion Logistica', 'Recta Tangente'),'upper left', shadow=True, fancybox=True)

leg = gca().get_legend()
ltext  = leg.get_texts()
llines = leg.get_lines()
frame  = leg.get_frame()

frame.set_facecolor('0.80')
setp(ltext, fontsize='small')
setp(llines, linewidth=1.5)

grid(True)
axhline(linewidth=1.5, color='b')
axvline(linewidth=1.5, color='b')

figure(2)

plot(xval, logistic(xval), 'k.')
plot(xval, rectatg3(xval), linewidth=1.0, color='g')
ylim([0,1])
legend(('Funcion Logistica', 'Recta Tangente'),'upper left', shadow=True, fancybox=True)
leg = gca().get_legend()
ltext  = leg.get_texts()
llines = leg.get_lines()
frame  = leg.get_frame()

frame.set_facecolor('0.80')
setp(ltext, fontsize='small')
setp(llines, linewidth=1.5)

xlabel(r'\textbf{Abcisa}', fontsize=12)
ylabel(r'\textit{Ordenada}',fontsize=12)
title(r"Funcion logistica f(x) = $\displaystyle\frac{1}{1+e^{-x}}$", fontsize=12, color='r')
grid(True)
axhline(linewidth=1.5, color='r')
axvline(linewidth=1.5, color='r')

figure(1)
savefig('fig1')
figure(2)
savefig('fig2')

show()

Y el resultado del código es éste:


Nota: En esa web encontraréis un enlace de descarga de la documentación en PDF.

Saludos :-)

Geany 0.19 En Ubuntu Lucid

Hola,  para el que no lo sepa aún ha salido una nueva versión de mi editor de código favorito , Geany. A mi me gusta mucho utilizarlo porque es muy liviano, portable, de fácil uso y con muchas características, gracias a los plugins de terceros.

Geany viene muy bien para programar en multitud de lenguajes: C/C++, Perl, XML, Python, PHP, HTML e incluso disponemos con un plugin con soporte para LateX. Una de las características que más me gustan es que gracias al plugin geany-gdb podemos hacer debugs (trazas) de nuestros códigos fácilmente. En fin, que tiene muchas cosas éste magnífico editor.

Estos días a ratos lo he ido compilando  y empaquetando, si alguien lo quiere probar o actualizar está ya disponible en mi propio repositorio de Launchpad, para añadir mi repositorio, si no lo has hecho ya ;-)

sudo su -

add-apt-repository ppa:lopeztobal/maths

apt-get update

apt-get upgrade

exit

Y para instalarlo con todos los plugins nuevos:

sudo apt-get install geany-plugins geany-plugins-common

Para ejecutarlo se encuentra en Aplicaciones->Programación

Saludos :-)

QtOctave 0.9.1 En Ubuntu Lucid

Hola, hace ya unas semanas que salió la nueva versión de éste gran programa creado por el español  Pedro L. Lucas, desgraciadamente he tenido muchos problemas para empaquetarlo debido a que no aparecían los iconos del entorno gráfico si lo instalaba en /usr/share. Afortunadamente he dado con la solución ;-) Además, gracias a Jordi Gutiérrez Hermoso, empaquetador oficial del programa en Debian se ha resuelto que podamos disfrutar de Qtoctave en español :-)

Para el que no lo sepa todavía Qtoctave es un GUI escrito en Qt4 del programa Octave, con el cual podemos realizar todo aquello que realizamos en Matlab pero con una aplicación de código libre. Si quieres actualizar la versión en tu Ubuntu Lucid es muy sencillo, abre terminal y escribe:

sudo su -

add-apt-repository ppa:lopeztobal/maths

apt-get update

apt-get upgrade

apt-get install qtoctave

exit

Si ya tienes de antes añadido mi repositorio la segunda línea no te hace falta, y si ya tenías instalado qtoctave no te hace falta ejecutar la penúltima línea. Cuando tenga un hueco lo empaqueto para Mandriva ;-)

Agradecimientos-> A Jordi por su amable ayuda y paciencia :-)

Saludos :-)

Programación Lineal Con Python

Hola, en Python hay diversidad de librerías para hacer programación lineal tanto la normal como la entera. En esta ocasión os voy ha hablar de PyMathPrpog, unas librerías basadas en Glpk y PyGlpk con las cuales podemos calcular nuestros problemas en métodos como el Simplex, Exacto e Interior; o Plain y Avanzado si lo que buscamos son soluciones enteras. También podemos obtener un informe detallado de nuestra solución, las primales, las primales factibles, las duales, etc. y todo ello de forma sencilla. Esta librería no se encuentra (que yo sepa) en los repositorios oficiales de Ubuntu, pero bueno si añades mi repositorio de Launchpad la puedes instalar bajo el nombre de python-mathprog. Supongamos que queremos solucionar el siguiente problema:
Max: z=10x+6y+4z
s.a.  \begin{cases}        x+y+z \le 100 \\   10x+4y+5z \le 600 \\ 2x+2y+6y \le 300 \\ x,y,z \ge 0     \end{cases}

El código en Python usando estas librerías es el siguiente:

from pymprog import *  # Importar el modulo
# indices y datos
xid, rid = range(3), range(3)
c = (10.0, 6.0, 4.0)
mat = [ (1.0, 1.0, 1.0),
        (10.0, 4.0, 5.0),
        (2.0, 2.0, 6.0)]
b = (100.0, 600.0, 300.0)
#definicion del problema
beginModel('basic')   #Lo definimos como basico
verbose(True)
x = var(xid, 'X') #crear variables
maximize( #funcion objetivo
  sum(c[i]*x[i] for i in xid), 'miobjetivo'
)
r=st( #Conjunto de restricciones
  sum(x[j]*mat[i][j] for j in xid) <= b[i] for i in rid
)
solve() #Solucion e Informe
print "Estado Solucionador:", status()
print 'Z = %g;' % vobj()  # Valor funcion Objetivo
#Impresion de nombre de las variables y las primales
print ';\n'.join('%s = %g {dual: %g}' % (
   x[i].name, x[i].primal, x[i].dual)
                    for i in xid)
print ';\n'.join('%s = %g {dual: %g}' % (
   r[i].name, r[i].primal, r[i].dual)
                    for i in rid)

print reportKKT()
print "Environment:", env
for pn in dir(env):
    if pn[:2]=='__'==pn[-2:]: continue
    print pn, getattr(env, pn)

print ' '
print evaluate(sum(x[i]*(i+x[i])**2 for i in xid))
print sum(x[i].primal*(i+x[i].primal)**2 for i in xid)
endModel() #Finalizar el Modelo

Y la solución por terminal es:


MAX 'miobjetivo': 10 X[0]+ 6 X[1]+ 4 X[2]
s.t. R0[0]: X[0]+ X[1]+ X[2] <= 100.0
s.t. R0[1]: 10 X[0]+ 4 X[1]+ 5 X[2] <= 600.0
s.t. R0[2]: 2 X[0]+ 2 X[1]+ 6 X[2] <= 300.0
Estado Solucionador: opt
Z = 733.333;
X[0] = 33.3333 {dual: 0};
X[1] = 66.6667 {dual: 0};
X[2] = 0 {dual: -2.66667}
R0[0] = 100 {dual: 3.33333};
R0[1] = 600 {dual: 0.666667};
R0[2] = 200 {dual: 0}

Karush-Kuhn-Tucker optimality conditions:
=========================================

1) Error in Primal Solutions:
-----------------------------
Largest absolute error: 0.000000 (row id: 1)
Largest relative error: 0.000000 (row id: 1)
Quality of primal solution: H

2) Error in Satisfying Primal Bounds:
-------------------------------------
Largest absolute error: 0.000000 (var id: 0)
Largest relative error: 0.000000 (var id: 0)
Quality of primal feasibility: H

3) Error in Dual Solutions:
-----------------------------
Largest absolute error: 0.000000 (col id: 0)
Largest relative error: 0.000000 (col id: 0)
Quality of dual solution: H

4) Error in Satisfying Dual Bounds:
-------------------------------------
Largest absolute error: 0.000000 (var id: 0)
Largest relative error: 0.000000 (var id: 0)
Quality of dual feasibility: H

Environment:
blocks 45
blocks_peak 72
bytes 27508
bytes_peak 28998
mem_limit None
term_hook None
term_on True
version (4, 38)

342288.888889
342288.888889


Como vemos en la salida por terminal obtenemos un informe muy detallado de la solución y sus posibles soluciones.
Obviamente al ser este ejemplo de 3 variables no es factible dibujar su región, al igual que no lo son la mayoría de estos problemas. Tan sólo son posibles sus soluciones gráficas para problemas de 2 variables, que se dan mayoritariamente en Bachiller. A mi estas librerías me parecen una buena alternativa al programa no libre LINGO. Me queda pendiente verlo con python-cvxopt, pero eso os lo cuento otro día ;-)

Saludos :-)

Librerías Lapack++ En Launchpad

Hola, siguiendo con mi particular cruzada de debianizar programas y librerías matemáticas he empaquetado por primera vez para Ubuntu y/o Debian las librerías matemáticas Lapack++, las cuales son una adaptación de las librerías Lapack, basadas en FORTRAN, al lenguaje C++

Para instalarlas tan sencillo como añadir mi repositorio e instalar los dos paquetes de que se compone:

sudo su -

add-apt-repository ppa:lopeztobal/maths

apt-get update

apt-get install liblapackpp-dev liblapackpp-doc

El segundo paquete es para poder acceder al tutorial de las librerías en html con vuestro navegador favorito, lo tenéis en el enlace siguiente:

Para poder practicar en su uso y ver si funciona os pongo el código de un pequeño ejemplo:

//      matrices22.cpp
//
//      Copyright 2010 Cristobal Lopez <lopeztobal@gmail.com>
//
//      This program is free software; you can redistribute it and/or modify
//      it under the terms of the GNU General Public License as published by
//      the Free Software Foundation; either version 2 of the License, or
//      (at your option) any later version.
//
//      This program is distributed in the hope that it will be useful,
//      but WITHOUT ANY WARRANTY; without even the implied warranty of
//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//      GNU General Public License for more details.
//
//      You should have received a copy of the GNU General Public License
//      along with this program; if not, write to the Free Software
//      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
//      MA 02110-1301, USA.

#include <iostream>
#include <stdio.h>
#include <lapackpp/laslv.h>

using namespace std;

int main(int argc, char **argv)
{
double a[]={ 1.0, 1/2.0, 1/3.0, 1/4.0,
                  1/2.0, 1/3.0, 1/4.0, 1/5.0,
                  1/3.0, 1/4.0, 1/5.0, 1/6.0,
                  1/4.0, 1/5.0, 1/6.0, 1/7.0 };
LaVectorDouble v(4);
LaVectorDouble c(4);

LaGenMatDouble A(a,4,4);
LaEigSolve(A,c,v,A);

cout<<"A = "<<endl<<A<<"\t";
cout<<"\nLos valores y vectores propios son:"<<endl;
cout<<c<<" + "<<v<<"i"<<endl;
return(0);
}

Para compilarlo y ejecutarlo por terminal:


g++ matrices22.cpp -o matrices22 -llapackpp
./matrices22

Y si lo queréis hacer con un IDE como Geany es sencillo, id a:


Construir->Seleccionar inclusiones y argumentos

Y en las dos primeras líneas añadid al final -llapackpp

Estas librerías son muy potentes y sirven para trabajar directamente con algoritmos matemáticos de Aproximación Numérica, muy útiles también para matrices dispersas.

Saludos :-)

Page 1 of 612345...Last »