Вы находитесь на странице: 1из 77

Programacion con Python

Release 0.4

Oscar Vargas Torres

02 de September de 2013

ndice general

1 Programacin bsica 1.1 Introduccin . . . . . . . . 1.2 Python bsico . . . . . . . 1.3 Expresiones y operadores . 1.4 Procedimientos y funciones 1.5 Estructuras de control . . . 2 Grcas 2.1 Grcas simples . . . . . . 2.2 Grcas de contorno . . . . 2.3 Grcas en 3D . . . . . . . 2.4 Ejercicios . . . . . . . . . . 2.5 Grcas de algunos campos

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

3 3 8 9 10 11 23 23 27 28 29 30

. . . . . . . . . . . . . . . . . . . . simples

3 lgebra lineal 33 3.1 Arreglos de NumPy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 3.2 lgebra Lineal bsica con NumPy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 3.3 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 4 Polinomios e interpolacin 39 4.1 Introduccin a la Interpolacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 4.2 Interpolacin segmentaria (splines) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 5 Ajuste de funciones 43 5.1 Regresin por mnimos cuadrados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 6 Races de ecuaciones no lineales 49 6.1 Introduccin: Races de ecuaciones no lineales . . . . . . . . . . . . . . . . . . . . . . . . . . 49 6.2 Un vistazo a la librera GNU Scientic Library (GSL) . . . . . . . . . . . . . . . . . . . . . . 54 7 Diferenciacin e integracin numrica 59 7.1 Diferenciacin numrica bsica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 7.2 Integracin numrica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

8 Ecuaciones Diferenciales Ordinarias 65 8.1 Ecuaciones Diferenciales Ordinarias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 8.2 PROYECTO FINAL: Rescatando a la tripulacin del Apollo 13 . . . . . . . . . . . . . . . . 70 9 ndices y tablas 73

ndice

73

ii

Programacion con Python, Release 0.4

Contents:

ndice general

Programacion con Python, Release 0.4

ndice general

CAPTULO

Programacin bsica

1.1 Introduccin
1.1.1 Por qu aprender a programar?
Porque es una habilidad que aumenta tus posibilidades de adquirir un mejor empleo. Para realizar clculos intensos, es necesario utilizar una computadora, pues hacerlos a mano sera muy tardado o imposible. Ejemplos de reas en las que puedes aplicar la programacin: Mtodos numricos: Resuelva de manera numrica (utilizando el mtodo de Euler) el sistema masa-resorte dado por la ecuacin diferencial mu + u + ku = F (t), u(0) = U0 , u (0) = 0

Sistema masa resorte que se describe mediante una ecuacin diferencial Gracacin. A continuacin se muestra un histograma obtenido a partir de una distribucin de probabilidad normal.

Programacion con Python, Release 0.4

import matplotlib.pyplot as plt import numpy as np x = np.random.randn(1000) plt.hist(x, 20) plt.grid() plt.show()

160 140 120 100 80 60 40 20 04 3 2 1 0 1 2 3

1.1.2 Python como primer lenguaje de programacin


Se ha escogido Python como un lenguaje de programacin porque combina capacidadades notables con una sintxis limpia, simple y compacta. Enunciamos algunas caractersticas de Python: Python es fcil de aprender y es muy apropiado para un curso introductorio de programacin. Es muy similar a Matlab y un buen lenguaje para hacer cmputo matemtico. Es fcil de combinar con lenguajes compilados como Fortran, C y C++, que son lenguajes ampliamente usados para cmputo cientco.

1.1.3 Instalacin de software utilizado en el curso


Se requiere: WinPython 3.3 Puedes descargarlo e instalarlo de http://code.google.com/p/winpython/downloads/list

Captulo 1. Programacin bsica

Programacion con Python, Release 0.4

1.1.4 Temario
1. Programacin con software matemtico. (a) Conceptos bsicos de programacin (con Python 3.x). Ejemplo: funciones. (b) Lectura y escritura de datos simple. 2. Grcas con software matemtico. (a) Matplotlib y Numpy. (b) Grcas simples en 2D y en 3D.
import matplotlib.pyplot as plt import numpy as np x = np.arange(-2, 2, 0.01) y = np.arange(-2, 2, 0.01) X, Y = np.meshgrid(x, y) ellipses = X*X/9 + Y*Y/4 - 1 cs = plt.contour(ellipses) plt.clabel(cs) plt.show()

0.2000.000 -0.200 350

0.000

0.200

-0.400
-0.800

300 250 200 150 100 50 00


0.200

-0.600
-0.200
50
0.000 100 150

-0.400

200

250

0.000 0.200 300 350

Grca de contornos. 3. lgebra lineal. (a) Matrices y vectores. (b) Sistemas de ecuaciones lineales.

1.1. Introduccin

Programacion con Python, Release 0.4 [ Para resolver el sistema de ecuaciones lineales Ax = b dado por A =
import numpy as np A = np.array([[3.0, 2.0], [-1.0, 2.0]]) b = np.array([18.0, 2.0]) from numpy.linalg import solve x = solve(A, b) print(x) # Solucin: x = [4.0, 3.0]

] [ ] 3 2 18 yb= : 1 2 2

4. Polinomios e interpolacin.
import numpy as np from scipy.interpolate import interp1d import matplotlib.pyplot as plt x = np.linspace(0, 10, 10) y = np.cos(-x**2/8.0) f = interp1d(x, y) f2 = interp1d(x, y, kind='cubic') xnew = np.linspace(0, 10, 40) plt.plot(x, y, 'o', xnew, f(xnew), '-', xnew, f2(xnew), '--') plt.legend(['data', 'linear', 'cubic'], loc='best') plt.show()

5. Ajuste de funciones. (a) Regresin. (b) Interpolacin. 6. Races de ecuaciones no lineales. Se tratar de hallar las races de ecuaciones. Es decir, el problema es: resolver f (x) = 0 para x. Ejemplo: determine la raz ms grande de h(x) = 2x3 11.7x2 + 17.7x 5 en forma grca.
import numpy as np import matplotlib.pyplot as plt x = np.linspace(0, 4) y = 2 * x**3 - 11.7 * x**2 + 17.7 * x - 5 plt.plot(x, y) plt.grid() plt.show()

Captulo 1. Programacin bsica

Programacion con Python, Release 0.4

8 6 4 2 0 2 4 6 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0

7. Funciones de splines e interpolacin no lineal. 8. Diferenciacin e integracin numrica. 9. Problemas de valor inicial de ecuaciones diferenciales ordinarias. El movimiento vertical de un peso sujeto a un resorte que obedece la Ley de Hooke, y que tiene un estmulo senoidal externo se puede modelar con la ecuacin diferencial:
2 y + 2cy + 0 y = F0 sin(t)

(1.1)

donde c, 0 y son nmeros reales positivos. Considremos el caso en que c < 0 , que corresponde a un sistema sub-amortiguado. Adems suponga que < 0 . Con estas suposiciones, la solucin general de (1.1) se puede expresar como y = yu + yd , donde ( ) ( ) 2 c2 + C ect sin t 2 c2 yu = C1 ect cos t 0 (1.2) 2 0 yd = F0 M ( ) sin[t + ( )] C1 , C2 dependen de las condiciones iniciales y M ( ) = 1 (1.4) (1.5) (1.3)

