In [9]:
%pylab inline
#%numpy.linalg inline
%qtconsole
from mpl_toolkits.mplot3d import Axes3D
from ipywidgets import interact, interactive
from IPython.display import clear_output, display, HTML
La computadora es una gran gran calculadora que permite hacer cualquier tipo de cuenta de las que necesitemos dentro de la Física (y de la vida también) mientras sepamos cómo decirle a la máquina qué cómputos hacer.
La computadora para hacer cuentas tiene que almacenar los números que necesitemos y luego hacer operaciones con ellos. Nuestros valores numéricos se guardan en espacios de memoria, y esos espacios tienen un nombre, un rótulo con el cual los podremos llamar y pedirle a la computadora que los utilice para operar con ellos, los modifique, etc. Ese nombre a cada espacio de memoria se asigna, al menos en Python, con el símbolo = que significa de ahora en más: "asignación".
Pero no sólamente guardaremos valores numéricos. Además de haber distintos tipos de valores numéricos, como veremos ahora, podemos guardar otros tipos de datos, como texto (strings) y listas (lists) entre muchos otros. Todos los tipos de valores que podremos almacenar difieren entre si el espacio en memoria que ocupan y las operaciones que podremos hacer con ellos.
Veamos un par de ejemplos
In [6]:
x = 5
y = 'Hola mundo!'
z = [1,2,3]
Aquí hemos guardado en un espacio de memoria llamado por nosotros "x" la información de un valor de tipo entero, 5, en otro espacio de memoria, que nosotros llamamos "y" guardamos el texto "Hola mundo!". En Python, las comillas indican que lo que encerramos con ellas es un texto. x no es un texto, así que Python lo tratará como variable para manipular. "z" es el nombre del espacio de memoria donde se almacena una lista con 3 elementos enteros.
Podemos hacer cosas con esta información. Python es un lenguaje interpretado (a diferencia de otros como Java o C++), eso significa que ni bien nosotros le pedimos algo a Python, éste lo ejecuta. Así es que podremos pedirle por ejemplo que imprima en pantalla el contenido en y, el tipo de valor que es x (entero) entre otras cosas.
In [4]:
print y
print type(x)
print type(y), type(z), len(z)
Vamos a utilizar mucho la función type() para entender con qué tipo de variables estamos trabajando. type() es una función predeterminada por Python, y lo que hace es pedir como argumento (lo que va entre los paréntesis) una variable y devuelve inmediatamente el tipo de variable que es.
Para las variables integers(enteros) y floats (flotantes) podemos hacer las operaciones matemáticas usuales y esperables. Veamos un poco las compatibilidades entre estos tipos de variables.
In [25]:
a = 5
b = 7
c = 5.0
d = 7.0
print a+b, b+c, a*d, a/b, a/d, c**2
Las listas son cadenas de datos de cualquier tipo, unidos por estar en una misma variable, con posiciones dentro de esa lista, con las cuales nosotros podemos llamarlas. En Python, las listas se enumeran desde el 0 en adelante.
Estas listas también tienen algunas operaciones que le son válidas.
Distintas son las tuplas. Las listas son editables, pero las tuplas no. Esto es importante cuando, a lo largo del desarrollo de un código donde necesitamos que ciertas cosas no cambien, no editemos por error valores fundamentales de nuestro problema a resolver.
In [15]:
lista1 = [1, 2, 'saraza']
print lista1, type(lista1)
print lista1[1], type(lista1[1])
print lista1[2], type(lista1[2])
print lista1[-1]
In [14]:
lista2 = [2,3,4]
lista3 = [5,6,7]
print lista2+lista3
print lista2[2]+lista3[0]
In [17]:
tupla1 = (1,2,3)
lista4 = [1,2,3]
lista4[2] = 0
print lista4
#tupla1[0] = 0
print tupla1
Hay formas muy cómodas de hacer listas. Presentamos una que utilizaremos mucho, que es usando la función range.
In [18]:
listilla = range(10)
print listilla, type(listilla)
Este tipo de variable tiene sólo dos valores posibles: 1 y 0, o True y False. Las utilizaremos escencialmente para que Python reconozca relaciones entre números.
In [20]:
print 5>4
print 4>5
print 4==5 #La igualdad matemática se escribe con doble ==
print 4!=5 #La desigualdad matemática se escribe con !=
print type(4>5)
Pero las operaciones básicas de suma, resta, multiplicación y división son todo lo que un lenguaje como Python puede hacer "nativamente". Una potencia o un seno es álgebra no lineal, y para hacerlo, habría que inventarse un algoritmo (una serie de pasos) para calcular por ejemplo sen($\pi$). Pero alguien ya lo hizo, ya lo pensó, ya lo escribió en lenguaje Python y ahora todos podemos usar ese algoritmo sin pensar en él. Solamente hay que decirle a nuestro intérprete de Python dónde está guardado ese algoritmo. Esta posibilidad de usar algoritmos de otros es fundamental en la programación, porque es lo que permite que nuestro problema se limite solamente a entender cómo llamar a estos algoritmos ya pensados y no tener que pensarlos cada vez.
Vamos entonces a llamar a una biblioteca llamada math que nos va a extender nuestras posibilididades matemáticas.
In [24]:
import math as m # Llamamos a una biblioteca y la bautizamos m por comodidad
r1 = m.pow(2,4)
r2 = m.cos(m.pi)
r3 = m.log(100,10)
r4 = m.log(m.e)
print r1, r2, r3, r4
Para entender cómo funcionan estas funciones, es importante recurrir a su documentation. La de esta biblioteca en particular se encuentra en
Pero si queremos definir nuestra propia manera de calcular algo, o si queremos agrupar una serie de órdenes bajo un mismo nombre, podemos definirnos nuestras propias funciones, pidiendo la cantidad de argumentos que querramos.
Vamos a usar las funciones lambda más que nada para funciones matemáticas, aunque también tenga otros usos. Definamos el polinomio $f(x) = x^2 - 5x + 6$ que tiene como raíces $x = 3$ y $x = 2$.
In [27]:
f = lambda x: x**2 - 5*x + 6
print f(3), f(2), f(0)
Las otras funciones, las más generales, se las llama funciones def, y tienen la siguiente forma.
In [29]:
def promedio(a,b,c):
N = a + b + c # Es importante que toda la función tenga su contenido indentado
N = N/3.0
return N
mipromedio = promedio(5,5,7) # Aquí rompimos la indentación
print mipromedio
Si en el fondo un programa es una serie de algoritmos que la computadora debe seguir, un conocimiento fundamental para programar es saber cómo pedirle a una computadora que haga operaciones si se cumple una condición y que haga otras si no se cumple. Nos va a permitir hacer programas mucho más complejos. Veamos entonces como aplicar un if.
In [35]:
def ejemplo(parametro):
if parametro > 0: # un if inaugura también un nuevo bloque indentado
print 'Tu parametro es', parametro, 'y es mayor que cero'
print 'Gracias'
else: # el else inaugura otro bloque indentado
print 'Tu parametro es', parametro, 'y es menor o igual que cero'
print 'Gracias'
print 'Vuelva pronto'
print ' '
ejemplo(5)
ejemplo(-1)
Para que Python repita una misma acción n cantidad de veces, utilizaremos la estructura for. En cada paso, nosotros podemos aprovechar el "número de iteración" como una variable. Eso nos servirá en la mayoría de los casos.
In [41]:
nuevalista = ['nada',1,2,'tres', 'cuatro', 7-2, 2*3, 7/1, 2**3, 3**2]
for i in range(10): # i es una variable que inventamos en el for, y que tomará los valores de la
print nuevalista[i] #lista que se genere con range(10)
La estructura while es poco recomendada en Python pero es importante saber que existe: consiste en repetir un paso mientras se cumpla una condición. Es como un for mezclado con un if.
In [42]:
i = 1
while i < 10: # tener cuidado con los while que se cumplen siempre. Eso daría lugar a los loops infinitos.
i = i+1
print i
Para esta primera parte, utilizaremos una biblioteca muy útil para cálculo matricial, numpy. De allí sacaremos los tipos de dato ndarray, matrix, y todas las operaciones que utilicemos. Veamos un poco cómo definir vectores fila, matrices, y cómo llamar a determinado componente de determinado vector o matriz.
In [5]:
pos = array([1,4,3])
mat = matrix([[1,2,3],
[4,5,6],
[7,8,9]])
x = pos[0] # en Python, las posiciones de los vectores comienzan a contarse en 0
y = pos[1]
z = pos[2]
print 'suma de las componentes:', x+y+z, sum(pos)
c = (mat[0,0] + mat[0,1])* mat[1,1]
print 'operación con los elementos de la matriz:' , c
#Nos acostumbraremos a utilizar arrays para matrices
mat = array(mat) # La función array() transforma mat (que era una matrix) en un ndarray
print mat, type(mat)
Las matrices especiales pueden armarse "a mano" como ejercicio, como también pueden buscarse entre las funciones que Python ofrece
In [6]:
identidad = zeros([3,3])
for i in range(3):
for j in range(3):
if i == j:
identidad[i,j] = 1
print 'identidad armada a mano: '
print identidad
identidad2 = identity(3)
print 'identidad de la función de Python: '
print identidad2
unos = ones([3,4]) #matriz de unos
print 'matriz de unos: '
print unos
ceros = zeros([4,3]) #matriz de ceros
print 'matriz de ceros: '
print ceros
Entre las operaciones que pueden hacerse con vectores y matrices se encuentran las que esperamos que estén: producto escalar, producto de matrices con vectores, transposición.
In [7]:
print 'teníamos la matriz: '
print mat
trans = transpose(mat)
print 'la traspuesta es: '
print trans
print 'vector pos=', pos
print 'producto escalar: ' , dot(pos, pos) # producto escalar entre vectores
print 'producto componente a componente:' , pos*pos # producto componente a componente. Más útil con funciones
A = array([[1,2],[0,1]]) #Otra forma de definir directamente matrices como arrays sin tener que transformar
x = array([1,2])
print 'A = ',A,' ', 'x= ', x
print 'Ax=', dot(A, x)
Y también tenemos esas funciones que siempre quisimos tener desde el CBC: inversa de una matriz, cálculo de determinantes, resolución de sistema de ecuaciones, hallazgo de autovalores y autovectores. Para esto usamos una biblioteca extra llamada linalg.
In [12]:
print 'Podemos encontrar la matriz inversa: '
print inv(A)
print 'su determinante:', det(A)
print 'Resolver un sistema de forma Ax=b'
b = x
print 'x =' ,solve(A, b)
print 'Y hallar autovalores y autovectores'
autoval, autovec = eig(A)
print 'Los autovalores: ', autoval
print 'Los autovectores: ', autovec
Lo siguiente que Python tiene de interesante para usar son sus facilidades para hacer gráficos. La biblioteca matplotlib nos ayudará en este caso. Primero, definimos un vector que nos hace de dominio, luego, un vector imagen de alguna función, y luego haremos el gráfico. Se muestran aquí algunas de las opciones que tiene matplotlib para presentar un gráfico, pero yendo a la documentación podrán encontrar infinidad de herramientas para hacer esto.
In [10]:
# Ploteos
x = linspace(-10, 10, 200) # con la función linspace generaremos un vector con componentes equidistantes.
y = x**2 # el vector imagen será igual de largo que x
plot(x,y, '-', color = 'red', label = 'Curva x**2') # ver qué pasa con 'r', 'g', '*' entre otros
title('Mi primer ploteo')
xlabel('Eje de las x')
ylabel('Eje de las y')
#xlim(-5,5)
#ylim(0,4)
legend('best')
grid(True)
In [38]:
f = lambda x,n: sin(n*pi*x) # Definimos una sucesión de funciones trigonométricas
y = f(x,0) # vector imagen de la función f(x) = 0
for i in range(5): # este es un caso simple donde sumo las 5 primeras funciones de la sucesión
y = y + f(x,i) # a esa y le sumo el valor de las imágenes de las siguientes funciones de la sucesión de funciones
plot(x,y, label = 'Curva')
title('Suma de senos')
xlabel('Dominio')
ylabel('Suma de los primeros 5 senos')
legend('best')
# Podríamos hacer derivación numérica
# Integración sería útil?
# Transformada de Fourier es irse al chori?
Out[38]:
In [ ]:
Para más referencias pueden googlear. Dejamos algunas de referencia:
http://pybonacci.org/2012/06/07/algebra-lineal-en-python-con-numpy-i-operaciones-basicas/
http://relopezbriega.github.io/blog/2015/06/14/algebra-lineal-con-python/
http://pendientedemigracion.ucm.es/info/aocg/python/modulos_cientificos/numpy/index.html
Pero es importantísimo manejarse con la documentación de las bibliotecas que se utilizan
https://docs.python.org/2/library/math.html
http://docs.scipy.org/doc/numpy/reference/routines.linalg.html
In [ ]: