Cómo resolver ecuaciones algebraicas en Python con SciPy

Introducción

En este artículo vamos a utilizar las rutinas de búsqueda de raíces ya disponibles en el módulo scipy.optimize para resolver ecuaciones algebraicas con Python. Ya vimos hace tiempo cómo encontrar el mínimo de una función con SciPy, y también cómo implementar los métodos de la bisección y de Newton en Python. Ahora, además, exploraremos el caso de sistemas de ecuaciones.

En esta entrada se ha usado python 2.7.3, numpy 1.6.2 y scipy 0.11.

Ejemplo básico: métodos de Brent y de Newton

Aunque el método de la bisección es muy conocido porque conceptualmente es muy sencillo de entender, nos vamos a olvidar de él y vamos a utilizar en su lugar el método de Brent, que viene implementado en SciPy en la función scipy.optimize.brentq, ya que según la documentación es la mejor opción. El método de Brent es un algoritmo complicado que combina el método de la bisección, el de la secante e interpolación cuadrática inversa: como el método de la bisección, tiene convergencia garantizada siempre que demos un intervalo \([a, b]\) donde \(f(a) f(b) < 0\); es decir, que haya un cambio de signo en el intervalo.

Continue reading

¿Cómo encontrar el mínimo de una función usando scipy?

NOTICE: Esta entrada es una traducción libre (algunas cosas no serán traducidas por no existir una traducción sencilla en castellano) de un artículo publicado en The Glowing Python con permiso de su autor.

Para la siguiente entrada se ha usado python 2.7.2, numpy 1.6.1, scipy 0.9.0 y matplotlib 1.1.0

En este ejemplo veremos como usar la función fmin para minimizar una función. La función fmin se encuentra en el módulo optimize de la librería scipy. La función fmin usa el algoritmo downhill simplex para encontrar el mínimo de la función objetivo empezando por un punto inicial dado por el usuario. En el ejemplo emezaremos a partir de dos puntos iniciales diferentes para comparar los resultados.

import numpy
import matplotlib.pyplot as plt
from scipy.optimize import fmin
# Función objetivo
rsinc = lambda x: -1 * numpy.sin(x)/x
# Empezamos a partir de x = -5
x0 = -5
xmin0 = fmin(rsinc,x0)
# Empezamos a partir de x = -4
x1 = -4
xmin1 = fmin(rsinc,x1)
# Dibujamos la función
x = numpy.linspace(-15,15,100)
y = rsinc(x)
plt.plot(x,y)
# Dibujo de x0 y el mínimo encontrado empezando en x0
plt.plot(x0,rsinc(x0),'bd',xmin0,rsinc(xmin0),'bo')
# Dibujo de x1 y el mínimo encontrado empezando en x1
plt.plot(x1,rsinc(x1),'rd',xmin1,rsinc(xmin1),'ro')
plt.axis([-15,15,-1.3,0.3])
plt.show()

La función fmin escribirá algunos detalles sobre el proceso iterativo llevado a cabo (dejamos la salida en inglés, que es lo que encontraréis cuando corráis el ejemplo):

Optimization terminated successfully.
         Current function value: -0.128375
         Iterations: 18
         Function evaluations: 36
Optimization terminated successfully.
         Current function value: -1.000000
         Iterations: 19
         Function evaluations: 38

Y la siguiente gráfica aparecerá en la pantalla:

Uso de la función fmin en scipy.optimize

El punto azul es el mínimo encontrado empezando a partir del diamante azul (x=-5) y el punto rojo es el mínimo encontrado a partir del diamante rojo (x=-4). En este caso, cuando empezamos a partir de x=-5 fmin se 'atasca' en un mínimo local mientras que si empezamos a partir de x=-4 fmin alcanza el mínimo global.

[Thanks to @JustGlowing to allow us to translate their articles]

Saludos.