2 2 )2 + 4c2 2 (0 ( ) 2c ( ) = arctan < ( ) < 0 2 2 0

1.1. Introduccin

Programacion con Python, Release 0.4

Figura 1.1: Regla trapezoidal (Integracin numrica)

1.2 Python bsico


Para iniciar con lo ms bsico, te recomiendo estudiar el Tutorial de Python (no es necesario que revises todo el tutorial, pero si es importante que empieces lo ms pronto posible, y que vayas practicando cada tema que se vea en clase) en http://docs.python.org/3/tutorial/index.html (este tutorial est en ingls, pero es el tutorial adecuado para la versin de Python que estaremos usando en el curso). Tambin puedes apoyarte en una versin del tutorial en espaol disponible en http://docs.python.org.ar/tutorial/3/index.html. Especialmente importantes son las secciones 1 a 5 del tutorial. Asegrate de estudiar al menos estas secciones del tutorial.

1.2.1 Prctica 1
1. Descarga WinPython de http://code.google.com/p/winpython/downloads/list y ejecuta el instalador (Verica primero si tienes una computadora con un sistema operativo de 64 bits o de 32 bits y descarga la versin ms apropiada para ti. Si tienes dudas, pregunta a tu profesor cmo averiguar esto. Otra opcin que tienes es descargar la versin de 32 bits, que puede ejecutarse en los dos tipos de computadoras). 2. Estudia con tu computadora el tutorial de Python, mencionado anteriormente. En otras palabras, ejecuta en tu computadora las instrucciones que se dan en esta seccin a la vez que vas leyendo el tutorial. Anota las dudas que tengas para que puedas preguntar ms adelante a tu profesor.

Captulo 1. Programacin bsica

Programacion con Python, Release 0.4

1.2.2 Prctica 2
Visita la pgina http://sta.not.iac.es/~rcardenes/hg/diveintopython3-es/native-datatypes.html y estudia los tipos de datos nativos que soporta Python 3 (puedes consultar la versin original en ingls en http://getpython3.com/diveintopython3/native-datatypes.html)

1.3 Expresiones y operadores


1.3.1 Prctica 3
1. Considere el movimiento vertical de una pelota que se lanza al aire. Dicho movimiento est dado por la frmula 1 y (t) = v0 (t) gt2 2 (1.6)

Con ayuda del siguiente bloque de cdigo, verica la posicin de la pelota a los 0.6 segundos de ser lanzada, si la velocidad inicial con que fue lanzada es de 6 m/s:
# Program for computing the height of a ball in vertical motion. v0 = 5 # initial velocity g = 9.81 # acceleration of gravity t = 0.6 #time y = v0*t - 0.5*g*t**2 # vertical position print(y)

Cules son los operadores que utilizas para la multiplicacin y para la exponenciacin? 2. Considere el movimiento vertical de la pelota dado por la ecuacin (1.6). Cunto tiempo le toma a la pelota alcanzar la altura yc ? 1 2 gt v0 t + yc = 0 2 Usando la frmula general para encontrar las races de una ecuacin de segundo grado, comprueba que las soluciones son: Comprueba que las soluciones estn dadas por las races de la ecuacin ( t1 = v0
2 v0

) 2gyc /g,

( ) 2 t2 = v0 + v0 2gyc /g

(1.7)

Utilizando el siguiente bloque de cdigo, averigua cules son los dos instantes de tiempo en que una pelota est a una altura de 0.3 m, si la velocidad inicial de la pelota es de 6 m/s:
v0 = 5 g = 9.81 yc = 0.2 import math t1 = (v0 - math.sqrt(v0**2 - 2*g*yc))/g t2 = (v0 + math.sqrt(v0**2 - 2*g*yc))/g print('En t={0:.4f} s y t={1:.4f} s, la altura es {2:.4f} m.'.format(t1, t2, yc))

3. Revisa los siguientes links http://docs.python.org/3/library/numeric.html http://docs.python.org/3/library/math.html

1.3. Expresiones y operadores

Programacion con Python, Release 0.4

Utilizando el siguiente bloque de cdigo, indica cules son los valores que toma la variable v:
import math as m # m is now the name of the math module v = m.sin(m.pi) from math import log as ln v = ln(5) from math import sin as s, cos as c, log as ln v = s(x)*c(x) + ln(x)

4. Con ayuda del siguiente cdigo, calcula las dos races complejas de la ecuacin cuadrtica f (x) = ax2 + bx + c cuando a = 1, b = 2 y c = 100:
>>> a = 1; b = 2; c = 100 # polynomial coefficients >>> from numpy.lib.scimath import sqrt >>> r1 = (-b + sqrt(b**2 - 4*a*c))/(2*a) >>> r2 = (-b - sqrt(b**2 - 4*a*c))/(2*a)

1.4 Procedimientos y funciones


1.4.1 Prctica 4
1. Introduce la siguiente funcin en WinPython (o en IDLE, emacs, o el editor de tu preferencia):
def mi_funcion(param1, param2): print param1 print param2

2. Llama la funcin anterior con los argumentos 3 Hola Cul es el tipo de estos argumentos? Utiliza la funcin type() 3. Convierte de metros a unidades de longitud inglesas. Construye un programa que reciba una longitud en metros y que entonces calcule y depliegue la correspondiente longitud en pulgadas, pies y millas. Utiliza las siguientes equivalencias: 1 pulgada = 2.54 cm 1 pie = 12 pulgadas 1 yarda = 3 pies 1 milla inglesa = 1760 yardas Como vericacin puede usar los siguientes datos: 640 m = 25196.85 pulgadas = 2099.74 pies = 699.91 yardas = 0.3977 millas inglesas 4. Modica (en caso de ser necesario) el programa del ejercicio anterior de modo que utilices funciones para resolver el problema propuesto. 5. Basndote en el siguiente cdigo, calcula el rea de un paralelogramo, de un cuadrado y de un crculo, as como el volumen de un cono utilizando funciones:

10

Captulo 1. Programacin bsica

Programacion con Python, Release 0.4

from math import pi h = 5.0 # altura b = 2.0 # base r = 1.5 # radio area_paralelogramo = h*b print("El area del paralelogramo es {0:.3f}".format(area_paralelogramo)) area_cuadrado = b**2 print("El area del cuadrado es {}".format(area_cuadrado)) area_circulo = pi*r**2 print("El area del circulo es {0:.3f}".format(area_circulo)) volumen_cono = 1.0/3*pi*r**2*h print("El volumen del cono es {0:.3f}".format(volumen_cono))

1.5 Estructuras de control


1.5.1 Estructuras selectivas
Estudia las pginas 29 a 31 del libro Python para todos. Ejemplo 1 Construya un diagrama de ujo (vea la Figura Seleccin simple (if)) tal que dado como dato la calicacin de un alumno en un examen, escriba aprobado en caso de que esa calicacin sea mayor o igual a 70.

Figura 1.2: Seleccin simple (if)

1.5. Estructuras de control

11

Programacion con Python, Release 0.4

El siguiente cdigo imprime Aprobado:


cal = 80 if cal >= 70: print("Aprobado")

Ejemplo 2 Construya un diagrama de ujo (vea la Figura Seleccin doble (if else).) tal que dado como dato la calicacin de un alumno en un examen, escriba aprobado si su calicacin es mayor o igual a 70 y reprobado en caso contrario.

Figura 1.3: Seleccin doble (if El siguiente cdigo imprime Reprobado:


cal = 60 if cal >= 70: print("Aprobado") else: print("Reprobado")

else).

Ejemplo 3 Construya un diagrama de ujo tal que dado como datos la categora y el sueldo de un trabajador, calcule el aumento correspondiente teniendo en cuenta la siguiente tabla. Imprima la categora del trabajador y su nuevo sueldo. Categora 1 2 3 4 Aumento 15% 10% 8% 7%

El siguiente cdigo resuelve el ejemplo:

12

Captulo 1. Programacin bsica

Programacion con Python, Release 0.4

cat = 2 sue = 1000 if cat == 1: n_sue = sue * 1.15 elif cat == 2: n_sue = sue * 1.10 elif cat == 3: n_sue = sue * 1.08 else: n_sue = sue * 1.07 print("La categora del trabajador es {}".format(cat)) print("El nuevo sueldo es {}".format(n_sue))

Cul es el salario del trabajador (considerando que el salario actual es de $1000.00) para cada categora? Ejercicios 1. Construya un diagrama de ujo tal que dado como dato un nmero entero, determine e imprima si el mismo es positivo, negativo o cero. Utilice la estructura de seleccin multiple. Despus codique su solucin en Python. 2. En una tienda efectan un descuento a los clientes dependiendo del monto de la compra. El descuento se efecta con base en el siguiente criterio: Si el monto es menor que $500.00, no hay descuento. Si el monto est comprendido entre $500.00 y $1,000.00 (inclusive), 5% de descuento. Si el monto est comprendido entre $1,000.00 y $7,000.00 (inclusive), 7% de descuento. Si el monto est comprendido entre $7,000.00 y $15,000.00 (inclusive), 11% de descuento. Si el monto es mayor a $15,000.00, 18% de descuento. Construya un diagrama de ujo que ilustre la solucin del ejercicio. Despus codique su solucin en Python. 3. En un estudio se ha hecho un estudio sobre los pacientes registrados durante los ltimos 10 aos, con el objeto de hacer una aproximacin de los costos de internacin por paciente. Se obtuvo un promedio diario segn el tipo de enfermedad que aqueja al paciente. Adems se pudo determinar que en promedio todos los pacientes con edad entre 14 y 22 aos implican un costo adicional del 10%. La siguiente tabla expresa los costos diarios, segn el tipo de enfermedad. Tipo de enfermedad 1 2 3 4 Costo/paciente/da 25 16 20 32

Construya un programa en Python que calcule e imprima el costo total que representa un paciente (pista: considere el nmero de das que el paciente permanece internado).

1.5.2 Estructuras cclicas


Estudia las pginas 32 a 35 del libro Python para todos

1.5. Estructuras de control

13

Programacion con Python, Release 0.4

Ejemplo 1 Imprima una tabla de conversin de grados Celsius a grados Fahrenheit. Dicha tabla debe verse como la siguiente: Celsius -20 -15 -10 -5 0 5 10 15 20 25 30 35 40 Fahrenheit -4.0 5.0 14.0 23.0 32.0 41.0 50.0 59.0 68.0 77.0 86.0 95.0 104.0

El siguiente cdigo resuelve el ejemplo:


print("------------------") # Encabezado de la tabla C = -20 dC = 5 while C <= 40: F = (9.0/5)*C + 32 print("{0}, {1}".format(C, F)) C = C + dC print("------------------") # Fin de la tabla # valor inicial de C # incremento de C en el ciclo # mientras C sea menor o igual que 40, hacer

Podemos construir una lista de las temperaturas con el siguiente cdigo:


Cdegrees = [] for C in range(-20, 45, 5): Cdegrees.append(C)

List Comprehension. Dado que recorrer una lista elemento a elemento y por cada uno de ellos crear otro nuevo en una lista distinta es una tarea frecuente, Python tiene una sintaxis compacta para hacer esto, llamada list comprehension. La sintaxis general es:
new_list = [E(e) for e in list]

donde

E(e)

representa una expresin que envuelve al elemento e. A continuacin ponemos varios ejemplos:

Cdegrees = [-5 + i*0.5 for i in range(n)] Fdegrees = [(9.0/5)*C + 32 for C in Cdegrees]

La tabla anterior puede construirse con un ciclo


table = [] for C, F in zip(Cdegrees, Fdegrees): table.append([C, F])

for:

Una versin ms pythonica del ciclo anterior se consigue utilizando una list comprehension:

14

Captulo 1. Programacin bsica

Programacion con Python, Release 0.4

table = [[C, F] for C, F in zip(Cdegrees, Fdegrees)]

Ejemplo 2 Las sumatorias ocurren con frecuencia en las matemticas. Por ejemplo, la funcin sin(x) puede calcularse como un polinomio: sin(x) x x3 x5 x7 + + 3! 5! 7! (1.8)

donde 3! = 3 2 1, 5! = 5 4 3 2 1, etc. son factoriales. La expresin k ! puede calcularse con math.factorial(k). Se requiere de un nmero innito de trminos en el lado derecho de (1.8) para que sea vlido usar el signo de igualdad. Con un nmero nito de trminos, se obtiene una aproximacin de la funcin sin(x). Suponga que es necesario calcular el lado derecho de (1.8) para potencias de hasta suma anterior con un ciclo while de Python, utiliza lo siguiente: 1. Un contador
k N = 25.

El clculo de la

que toma los valores impares desde 1 hasta un algn nmero mximo N.
sumatoria,

2. Una variable para la sumatoria, digamos

que acumule los trminos, uno a la vez.

El propsito de cada iteracin del ciclo es calcular un nuevo trmino y aadirlo a sumatoria. Dado que el signo de cada trmino se alterna, podemos introducir una variable signo que cambie entre 1 y 1 en cada iteracin del ciclo. Las ideas anteriores pueden codicarse en Python de la siguiente manera:
x = 1.2 # asignar algn valor N = 25 # maxima potencia en la suma k = 1 sumatoria = x signo = 1.0 import math while k < N: signo = - signo k = k + 2 term = signo * x**k / math.factorial(k) sumatoria = sumatoria + term print("sin({0:g}) = {1:g} (aproximacin con N = {2:d})".format(x, sumatoria, N)) print("Valor real = {0:g}".format(math.sin(x)))

Ejemplo 3: Series de Fourier Sea f (t) una funcin denida en un intervalo (a, a + T ), donde a R y T > 0 es el periodo de la funcin. f (t) puede escribirse como ( ) ( )] [ a0 2nt 2nt f (t) = + an cos + bn sin 2 T T n=1

1.5. Estructuras de control

15

Programacion con Python, Release 0.4

Para encontrar los coecientes a0 , an y bn , se utilizan las siguientes frmulas: a0 = an = 2 T 2 T


a a+T a+T

f (t) dt ( f (t) cos


a a+T

2 bn = T

( f (t) sin

2nt T 2nt T

) dt ) dt

El uso ms frecuente de la serie de Fourier es para representar funciones peridicas. Lo que se hace es denir la funcin para un intervalo (a, a + T ) con una serie de Fourier. El resultado es una funcin denida en todo el eje real. a0 siempre da el valor promedio de la funcin. El valor que da la serie geomtrica de Fourier para El valor 2 los valores en que la funcin presenta discontinuidades es el valor promedio de la funcin. Un desarrollo en serie de Fourier para f (t) denida de acuerdo con la gura
import matplotlib.pyplot as plt import numpy as np x1 = np.array([0.0, 1.0]) y1 = np.array([2.0, 2.0]) x2 = np.array([1.0, 2.0]) y2 = np.array([-1.0, -1.0]) plt.plot(x1, y1, 'b', x2, y2, 'b') plt.axis([0.0, 2.0, -2.0, 3.0]) plt.grid() plt.show()

16

Captulo 1. Programacin bsica

Programacion con Python, Release 0.4

3 2 1 0 1 2 0.0

0.5

1.0

1.5

2.0

est dado por las siguientes expresiones: a0 = 1 an = 0 3 n bn = [1 (1) ] n T =2 es decir, la solucin es: f (t) = 1 3 n + [1 (1) ] sin(nt) 2 n=1 n

6 1 sin [(2n 1)t] = + 2 n=1 (2n 1) =


1 6 sin [(2n 1)t] + 2 n=1 2n 1

La grca siguiente se obtiene utilizando los primeros 3 trminos de la sumatoria de la ltima expresin para f (t):
import matplotlib.pyplot as plt import numpy as np from numpy import pi

1.5. Estructuras de control

17

Programacion con Python, Release 0.4

num_puntos = 301 t = np.linspace(-2.0, 4.0, num_puntos) f = np.zeros((3, num_puntos)) for n in range(3): impar = 2*n + 1 theta = impar*pi*t f[n] = np.sin(theta)/impar plt.plot(t, f[n]) y = 0.5 + 6.0/pi*f.sum(0) plt.plot(t, y) plt.grid() plt.show()

2.5 2.0 1.5 1.0 0.5 0.0 0.5 1.0 1.5 2 1 0 1 2 3 4

Modique el programa anterior para visualizar la seal peridica que se obtiene al sumar los primeros diez trminos de la serie. Despus visualize la seal correspondiente a 100 trminos. Ejercicios 1. Escriba un programa que genere todos los nmeros impares desde 1 hasta n. Fije un valor para n al inicio del programa y use un ciclo while para calcular los nmeros. Asegrese de que si n es un nmero par, el nmero impar ms grande generado es n - 1. Nombre del programa: impar.py 2. Modique el programa del ejercicio 1 y almacene los nmeros impares generados en una lista. Empiece con una lista vaca y use un ciclo while donde en cada iteracin del ciclo agregue un nuevo elemento a la 18 Captulo 1. Programacin bsica

Programacion con Python, Release 0.4

lista. Finalmente, imprima la lista de elementos en la pantalla. Nombre del programa: lista_impares1.py 3. Resuelva el ejercicio 2 utilizando una list comprehension (con lista_impares2.py
for

range).

Nombre del programa:


M 1 : k

4. (Calculo de una sumatoria) Se supone que el siguiente cdigo calcule la suma s =


s = 0 k = 1 M = 100 while k < M: s += 1/k print(s)

k=1

Este programa no funciona correctamente. Cules son los tres errores? Si usted intenta ejecutar el programa, nada suceder en la pantalla. Teclee Ctrl-C, es decir, presione (y deje presionada) la tecla Control (Ctrl) y entonces teclee la letra c, para detener el programa. Escriba un programa correcto. Nombre del programa: suma_while.py. Hay dos formas bsicas de encontrar errores en el programa: (a) Lea el programa cuidadosamente y piense en las consecuencias de cada instruccin (b) Imprima resultados intermedios y compare con los clculos manuales Primero, intente el mtodo (a) y encuentre tantos errores como pueda. Entonces, intente el mtodo (b) para M = 3 y compare la evolucin de s con sus propios clculos manuales. Nota: Una forma pythonica de resolver este problema es mediante:
print(sum(1.0/k for k in xrange(1, M+1, 1)))

5. El siguiente programa graca la funcin trigonomtrica sin(x)


import matplotlib.pyplot as plt import numpy as np from numpy import pi x = np.linspace(-2*pi, 2*pi, 101) y = np.sin(x) plt.plot(x, y) plt.grid() plt.show()

1.5. Estructuras de control

19

Programacion con Python, Release 0.4

1.0

0.5

0.0

0.5

1.0 8

Suponga que desea calcular la funcin seno inversa: arcsin(x). El mdulo numpy tiene una funcin para calcular dicha funcin, pero cul es el nombre de esta funcin? Graque esta funcin en el dominio adecuado. 6. Sea:
q = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h']]

Indexe esta lista para extraer (a) La letra (b) La lista


a ['d', 'e', 'f'] h

(c) El ltimo elemento (d) El elemento


d

(e) Explique por qu Nombre del programa:

q[-1][-2]

tiene el valor g.

index_nested_list.py

7. Construya un doble loop sobre una lista anidada. Considere la lista del ejercicio 6. Es posible visitar todos los elementos de q usando el siguiente for loop anidado:
for i in q: for j in range(len(i)): print i[j]

Cul es el tipo de las variables

y j?

20

Captulo 1. Programacin bsica

Programacion con Python, Release 0.4

8. Reescriba la generacin de la lista anidada q:


q = [r**2 for r in [10**i for i in range(5)]]

utilizando ciclos estndar

for

en lugar de list comprehensions.


matplotlib

9. Graque la siguiente funcin utilizando

0 x N (x) = 2x 0

si si si si

x<0 0x<1 1x<2 x2

10. Un desarrollo en serie de Fourier para la funcin dada por: 0, si 0 < t < 2 t 2 , si 2 < t < f (t) = 3 3 t, si < t < 2 2 3 0, si < t < 2 2 donde el periodo es T = 2 , est dado por: a0 = an = 4

( n )] 2 [ n ( 1) cos n2 2 bn = 0

es decir, la solucin es:


( n )] 2 [ n f (t) = + ( 1) cos cos(nt) 8 n=1 n2 2

( n )] 2 1 [ n + ( 1) cos cos(nt) 8 n=1 n2 2

Graque la serie anterior con 100 trminos.

1.5. Estructuras de control

21

Programacion con Python, Release 0.4

22

Captulo 1. Programacin bsica

CAPTULO

Grcas

2.1 Grcas simples


La visualizacin de una curva f (x) se realiza al gracar lineas rectas entre n puntos en la curva. Entre ms 2 puntos se usen, ms suave es la forma de la grca. Com ejemplo, vamos a gracar la curva y = t2 et para valores de t entre 0 y 3. Primero generamos coordenadas igualmente espaciadas para t, para este ejemplo, 51 valores (50 intervalos). Entonces calculamos los correspondientes valores para y en estos puntos, antes de invocar el comando plot(t, y) para obtener la grca. A continuacin mostramos el programa:
from matplotlib.pylab import * def f(t): return t**2*exp(-t**2) t = linspace(0, 3, 51) # 51 puntos entre 0 y 3 y = zeros(len(t)) # reservar espacio de memoria para y con elementos flotantes. # Se puede hacer utilizando ciclos, pero es mas lento # for i in xrange(len(t)): # y[i] = f(t[i])

# Se obtiene una ejecucion mas rapida (y la sintaxis tambien es mas simple) # actuando sobre todo el arreglo t y = f(t) plot(t, y) xlabel("t") ylabel("y") legend(["t^2*exp(t^2)"]) show()

23

Programacion con Python, Release 0.4

0.40 0.35 0.30 0.25 0.20 0.15 0.10 0.05 0.00 0.0 0.5 1.0 1.5 t 2.0 y

t^2*exp(t^2)

2.5

3.0

Descarga el manual de matplotlib de http://matplotlib.org/contents.html (o use directamente el link http://matplotlib.org/Matplotlib.pdf) y estudia el tutorial de pyplot. 1. Graca la funcin f (x) = x3 en color rojo, con lneas punteadas, en el intervalo de 5 a 5. 2. Modica el grueso de la lnea de la grca anterior a 2.0. 3. Graca las funciones seno y coseno en el rango de [, ] utilizando el comando subplot()

2.1.1 La funcin exponencial


En 1840 P.F. Verhulst, matemtico y bilogo belga, propuso un modelo para predecir el crecimiento de poblaciones humanas. La llamada funcin logstica P (t) = K , 1 + cert r<0 (2.1)

donde k , c y r son constantes, ha demostrado ser un modelo exacto de crecimiento para poblaciones de protozoarios, bacterias, moscas de fruta o animales connados a espacios limitados. Este modelo muestra un crecimiento acotado. Ms especcamente, la problacin predicha por (2.1) no aumentar ms all del nmero K , llamado capacidad lmite o de soporte del sistema. Para r < 0, ert 0 y P (t) 0 cuando t .

24

Captulo 2. Grcas

Programacion con Python, Release 0.4

2.1.2 Prctica 5
Un alumno enfermo de un virus de catarro regresa a un colegio aislado, de 2 000 estudiantes. La cantidad de estudiantes infectados con catarro, t das despus del regreso del alumno enfermo, se calcula con la funcin logstica P (t) = 2000 1 + 1999e0.8905t

1. De acuerdo con este modelo, cuntos estudiantes sern infectados por el catarro despus de 5 das? Para responder a esta pregunta, basta con calcular P (5) = 82.348 (en realidad son 83 estudiantes). Esto clculo puede hacerse con una calculadora, o con el siguiente cdigo:
import numpy as np def p(t): return 2000.0/(1.0 + 1999.0*np.exp(-0.8905*t)) print(p(5))

2. Cunto tiempo pasar para que la mitad de la poblacin de estudiantes quede infectada? Para responder a esta pregunta de manera exacta, se puede despejar t de la ecuacin: 1000 = 2000 1 + 1999e0.88905t

cuya solucin es t = ln(1999)/0.8905 8.535 das. Esto puede responderse de manera aproximada utilizando una grca. 3. Cuntos alumnos indica el modelo que se infectarn despus de un tiempo muy prolongado? El modelo indica que se infectarn todos los estudiantes. 4. Trace una grca de P (t).
import matplotlib.pyplot as plt import numpy as np t = np.linspace(0.0, 20.0, 2001) p = 2000.0/(1.0 + 1999.0*np.exp(-0.8905*t)) plt.plot(t, p) plt.grid() fig = plt.gcf() size = fig.get_size_inches() scale = 0.6 fig.set_size_inches( (size[0]*scale, size[1]*scale) ) plt.show()

2.1. Grcas simples

25

Programacion con Python, Release 0.4

2000 1500 1000 500 00 5 10 15 20

Ahora veremos la misma grca con una escala logartmica en el eje vertical:
import matplotlib.pyplot as plt import numpy as np t = np.linspace(0.0, 20.0, 2001) p = 2000.0/(1.0 + 1999.0*np.exp(-0.8905*t)) plt.semilogy(t, p) plt.grid() fig = plt.gcf() size = fig.get_size_inches() scale = 0.6 fig.set_size_inches( (size[0]*scale, size[1]*scale) ) plt.show()

26

Captulo 2. Grcas

Programacion con Python, Release 0.4

104 103 102 101 100 0 5 10 15 20

2.2 Grcas de contorno


Utilizando el cdigo siguiente, trate de reproducir la gura siguiente
import numpy as np import matplotlib.pylab as pl def f(x, y): return (1 - x/2 + x**5 + y**3) * np.exp(-x**2 - y**2) n = 256 x = np.linspace(-3, 3, n) y = np.linspace(-3, 3, n) X, Y = np.meshgrid(x, y) pl.contourf(X, Y, f(X, Y), 8, alpha=0.75, cmap='jet') C = pl.contour(X, Y, f(X, Y), 8, colors='black', linewidth=0.5) pl.show()

2.2. Grcas de contorno

27

Programacion con Python, Release 0.4

3 2 1 0 1 2 33 2 1 0 1 2 3

2.3 Grcas en 3D
2.3.1 Prctica 6
(surface3ddemo.py)
from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm from matplotlib.ticker import LinearLocator, FormatStrFormatter import matplotlib.pyplot as plt import numpy as np fig = plt.figure() ax = fig.gca(projection='3d') X = np.arange(-5, 5, 0.25) Y = np.arange(-5, 5, 0.25) X, Y = np.meshgrid(X, Y) R = np.sqrt(X**2 + Y**2) Z = np.sin(R) surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False) ax.set_zlim(-1.01, 1.01) ax.zaxis.set_major_locator(LinearLocator(10))

28

Captulo 2. Grcas

Programacion con Python, Release 0.4

ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f')) fig.colorbar(surf, shrink=0.5, aspect=5) plt.show()

6 4

2 0

6 6

1.01 0.79 0.56 0.34 0.11 -0.11 -0.34 -0.56 -0.79 -1.01 6

0.8 0.6 0.4 0.2 0.0 0.2 0.4 0.6 0.8

2.4 Ejercicios
1. Conduccin electroltica en las rocas (Ley de Archie). La resistividad elctrica de un cilndro slido de longitud L y seccin transversal A, con resistencia R entre sus dos caras, est dado por: =R A L

Debido a que la mayora de las rocas son pobres conductores, sus resistidades seran muy grandes si no fuera por el hecho de que son usualmente porosas y que los poros estn llenos con uidos, principalmente agua. Como resultado, las rocas son conductores electrolticos, cuya resistividad efectiva puede denirse por la frmula anterior, donde la propagacin de la corriente se da mediante conduccin inica (por molculas que tienen un exceso o deciencia de electrones). Por lo tanto la resistividad vara con la movilidad, concentracin y grado de disociacin de los iones (esta ltima depende de la constante dielctrica del solvente). El ujo de corriente no solamente es lento comparado con la conduccin ohmica, sino que implica un transporte real de material, normalmente resultando en transformacin qumica. 2.4. Ejercicios 29

Programacion con Python, Release 0.4

La conductividad de una roca porosa vara con el volumen y el arreglo de los poros y ms an con la conductividad y la cantidad de agua contenida. De acuerdo con la frmula emprica obtenida por Archie (1942): e = am S n W

donde es la fraccin de volumen poroso (porosidad), S es la fraccin de los poros que contienen agua, W es la resistividad del agua, n 2 y a, m son constantes, 0.5 a 2.5, 1.3 a 2.5. Suponga que S = 1, a = 1.5 y m = 2, entonces 1.5 e = 2 W

Utilice una grca con escalas logartmicas para gracar la frmula anterior para valores de = 0.01, 0.1, 0.3, 0.5. 2. Vida media del plutonio. Un reactor de cra convierte uranio 238 relativamente estable en el istopo plutonio 239. Despus de 15 aos, se ha determinado que 0.043% de la cantidad inicial de A0 de plutonio se ha desintegrado. (a) Determine la vida media de ese istopo, si la razn de desintegracin es proporcional a la cantidad que queda. (b) Graque A(t) si A0 = 1.0 kg. Verique grcamente la respuesta del inciso anterior.

2.5 Grcas de algunos campos simples


Revisemos varias representaciones del campo vectorial = cos(x) A + sin(y )

La siguiente gura utiliza echas para indicar la direccin del campo. El color indica la magnitud del campo.
from pylab import * from numpy import ma X,Y = meshgrid( arange(0,2*pi,.2),arange(0,2*pi,.2) ) U = cos(X) V = sin(Y) figure() M = sqrt(pow(U, 2) + pow(V, 2)) Q = quiver( X, Y, U, V, M) qk = quiverkey(Q, 0.5, 0.92, 2, r'$2 \frac{m}{s}$', labelpos='W', \ fontproperties={'weight': 'bold'}) l, r, b, t = axis() dx, dy = r - l, t - b axis([l - 0.05*dx, r + 0.05*dx, b - 0.05*dy, t + 0.05*dy]) colorbar() show()

30

Captulo 2. Grcas

Programacion con Python, Release 0.4

7 6 5 4 3 2 1 0 0 1 2

2m s

1.35 1.20 1.05 0.90 0.75 0.60 0.45 0.30 0.15

Ahora se utilizan lneas de fuerza para indicar la direccin de campo. El color est asociado a la magnitud del campo.
import numpy as np from numpy import pi import matplotlib.pyplot as plt Y, X = np.mgrid[0:2*pi:100j, 0:2*pi:100j] U = np.cos(X) V = np.sin(Y) M = np.sqrt(U*U + V*V) plt.streamplot(X, Y, U, V, color=M, linewidth=2, cmap=plt.cm.autumn) plt.colorbar() plt.show()

2.5. Grcas de algunos campos simples

31

Programacion con Python, Release 0.4

6 5 4 3 2 1 00 1 2 3 4 5 6

1.35 1.20 1.05 0.90 0.75 0.60 0.45 0.30 0.15

2.5.1 Ejercicio
Representa el campo vectorial siguiente de las dos maneras ejemplicadas anteriormente. ( ) ( ) = sin y A sin x 2 2

32

Captulo 2. Grcas

CAPTULO

lgebra lineal

3.1 Arreglos de NumPy


Numpy es el paquete fundamental para cmputo cientco en Python. Se trata de una librera para Python que proporciona un arreglo multidimensional, varios objetos derivados (tales como arreglos enmascarados y matrices), y varias rutinas para operaciones rpidas sobre arreglos, incluyendo manipulacin matemtica, lgica y de la forma de los arreglos; ordenamiento, seleccin, I/O, transformadas discretas de Fourier, lgebra lineal bsica, operaciones estadsticas bsicas, simulacin aleatoria y mucho ms. Para ilustrar la importancia de los arreglos de NumPy, considere el siguiente problema: multiplicar cada elemento de una secuencia unidimensional con el correspondiente elemento de otra secuencia de la misma longitud. Si los datos estn almacenados en dos listas de Python, a y b, podramos iterar sobre cada elemento, de la siguiente manera:
c = [] for i in range(len(a)): c.append(a[i]*b[i])

Esto produce el resultado correcto, pero si a y b contienen cada uno un milln de nmeros, pagaremos el precio por las ineciencias de los ciclos en Python. Podramos conseguir la misma tarea mucho ms rpido en C al escribir (por simplicidad no escribimos las declaraciones de variables, inicializaciones, la reservacin del espacio de memoria, etc.).
for (i = 0; i < numero_elementos; i++) { c[i] = a[i]*b[i]; }

Utilizando arreglos de Numpy a y b, podemos realizar la misma operacin con:


c = a * b

casi a la misma velocidad que con C, pero con la simplicidad en la programacin que se espera de cdigo escrito en Python.

3.1.1 Un ejemplo ms realista en C


El siguiente ejemplo muestra el producto punto de dos vectores en C (se est utilizando el framework Accelerate, especco para Mac OS X, que incluye una librera para BLAS, es decir Basic Linear Algebra)

33

Programacion con Python, Release 0.4

#include <stdio.h> #include <stdlib.h> #include <Accelerate/Accelerate.h> void runSDOTSample (void) { float *X, *Y; int N, i; float resultFloat; // Initialize the inputs and allocate space N = 10; X = ( float* ) malloc ( sizeof ( float ) * N ); Y = ( float* ) malloc ( sizeof ( float ) * N ); for ( i = 0; i < N; i++ ) { X[i] = 1.0; Y[i] = 2.0; } resultFloat = cblas_sdot ( N, X, 1, Y, 1 ); printf("the result of cblas_sdot is %4.4f\n", resultFloat); //deallocate space free ( X ); free ( Y ); } int main(int argc, const char * argv[]) { runSDOTSample(); return 0; }

3.1.2 Prctica 4
Imagine que desea sumar dos vectores llamados a y b. El vector a contiene los cuadrados de los enteros 0 hasta n (excluyendo n); por ejemplo, si n = 3, entonces a = (0, 1, 4). El vector b contiene los cubos de los enteros 0 hasta n (excluyendo n); por ejemplo, si n = 3, entonces b = (0, 1, 8). Cmo hara eso con Python nicamente? Sumando vectores utilizando Python puro La siguiente funcin resuelve el problema de la suma de vectores utilizando Python sin NumPy:
def pythonsum(n): a = range(n) b = range(n) c = [] for i in range(len(a)): a[i] = i ** 2 b[i] = i ** 3 c.append(a[i] + b[i]) return c

Sumando vectores utilizando NumPy La siguiente funcin resuelve el mismo problema con NumPy:

34

Captulo 3. lgebra lineal

Programacion con Python, Release 0.4

def numpysum(n): a = numpy.arange(n) ** 2 b = numpy.arange(n) ** 3 c = a + b return c

Comparando los tiempos de ejecucin Con ayuda del siguiente cdigo, compare los tiempos de ejecucin para n = 1000, 2000, 3000. Ejecute su programa desde la lnea de comandos.
import sys from datetime import datetime import numpy def numpysum(n): a = numpy.arange(n) ** 2 b = numpy.arange(n) ** 3 c = a + b return c def pythonsum(n): a = range(n) b = range(n) c = [] for i in range(len(a)): a[i] = i ** 2 b[i] = i ** 3 c.append(a[i] + b[i]) return c size = int(sys.argv[1]) start = datetime.now() c = pythonsum(size) delta = datetime.now() - start print("The last 2 elements of the sum {}".format(c[-2:])) print("PythonSum elapsed time in microseconds {}".format(delta.microseconds)) start = datetime.now() c = numpysum(size) delta = datetime.now() - start print("The last 2 elements of the sum {}".format(c[-2:])) print("NumPySum elapsed time in microseconds {}".format(delta.microseconds))

Este programa funciona adecuadamente con Python de 64 bits. La tabla siguiente muestra los tiempos de ejecucin (en microsegundos) obtenidos en mi mquina para algunos valores de size (la segunda columna corresponde a la funcin que utiliza listas y la tercera, a la funcin que utiliza arreglos de NumPy): size 10 100 1000 10000 Tiempo (pythonsum) 20 66 622 5468 Tiempo (numpysum) 50 52 78 369

3.1. Arreglos de NumPy

35

Programacion con Python, Release 0.4

3.1.3 Arreglos multidimensionales


Los arreglos de NumPy son homogneos, es decir, los elementos del arreglo tienen que ser del mismo tipo. La ventaja es que ahora es fcil determinar el tamao que se requiere para almacenar el arreglo. Los arreglos de NumPy se indexan como en Python, a partir de 0. Utilizando el siguiente cdigo, averige cul es el tipo de los elementos del arreglo a (las respuestas son diferentes dependiendo de si utiliza Python de 32 bits o de 64 bits):
>>> a = arange(5) >>> a.dtype

Adems del tipo de los elementos del arreglo, tambin es importante conocer su forma:
>>> a >>> array([0, 1, 2, 3, 4]) >>> a.shape >>> (5,)

El atributo shape (forma) del arreglo es una tupla, en este caso, una tupla de 1 elemento, que contiene el tamao del arreglo en cada dimensin. Creando un arreglo multidimensional Muestre la forma y el tipo de los elementos del arreglos siguientes:
>>> m1 = array([arange(2), arange(2)]) >>> m2 = array([ [1, 2], [3, 4] ])

Ahora cree una matriz de tamao 3 3 con los siguientes elementos 0 1 2 3 4 5 6 7 8 Compruebe que tambin puede crearlo de la siguiente manera:
>>> m3 = arange(9).reshape(3, 3)

Los elementos de m3 pueden accederse mediante la siguiente sintxis:


>>> m3[0, 0]

Cul es la salida de

m3[2, 1]?

3.2 lgebra Lineal bsica con NumPy


El paquete numpy.linalg contiene funciones de lgebra lineal. Con este mdulo, usted puede invertir matrices, calcular eigenvalores, resolver sistemas de ecuaciones lineales, calcular determinantes, entre otras cosas.

36

Captulo 3. lgebra lineal

Programacion con Python, Release 0.4

3.2.1 La inversa de una matriz


La inversa de una matriz cuadrada A de n n se denota por A1 , que cuando se multiplica por la matriz original, es igual a la matriz identidad. Esto puede escribirse como se indica a continuacin: AA1 = In A1 A = In

La funcin inv del paquete numpy.linalg puede invertir una matriz por nosotros. Vamos a resolver un ejemplo: 1. Crea la matriz A con la funcin
mat:

>>> A = numpy.mat("0 1 2; 1 0 3; 4 -3 8")

2. Invierte la matriz A con la funcin


>>> A_inv = numpy.linalg.inv(A)

inv:

Si la matriz es singular, o no es cuadrada, resulta un error 3. Verica utilizando multiplicacin matricial:


>>> print("Verifica\n {}".format(A * A_inv))

LinAlgError.

3.2.2 Resolviendo un sistema de ecuaciones lineales


La funcin solve de numpy.linalg resuelve sistemas de ecuaciones de la forma Ax = b, donde A es una matriz, b puede ser un arreglo unidimensional o bidimensional, y x es la variable desconocida. 1. Crea la matriz A y el vector b:
>>> A = numpy.mat("1 -2 1; 0 2 -8; -4 5 9") >>> print("A\n {}".format(A)) >>> b = numpy.array([0, -8, 9]) >>> print("b\n {}".format(b))

2. Invoque la funcin

solve

para resolver el sistema de ecuaciones lineales:

>>> x = numpy.linalg.solve(A, b) >>> print("Solucion: {}".format(x))

3. Verique que la solucin es correcta (dot realiza una multiplicacin matricial):


>>> print("Verifica\n {}".format( numpy.dot(A, x) ))

3.3 Ejercicios
Instrucciones: Utilice Numpy para resolver los siguientes ejercicios. 3.2 1.5 1. Resuelva las operaciones indicadas, suponiendo que u = 0.6, v = 4.1 1.4 0.2 (a) u v (b) u (c) 3 v u 3.3. Ejercicios 37

Programacion con Python, Release 0.4

(d) u v 2. Encuentre la solucin del sistema de ecuaciones lineales dado por las matrices aumentadas 0 2 3 8 1 5 (a) 2 3 1 1 2 5 1 1 1 1 4 1 2 3 4 10 (b) 1 3 6 10 20 1 4 10 20 35 3. Utilice la funcin numpy.linalg.eig para encontrar los eigenvalores y eigenvectores de la matriz cua 1 0 2 drada A = 3 1 3 2 0 1

38

Captulo 3. lgebra lineal

CAPTULO

Polinomios e interpolacin

4.1 Introduccin a la Interpolacin


La interpolacin se usa para estimar valores intermedios entre datos precisos. El mtodo ms comn que se usa para este propsito es la interpolacin polinomial. Para n + 1 puntos, hay uno y slo un polinomio de orden n que pasa a travs de todos los puntos. Por ejemplo, hay slo una lnea recta (un polinomio de primer orden) que conecta dos puntos. De manera similar nicamente una parbola conecta un conjunto de tres puntos. La interpolacin polinomial consiste en determinar el nico polinomio de nsimo orden que ajuste n + 1 puntos. Este polinomio entonces proporciona una frmula para calcular valores intermedios.

4.1.1 Interpolacin de polinomios de Lagrange con SciPy 4.1.2 Ejemplo


Estime log10 5 mediante interpolacin lineal. Interpole entre log 4 = 0.60206 y log 6 = 0.7781513:
import numpy as np from scipy.interpolate import lagrange x = np.array([4.0, 6.0]) y = np.array([0.60206, 0.7781513]) p = lagrange(x, y) print(p) print(p(4.0)) print(p(6.0)) print(p(5.0))

Interpole entre log 4.5 = 0.6532125 y log 5.5 = 0.7403627. Ajuste con un polinomio de interpolacin de Lagrange de tercer orden para estimar log 5 utilizando los datos anteriores.

39

Programacion con Python, Release 0.4

4.1.3 El fenmeno de Runge


Ejemplo Consideremos el polinomio interpolador de Lagrange de la funcin f (x) = 1/(1 + 12x2 ) en el intervalo [1, 1] para nodos equiespaciados, tiende a cero el error EN (x) = F (x) PN (x) cuando N crece? No: el mximo del trmino del error EN (x) crece cuando N . Esta falta de convergencia se conoce como fenmeno de Runge
import numpy as np import matplotlib.pyplot as plt from scipy.interpolate import lagrange def f(x): return 1.0/(1.0 + 12.0 * x**2) x = np.linspace(-1.0, 1.0, 200) plt.plot(x, f(x), '--') x2 = np.linspace(-1.0, 1.0, 11) p = lagrange(x2, f(x2)) y2 = p(x2) plt.plot(x2, y2, 'o') plt.plot(x, p(x), linewidth=2.0) plt.grid() plt.show()

Una mejor solucin utilizando polinomios de Chebyshev


import numpy as np import matplotlib.pyplot as plt from numpy.polynomial import Chebyshev as T def f(x): return 1.0/(1.0 + 12.0 * x**2) N = 11 x = np.cos([(2*k + 1)*np.pi/2.0/N for k in range(N)]) y = f(x) p = T.fit(x, y, 10) xx, yy = p.linspace() plt.plot(xx, f(xx), '--') plt.plot(x, y, 'o') plt.plot(xx, yy, lw=2) plt.grid() plt.show()

40

Captulo 4. Polinomios e interpolacin

Programacion con Python, Release 0.4

1.0 0.8 0.6 0.4 0.2 0.01.0

0.5

0.0

0.5

1.0

4.2 Interpolacin segmentaria (splines)

4.2. Interpolacin segmentaria (splines)

41

Programacion con Python, Release 0.4

42

Captulo 4. Polinomios e interpolacin

CAPTULO

Ajuste de funciones

Veremos ajuste por mnimos cuadrados.

5.1 Regresin por mnimos cuadrados


5.1.1 Regresin lineal
Es el ajuste de un conjunto de pares de observaciones: (x1 , y1 ), (x2 , y2 ), ldots, (xn , yn ) a una lnea recta. La expresin matemtica para esta ltima es: y = a0 + a1 x + e

donde a0 y a1 son coecientes que representan el intercepto y la pendiente, respectivamente, y e es el error, o residuo, entre el modelo y las observaciones, el cual se puede representar al reordenar la expresin anterior como: e = y a0 a1 x (5.1)

As, el error o residuo es la discrepancia entre el valor real de y y el valor aproximado, a0 + a1 x, predicho por la ecuacin lineal. En la regresin lineal por mnimos cuadrados, la estrategia es (como su nombre lo indica), minimizar la suma de los cuadrados de los residuos entre la y medida y la y calculada con el modelo lineal: Sr =
n i=1

e2 i =

n i=1

(yi a0 a1 xi )

(5.2)

donde n es el nmero de pares de observaciones. Ecuaciones normales (regresin lineal) Para determinar los valores de a0 y a1 que minimizan la Ec. (5.2), esta ltima es diferenciada parcialmente con respecto a cada coeciente e igualando cada expresin resultante a cero. Como resultado se tienen las

43

Programacion con Python, Release 0.4

ecuaciones normales:

( ) na0 + x i a1 = yi ( ) ( ) xi a0 + x2 xi yi i a1 =

(5.3) (5.4)

que pueden resolverse en forma simultnea.

5.1.2 Ejemplo 1: Lo bsico


Ajustemos una lnea recta y = mx + b, a travs de unos puntos con un poco de ruido:
import numpy as np x = np.array([ 0, 1, 2, 3]) y = np.array([-1, 0.2, 0.9, 2.1]) # Es posible escribir la ecuacin lineal como y = Ap, donde # A = [[x 1]] A = np.vstack([x, np.ones(len(x))]).T print(A) # y # p = [[m], [b]] # Use np.linalg.lstsq para calcular p: m, b = np.linalg.lstsq(A, y)[0] print(m, b) # Comprueba que # m = 1.0 y b = -0.95

Ahora vamos a gracar los datos junto con la lnea ajustada:


import matplotlib.pyplot as plt import numpy as np x = np.array([ 0, 1, 2, 3]) y = np.array([-1, 0.2, 0.9, 2.1]) m, b = 1.0, -0.95 plt.plot(x, y, 'o', label='Datos originales', markersize=10) plt.plot(x, m*x + b, 'r', label='Datos ajustados') plt.legend(loc='best') plt.show()

44

Captulo 5. Ajuste de funciones

Programacion con Python, Release 0.4

2.5 2.0 1.5 1.0 0.5 0.0 0.5 1.0 0.0

Datos originales Datos ajustados

0.5

1.0

1.5

2.0

2.5

3.0

Resuelva el ejercicio manualmente y compruebe sus resultados.

5.1.3 Forma general lineal por mnimos cuadrados


La regresin lineal, polinomial y lineal mltiple pertenecen al siguiente modelo general de mnimos cuadrados lineales: y = a0 z0 + a1 z1 + a2 z2 + + am zm + e (5.5)

donde z0 , z1 , . . ., zm son las m + 1 funciones diferentes. La regresin lineal simple y mltiple encajan dentro de este modelo: z0 = 1, z1 = x1 , . . ., zm = xm . Adems la regresin de polinomios se incluye tambin si las z son monomios simples como en z0 = x0 = 1, z1 = x, . . ., zm = xm . Observe que la terminologa lineal se reere slo a la dependencia del modelo sobre sus parmetros (es decir, las a). Como en el caso de regresin de polinomios, las mismas funciones pueden ser altamente no lineales. La ecuacin (5.5) puede se puede expresar en notacin matricial como: Y = ZA + E (5.6)

donde Z es una matriz d los valores calculados de las funciones z en los valores medidos de las variables

5.1. Regresin por mnimos cuadrados

45

Programacion con Python, Release 0.4

independientes z01 z02 Z= . . . z0n z11 z12 . . . z1n .. . zm1 zm2 . . . zmn

donde m es el nmero de variables del modelo y n es el nmero de datos. Como n m + 1, la mayora de las veces Z no es una matriz cuadrada. El vector columna Y contiene los valores observados de la variable dependiente: y1 y2 Y = . . . yn

El vector columna A contiene los coecientes desconocidos a0 a1 A= . . . am

y el vector columna E contiene los residuos e1 e2 E= . . . an

La suma de los cuadrados de los residuos para este modelo se puede denir como
n i=1

Sr =

e2 i =

n i=1

yi

m j =0

2 aj zji

Esta cantidad se puede minimizar al tomar su derivada parcial con respecto a cada uno de los coecientes y jar los resultados de la ecuacin igual a cero. La salida de este proceso son las ecuaciones normales que se pueden expresar brevemente en forma de matriz como Z T ZA = Z T Y Ejemplo 2: Regresin polinomial (de segundo orden) Ajustar a una parbola los datos siguientes: (5.7)

46

Captulo 5. Ajuste de funciones

Programacion con Python, Release 0.4

xi 0 1 2 3 4 5

yi 2.1 7.7 13.6 27.2 40.9 61.1 1 1 Z = . . . x2 1 x2 2 . . . x2 n xm 1 xm 2 . . . xm n

La matriz Z debe tomar la forma x1 x2 . . .

(5.8)

1 xn que es un caso particular de la matriz de Vandermonde 1 x1 x2 1 1 x2 x2 2 Z = . . . . . . . . . 1 xn x2 n

Podemos denir una funcin en python que calcule la matriz de Vandermonde de la siguiente manera:
import numpy as np def vandermonde(x, N): return np.column_stack([x**(i) for i in range(N + 1)])

Compruebe que llamar esta funcin con


[[ 1 [ 1 [ 1 [ 1 [ 1 [ 1 0 1 2 3 0] 1] 4] 9]

x = np.arange(6)

N = 2

genera el siguiente arreglo de numpy:

4 16] 5 25]]

Por lo tanto, el problema planteado puede resolverse planteando las ecuaciones normales (5.7):
import numpy as np def vandermonde(x, N): return np.column_stack([x**(i) for i in range(N + 1)]) Z = vandermonde(np.arange(6), 2) Y = np.array([2.1, 7.7, 13.6, 27.2, 40.9, 61.1]) A = np.linalg.solve( np.dot(Z.T, Z), np.dot(Z.T,Y) ) print(A)

Utilizando

numpy.vander

numpy.linalg.lstsq,

el problema puede resolverse de la siguiente manera:

import numpy as np Z = np.vander(np.arange(6), 3) Y = np.array([2.1, 7.7, 13.6, 27.2, 40.9, 61.1]) A = np.linalg.lstsq(Z, Y)[0] print(A)

5.1. Regresin por mnimos cuadrados

47

Programacion con Python, Release 0.4

Interprete los resultados anteriores y graque los datos junto con el resultado obtenido de la regresin polinomial

48

Captulo 5. Ajuste de funciones

CAPTULO

Races de ecuaciones no lineales

6.1 Introduccin: Races de ecuaciones no lineales


6.1.1 Mtodo grco
Aunque el mtodo grco no es el ms exacto para hallar las races de las ecuaciones no lineales, resulta de ayuda. Ejemplo 1 Encuentre la raz de ] 1 exp(0.146843c) f (c) = 667.38 40 c [

en el intervalo de [0.5, 18.0]


import numpy as np import matplotlib.pyplot as plt c = np.linspace(0.5, 18.0) f = 667.38*(1 - np.exp(-0.146843*c))/c - 40 plt.plot(c, f) plt.grid() plt.show()

49

Programacion con Python, Release 0.4

60 50 40 30 20 10 0 100 2 4 6 8 10 12 14 16 18

Puede notarse que la solucin est entre 14 y 16. Si graca en ese intervalo, puede notarse un poco mejor la raz.
import numpy as np import matplotlib.pyplot as plt c = np.linspace(14.0, 16.0) f = 667.38*(1 - np.exp(-0.146843*c))/c - 40 plt.plot(c, f) plt.grid() plt.show()

50

Captulo 6. Races de ecuaciones no lineales

Programacion con Python, Release 0.4

2.0 1.5 1.0 0.5 0.0 0.5 1.0 1.5 2.0 2.5 14.0 14.5 15.0 15.5 16.0

Se puede utilizar Scipy para encontrar las races de manera numrica, con mucha simplicidad. A continuacin se muestra cmo se resuelve el problema anterior con el mtodo de biseccin, uno de los ms simples para encontrar races de ecuaciones no lineales.
import numpy as np from scipy.optimize import bisect def f(x): return 667.38*(1 - np.exp(-0.146843*x))/x - 40 x0 = bisect(f, 0.5, 18.0) print(x0)

6.1.2 Ejercicios
1. Determine la raz real ms grande de h(x) = 2x3 11.7x2 + 17.7x 5 (a) En forma grca.
import numpy as np import matplotlib.pyplot as plt x = np.linspace(0.0, 4.0) h = ((2*x - 11.7)*x plt.plot(x, h) + 17.7)*x - 5.0

6.1. Introduccin: Races de ecuaciones no lineales

51

Programacion con Python, Release 0.4

plt.grid() plt.show()

8 6 4 2 0 2 4 6 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0

import numpy as np import matplotlib.pyplot as plt x = np.linspace(3.5, 3.6) h = ((2*x - 11.7)*x plt.plot(x, h) plt.grid() plt.show() + 17.7)*x - 5.0

52

Captulo 6. Races de ecuaciones no lineales

Programacion con Python, Release 0.4

0.6 0.4 0.2 0.0 0.2 0.4 0.6 0.8 3.50 3.52 3.54 3.56 3.58 3.60

Puede notarse que la raz ms grande es aproximadamente 3.56. (b) Con el mtodo de Newton-Raphson (tres iteraciones, x0 = 3, = 0.001). Este mtodo es una aproximacin a una raz de f (x) = 0 a partir del valor inicial p0 mediante la iteracin: pk = pk1 f (pk1 ) f (pk1 )

Un algoritmo para el mtodo de Newton-Raphson se obtiene fcilmente al sustituir la ecuacin anterior por la frmula predictiva x = g (x) en el algoritmo de punto jo. Observe, sin embargo, que el programa tambin debe modicarse para calcular la primera derivada. Considerando varios problemas potenciales con el mtodo de Newton Raphson, el programa se podra mejorar incorporando algunas consideraciones adicionales (ver pg. 153, 154 del libro Mtodos numricos para ingenieros, de Chapra y Canale).
def newton_raphson(g, dg, p0, delta, epsilon, num_max_iteraciones): # DATOS DE ENTRADA # g es la funcion de iteracin. # dg es la derivada de g # p0 es la aproximacion inicial a un cero de f # delta es la tolerancia para la diferencia entre un valor de la # iteracion y el valor de la iteracion anterior # epsilon es la tolerancia para los valores de la funcion # numMaxIteraciones es el numero maximo de iteraciones # RESULTADOS: # err es la diferencia entre dos trminos consecutivos

6.1. Introduccin: Races de ecuaciones no lineales

53

Programacion con Python, Release 0.4

# P es la sucesin {pn} completa # k es el nmero de iteraciones realizadas # P[k] es la aproximacin al punto fijo P = zeros(numMaxIteraciones + 1) P[0] = p0 for k in range(1, numMaxIteraciones + 1): gk = P[k - 1] - g(P[k - 1])/dg(P[k - 1]) P[k] = gk err = abs(P[k] - P[k - 1]) errorRelativo = 2*err/(abs(P[k]) + delta) y = g(P[k]) if (err < delta or errorRelativo < delta or abs(y) < epsilon): break if (k == numMaxIteraciones): print('Se ha excedido el numero de iteraciones') return P, k, errorRelativo def h(x): return ((2*x - 11.7)*x def dh(x): return (6.0*x - 23.4)*x + 17.7 P, k, error_relativo = newton_raphson(h, dh, 3.0, 0.001, 0.0001, 10) + 17.7)*x - 5.0

(c) Utilizando el mtodo


def h(x):

newton

del mdulo

scipy.optimize.

return ((2*x - 11.7)*x def dh(x):

+ 17.7)*x - 5.0

return (6.0*x - 23.4)*x + 17.7 from scipy.optimize import newton zero = newton(h, 3.0, dh) print(zero)

6.2 Un vistazo a la librera GNU Scientic Library (GSL)


Aprovecharemos que la librera GSL tiene rutinas para encontrar las races de funciones unidimensionales arbitrarias que proporcionan acceso a los pasos intermedios de la solucin, para estudiar cmo funcionan los mtodos de intervalos. La librera GSL est escrita en C. No te preocupes si no comprendes todo el cdigo del ejemplo siguiente (basado en el manual de referencia de la GNU GSL). Esta parte del curso es ms ilustrativa y de ninguna manera exhaustiva. Lee con atencin los comentarios que se dan en el cdigo, pues te servirn de mucho para comprender la intencin del mismo.
/* * ===================================================================================== * * * * * Descripcin: Definicin de Nombre del archivo: demo_fn.h

54

Captulo 6. Races de ecuaciones no lineales

Programacion con Python, Release 0.4

* * * * * * * * * * *

+ Estructura parametros_cuadratica. Esta estructura almacena los coeficientes {a, b, c} de un polinomio cuadrtico ax^2 + bx + c como nmeros de tipo double. Declaracin de prototipos de funciones para + Evaluar un polinomio cuadrtico, dado por los parmetros apuntados por params, en un valor x (cuadratica) + Evaluacin de la derivada del polinomio cuadrtico (deriv_cuadratica) + Evaluacin simultnea del polinomio y de su derivada (fdf_cuadratica)

* ===================================================================================== */ struct parametros_cuadratica { double a, b, c; }; double cuadratica(double x, void *params); double deriv_cuadratica(double x, void *params); void fdf_cuadratica(double x, void *params, double *y, double *dy);

A continuacin se muestra la implementacin de los prototipos declarados en demo_fn.h


/* * ===================================================================================== * * * * * * * ===================================================================================== */ #include "demo_fn.h" double cuadratica(double x, { struct parametros_cuadratica *p = (struct parametros_cuadratica *) params; double a = p->a; double b = p->b; double c = p->c; return (a * x + b) * x + c; } double deriv_cuadratica(double x, void *params) { struct parametros_cuadratica *p = (struct parametros_cuadratica *) params; double a = p->a; double b = p->b; double c = p->c; return 2.0 * a * x + b; } void *params) Descripcin: Definicin (implementacin) de los prototipos en demo_fn.h Nombre del archivo: demo_fn.c

6.2. Un vistazo a la librera GNU Scientic Library (GSL)

55

Programacion con Python, Release 0.4

void fdf_cuadratica(double x, void *params, double *y, double *dy) { struct parametros_cuadratica *p = (struct parametros_cuadratica *) params; double a = p->a; double b = p->b; double c = p->c; *y = (a * x + b) * x + c; *dy = 2.0 * a * x + b; }

Finalmente, el siguiente programa utiliza los dos archivos de cdigo fuente anteriores para encontrar la raz del polinomio cuadrtico x2 5 = 0:
/* * ===================================================================================== * * * * * * * */ #include <stdio.h> #include <gsl/gsl_errno.h> #include <gsl/gsl_math.h> #include <gsl/gsl_roots.h> #include "demo_fn.c" int main () { int estado; /* Indica el estado de una iteracin del mtodo */ int iter = 0; /* Contador de iteraciones */ const int MAX_ITER = 100; /* Nmero mximo de iteraciones */ const gsl_root_fsolver_type *T; /* Apuntador al _tipo_ de solucionador */ gsl_root_fsolver *s; /* Apuntador a la instancia del solucionador */ double r = 0.0; /* Valor inicial de la raz */ double raiz_esperada = sqrt (5.0); /* Valores iniciales de los limites del intervalo de bsqueda */ double x_inferior = 0.0, /* * Estructura capaz de apuntar a * * */ gsl_function F; struct parametros_cuadratica params = {1.0, F.function = &cuadratica; F.params = &params; /* Se utiliza el mtodo de biseccin. 0.0, -5.0}; + la funcin cuya raz desea encontrarse + los parmetros que necesita la funcin x_superior = 5.0; Compilar con: Descripcin: Ejemplo del uso de rutinas de GSL para encontrar las races de funciones unidimensionales arbitrarias. icc demo_root.c -lgsl -o demo_root Nombre del archivo: demo_root.c

* =====================================================================================

56

Captulo 6. Races de ecuaciones no lineales

Programacion con Python, Release 0.4

* NOTA: Se pueden seleccionar entre diferentes tipos de solucionadores. * */ T = gsl_root_fsolver_bisection; s = gsl_root_fsolver_alloc (T); /* Se crea la nueva instancia del solucionador */ /* * Se inicializa el solucionador s para que use la funcin F y * el intervalo inicial de bsqueda [x_inferior, */ gsl_root_fsolver_set (s, &F, x_inferior, x_superior); /* Imprimir el nombre del mtodo usado */ printf ("Usando el mtodo %s\n", printf ("%5s [%9s, "iter", /* * Iterar mientras que * el estado sea GSL_CONTINUE y * no se haya alcanzado el nmero mximo de iteraciones */ do { iter++; /* Incrementar en uno el contador de iteraciones */ /* * Lleva a cabo una iteracin del solucionador s. * Si la iteracin encuentra un error inesperado, la variable estado * contiene un cdigo de error */ estado = gsl_root_fsolver_iterate (s); /* Actualiza la mejor estimacin de la raz que se tiene al momento */ r = gsl_root_fsolver_root (s); /* Actualiza los lmites del mejor intervalo que encierra una posible raz */ x_inferior = gsl_root_fsolver_x_lower (s); x_superior = gsl_root_fsolver_x_upper (s); /* * Verificar la convergencia del mtodo en el intervalo con * error absoluto = 0.0 * error relativo = 0.001 * El test devuelve GSL_SUCCESS si el mtodo ha convergido */ estado = gsl_root_test_interval (x_inferior, if (estado == GSL_SUCCESS) printf ("El mtodo converge:\n"); /* Mostrar informacin sobre la iteracin actual */ printf ("%5d [%.7f, iter, x_inferior, x_superior, r, r - raiz_esperada, x_superior - x_inferior); } while (estado == GSL_CONTINUE && iter < MAX_ITER); /* Liberar la memoria asociada al solucionador s */ gsl_root_fsolver_free (s); %.7f] %.7f %+.7f %.7f\n", x_superior, 0, 0.001); gsl_root_fsolver_name (s)); /* Imprimir el encabezado de resultados intermedios */ %9s] %9s %10s %9s\n", "superior", "raiz", "err", "err(est)"); "inferior", x_superior] Verifique el manual de la GSL

6.2. Un vistazo a la librera GNU Scientic Library (GSL)

57

Programacion con Python, Release 0.4

/* Terminar el programa devolviendo el valor de la variable estado */ return estado; } /* ---------Fin de la funcin main ---------- */

El resultado de ejecutar el programa anterior es:


Usando el mtodo bisection iter [ inferior, 1 [0.0000000, 2 [1.2500000, 3 [1.8750000, 4 [2.1875000, 5 [2.1875000, 6 [2.1875000, 7 [2.2265625, 8 [2.2265625, 9 [2.2265625, 10 [2.2314453, 11 [2.2338867, El mtodo converge: 12 [2.2351074, 2.2363281] 2.2357178 -0.0003502 0.0012207 superior] raiz err err(est) 2.5000000] 1.2500000 -0.9860680 2.5000000 2.5000000] 1.8750000 -0.3610680 1.2500000 2.5000000] 2.1875000 -0.0485680 0.6250000 2.5000000] 2.3437500 +0.1076820 0.3125000 2.3437500] 2.2656250 +0.0295570 0.1562500 2.2656250] 2.2265625 -0.0095055 0.0781250 2.2656250] 2.2460938 +0.0100258 0.0390625 2.2460938] 2.2363281 +0.0002601 0.0195312 2.2363281] 2.2314453 -0.0046227 0.0097656 2.2363281] 2.2338867 -0.0021813 0.0048828 2.2363281] 2.2351074 -0.0009606 0.0024414

Verica manualmente los resultados de la tabla anterior.

58

Captulo 6. Races de ecuaciones no lineales

CAPTULO

Diferenciacin e integracin numrica

7.1 Diferenciacin numrica bsica


Aproximacin a la primera derivada con diferencia hacia adelante f (xi ) = f (xi+1 ) f (xi ) + O(xi+1 xi ) xi+1 xi

Aproximacin a la primera derivada con diferencia hacia atrs f (xi ) = f (xi ) f (xi1 ) + O(xi xi1 ) xi xi1

Aproximacin a la primera derivada con diferencias centradas f (xi ) = ( ) f (xi+1 ) f (xi1 ) + O h2 2(xi+1 xi1 )

El siguiente bloque de cdigo resuelve el problema:


def derivadasConDifDivididas(f, xi, h): difHaciaAdelante = (f(xi + h) - f(xi))/h print("Con diferencia hacia adelante: {}".format(difHaciaAdelante)) difHaciaAtras = (f(xi) - f(xi - h))/h print("Con diferencia hacia atras: {}".format(difHaciaAtras)) difCentradas = (f(xi + h) - f(xi - h))/(2*h) print("Con diferencia centrada: {}".format(difCentradas)) def f(x): return (((-0.1*x - 0.15)*x - 0.5)*x - 0.25)*x + 1.2 derivadasConDifDivididas(f, 0.5, 0.5) derivadasConDifDivididas(f, 0.5, 0.25)

59

Programacion con Python, Release 0.4

Utilizando Scipy:
from scipy.misc import derivative def f(x): return (((-0.1*x - 0.15)*x - 0.5)*x - 0.25)*x + 1.2 df = derivative(f, 0.5, 0.25)

7.2 Integracin numrica


Algunas funciones pueden ser integradas de manera analtica, mientras que muchas otras no, y entonces se debe recurrir a una aproximacin numrica a la integral. Por ejemplo, en el campo de la termodinmica estadstica, el modelo de Debye para calcular la capacidad calrica de un slido considera la siguiente funcin x t3 (x) = dt t 0 e 1 Puesto que ho hay una expresin analtica para (x), debemos usar algn mtodo de integracin numrica para calcular sus valores.

7.2.1 Ejemplo 1
Calcule
0 4

x2 dx utilizando

scipy.integrate

y compare con el resultado analtico:

from scipy import integrate x2 = lambda x: x**2 integ = integrate.quad(x2, 0.0, 4.0) print integ

Ahora calcule de manera numrica: 1. (5) 2. ex dx. Pista: utilice


0

inf

para denotar +.

La regla trapezoidal La regla trapezoidal es la ms sencilla de todas las frmulas de integracin cerrada de Newton-Cotes. Geomtricamente, la regla trapezoidal es equivalente a aproximar el rea bajo la curva con la del trapecio bajo la lnea recta que conecta f (a) y f (b) en la Figura Regla trapezoidal . Recuerde que la frmula para calcular el rea de un trapecio es la altura por el promedio de las bases. En nuestro caso, el concepto es el mismo, pero el trapecio est sobre su lado. La regla compuesta del trapecio Un mtodo intuitivo para hallar el rea limitada por una curva y = f (x) en un intervalo [a, b] es dar una aproximacin a dicha rea sumando las reas de una serie de trapecios construidos sobre los intervalos {[xk , xk+1 ]} de una particin de [a, b]. 60 Captulo 7. Diferenciacin e integracin numrica

Programacion con Python, Release 0.4

Figura 7.1: Regla trapezoidal

from pylab import * from matplotlib.patches import Polygon def func(x): return (x-3) * (x-5) * (x-7) + 85 ax = subplot(111) a, b = 2, 9 # Area de la integral x = arange(0, 10, 0.01) y = func(x) plot(x, y, linewidth=1) # make the shaded region ix = linspace(a, b, 4) iy = func(ix) verts = [(a,0)] + zip(ix,iy) + [(b,0)] poly = Polygon(verts, facecolor='0.8', edgecolor='k') ax.add_patch(poly) markerline, stemlines, baseline = stem(ix, iy, 'k-.') setp(markerline, 'markerfacecolor', 'b') axis([0,10, 0, 180]) figtext(0.9, 0.05, 'x') figtext(0.1, 0.9, 'y') ax.set_xticks((a,b)) ax.set_xticklabels(('a','b'))

7.2. Integracin numrica

61

Programacion con Python, Release 0.4

ax.set_yticks([]) show()

Supongamos que se divide el intervalo [a, b] en M subintervalos [xk , xk+1 ] de anchura comn h = (b a)/M mediante una particin cuyos nodos xk = a + kh, para k = 0, 1, . . . , M , estn equiespaciados. La regla compuesta del trapecio con M subintervalos se puede expresar de las siguientes formas equivalentes: T (f, h) = h (f (xk1 ) + f (xk )) 2
M k=1

(7.1)

o bien T (f, h) = h (f0 + 2f1 + 2f2 + 2f3 + + 2fM 2 + 2fM 1 + fM ) 2 (7.2)

o bien T (f, h) =
M 1 h (f (a) f (b)) + h f (xk ) 2 k=1

(7.3)

Este valor es una aproximacin a la integral de f (x) en [a, b], lo que se escribe como
a b

f (x) dx T (f, h)

7.2.2 Ejemplo 2
Consideremos f (x) = 2 + sin(2 x). Vamos a usar la regla compuesta del trapecio con 11 nodos para calcular una aproximacin a la integral de f (x) en el intervalo [1, 6]. Para los once nodos, tomamos M = 10, con lo que h = (6 1)/10 = 1/2. Usando la frmula (7.3), los clculos son: ( ) 1 1/2 T f, = (f (1) + f (6)) + 2 2 ( ( ) ( ) ( ) ( ) ( )) 1 3 5 7 9 11 f + f (2) + f + f (3) + f + f (4) + f + f (5) + f 2 2 2 2 2 2 1 = (2.9093 + 1.01735) + 4 1 (2.63815 + 2.30807 + 1.97931 + 1.68305 + 1.43530 + 1.24319 + 1.10831 + 1.02872 + 1.00024) 2 1 1 = (3.92665) + (14.42438) 4 2 = 0.98166 + 7.21219 = 8.19385 Compruebe el resultado anterior manualmente y despus utilizando el siguiente cdigo:

62

Captulo 7. Diferenciacin e integracin numrica

Programacion con Python, Release 0.4

from numpy import linspace, sin, sqrt from scipy.integrate import trapz x = linspace(1, 6, 11) y = 2 + sin( 2*sqrt(x) ) T = trapz(y, x) print(T)

7.2. Integracin numrica

63

Programacion con Python, Release 0.4

64

Captulo 7. Diferenciacin e integracin numrica

CAPTULO

Ecuaciones Diferenciales Ordinarias

8.1 Ecuaciones Diferenciales Ordinarias


Considere la ecuacin: dy = 1 e t dt Esta ecuacin es separable, por lo que puede resolverse directamente mediante integracin: y (t) = t + et + C

donde C es la constante de integracin. En esta solucin existe un grado de libertad, dado por la eleccin de la constante de integracin C .
import matplotlib.pyplot as plt import numpy as np num_puntos = 81 t = np.linspace(-2.0, 5.0, num_puntos) num_curvas = 5 y = np.zeros((num_curvas, num_puntos)) for i, C in enumerate(range(-2, num_curvas - 2)): y[i] = plt.grid() plt.show() t + np.exp(-t) + C plt.plot(t, y[i])

65

Programacion con Python, Release 0.4

8 7 6 5 4 3 2 1 0 12 1 0 1 2 3 4 5

A diferencia de la ecuacin diferencial dada, no todas pueden resolverse de manera exacta (ya sea mediante integracin directa o por alguno de los mtodos tradicionales). A menudo se da el caso de que no hay una solucion analtica conocida, por lo que necesitamos aproximaciones numricas. A modo de ejemplo, consideremos, en el contexto de la dinmica de poblaciones, un sistema no lineal que es una modicacin de las ecuaciones de Lotka-Volterra x = f (t, x, y ) = x xy 1 2 x 10 1 y = g (t, x, y ) = xy y y 2 20

para 0 t 30 con la condicin inicial x(0) = 2 e y (0) = 1. La solucin numrica se consigue con el siguiente cdigo:
import matplotlib.pyplot as plt import numpy as np from scipy.integrate import odeint x0 = [2, 1] def f(xVec, t): x, y = xVec f0 = x - x*y - x**2 / 10.0 f1 = x*y - y - y**2 / 20.0 return [f0, f1]

66

Captulo 8. Ecuaciones Diferenciales Ordinarias

Programacion con Python, Release 0.4

t = np.linspace(0.0, 30.0, 3001) xVec = odeint(f, x0, t) x = xVec[:, 0] y = xVec[:, 1] plt.plot(x, y) plt.show()

8.1.1 Mezclas de soluciones salinas


La mezcla de dos soluciones salinas de distintas concentraciones da lugar a una ecuacin diferencial de primer orden, que dene la cantidad de sal que contiene la mezcla. Supongamos que un tanque est parcialmente lleno con 100 galones de salmuera (sal disuelta en agua), con 1 lb de sal por galn a razn de 6 gal/min. El contenido del 10 lb de sal disuelta. Le entra salmuera con 2 tanque est bien mezclado y de l sale a razn de 6 gal/min. El contenido del tanque est bien mezclado y de l sale a razn de 4 gal/min de solucin. Calcule la cantidad de libras de sal que hay en el tanque a los 30 minutos. ( )( ) 1 lb gal lb Ri = 6 =3 2 gal min min )( ) ( lb gal 2A lb A 4 = Ro = 100 + 2t gal min 50 + t min dA 2A = Ri Ro = 3 dt 50 + t La ecuacin diferencial anterior se puede expresar en la forma estndar para las ecuaciones lineales: dA 2 + A=3 dt 50 + t El factor integrante es:

(8.1)

2 50+t

dt

= e2 ln(50+t) = (50 + t)2

(8.2)

Multiplicando la Ec. (8.1) por el factor integrante (8.2) ( ) dA 2 2 (50 + t) + A = 3(50 + t)2 dt 50 + t ] d [ (50 + t)2 A , por lo que tenemos la expresin ms simple: dt ] d [ (50 + t)2 A = 3(50 + t)2 dt

identicamos el lado izquierdo como

que hay que resolver por integracin de ambos miembros: (50 + t)2 A = 3 (50 + t)2 dt = (50 + t)3 + C

Sustituyendo la condicin inicial A(0) = 10, en la expresin anterior, obtenemos C = 100000. La solucin de la Ec. (8.1) es: A(t) = 50 + t 100000 (50 + t)2

8.1. Ecuaciones Diferenciales Ordinarias

67

Programacion con Python, Release 0.4

Por lo tanto, a los 30 min., la cantidad de sal disuelta en el tanque es A(30) = 64.375 lb. Resuelva de manera numrica el problema. Graque la solucin exacta junto con la solucin numrica, hasta los 35 min.

8.1.2 Un resorte de Hooke con estmulo senoidal


El movimiento vertical de un peso sujeto a un resorte que obedece la Ley de Hooke, y que tiene un estmulo senoidal externo se puede modelar con la ecuacin diferencial:
2 y + 2cy + 0 y = F0 sin(t)

(8.3)

donde c, 0 y son nmeros reales positivos. Considremos el caso en que c < 0 , que corresponde a un sistema sub-amortiguado. Adems suponga que < 0 . Con estas suposiciones, la solucin general de (8.3) se puede expresar como y = yu + yd , donde ( ) ( ) 2 c2 + C ect sin t 2 c2 (8.4) yu = C1 ect cos t 0 2 0 yd = F0 M ( ) sin[t + ( )] C1 , C2 dependen de las condiciones iniciales y 1 M ( ) = 2 (0 2 )2 + 4c2 2 ( ) 2c ( ) = arctan < ( ) < 0 2 2 0 Ejemplo El sistema y +y + 4y = 12 sin t (8.6) (8.7) (8.5)

con c = 1/2, 0 = 2, = 1, sujeto a las condiciones iniciales y (0) = 0, y (0) = 0 tiene la solucin [ ( ) ( )] 15 2 15 6 t/2 6 y (t) = e cos t 15 sin t + 10 sin(t 0.32175) 5 2 5 2 5

import matplotlib.pyplot as plt import numpy as np tfinal = 20.0 num_puntos = tfinal * 100 + 1 t = np.linspace(0.0, tfinal, num_puntos) theta = np.sqrt(15)*t/2.0 yu = np.exp(-0.5*t)*(1.2*np.cos(theta) - 1.54919*np.sin(theta)) yd = 1.2*np.sqrt(10)*np.sin(t - 0.32175) y = yu + yd plt.plot(t, y) plt.grid() plt.show()

68

Captulo 8. Ecuaciones Diferenciales Ordinarias

Programacion con Python, Release 0.4

4 3 2 1 0 1 2 3 40 5 10 15 20

Una solucin numrica de este problema, utilizando un mtodo de Runge-Kutta de orden (4)5 debido a Dormand y Prince (con control del tamao de paso y salida densa) est dada por el siguiente cdigo:
import matplotlib.pyplot as plt import numpy as np from scipy.integrate import ode from math import sin y0 = [0, 0] t0 = 0 def f(t, y, c, omega0, F0, omega): x, v = y xDot = v vDot = -omega0*omega0 *x - 2*c*v + F0*sin(omega*t) return [xDot, vDot] r = ode(f).set_integrator('dopri5') r.set_initial_value(y0, t0) #(c = 0.5, omega0 = 2.0, F0 = 12.0, omega = 1.0) r.set_f_params(0.5, 2.0, 12.0, 1.0) t1 = 20.0 t = np.linspace(0.0, t1, t1*100 + 1)

8.1. Ecuaciones Diferenciales Ordinarias

69

Programacion con Python, Release 0.4

dt = t[1] y = np.zeros(len(t)) y[0] = y0[0] i = 1 while r.successful() and r.t <= t1: r.integrate(r.t + dt) t[i] = r.t y[i] = r.y[0].real i += 1 plt.plot(t, y) plt.grid() plt.axis([0.0, 20.0, -4.0, 4.0]) plt.show()

8.2 PROYECTO FINAL: Rescatando a la tripulacin del Apollo 13


En 1970, la tripulacin del Apollo 13 abort el aterrizaje lunar debido a una explosin en uno de los tanques de oxgeno. Utilizando los siguientes datos, simule la trayectoria de la nave Descripcin Masa de la Tierra Radio terrestre (en el ecuador) Constante de Gravitacin Universal Masa de la Luna Radio de la Luna Distancia Tierra a Luna (en realidad no es cte.) Periodo de la Luna ngulo inicial de la Luna Duracin total del viaje Posicin inicial de la nave (en t = 0) Velocidad inicial de la nave (en t = 0) Simule Una reduccin (instantnea) en la rapidez de 7.04 m/s a los 101,104 segundos Un incremento (instantneo) de la velocidad, dado por la variable boost (en m/s), a los 212,100 segundos. Pruebe con los valores siguientes valores para boost: 10.0, 10.0, 50.0, 100.0. Suponga que la Tierra est en el centro del plano coordenado. Considere el movimiento de traslacin de la Luna alrededor de la Tierra, como una rbita circular. Utilizando la Ley de Gravitacin Universal, y la segunda Ley de Newton, obtenemos una ecuacin diferencial de segundo orden, explcita y no lineal, que determina la aceleracin de la nave n = G x mL mT xn + G (xL xn ) 3 xn xL xn 3 (8.8) Valor 5.97 1024 kg 6.378 106 m 6.67 1011 m3 /(kg s2 ) 7.35 1022 kg 1.74 106 kg 400.5 106 m 27.3 das 61 12 das [6.701 106 , 0]T m [0, 10.818 103 ]T m/s

donde xn es la posicin de la nave (relativa a la Tierra); mT , la masa de la Tierra; G, la constante de Gravitacin Universal; mL , la masa de la Luna; xL es la posicin de la Luna. Una grca de la ruta seguida por la nave debe verse similar a la siguiente:

70

Captulo 8. Ecuaciones Diferenciales Ordinarias

Programacion con Python, Release 0.4

8.2. PROYECTO FINAL: Rescatando a la tripulacin del Apollo 13

71

Programacion con Python, Release 0.4

72

Captulo 8. Ecuaciones Diferenciales Ordinarias

CAPTULO

ndices y tablas

genindex modindex search

73

Вам также может понравиться