Numpy – Vectores y matrices

Resumen de algunas funciones para vectores y matrices como arreglos en la librería Numpy de Python, usadas en el curso para facilitan el cálculo numérico. El orden de las instrucciones es el que aparece en las entradas del blog.

Lo primero es hacer el llamado a las librerías con el alias ‘np’

import numpy as np

Vectores

puntos espaciados entre [a,b] – np.linspace()

para obtener puntos en el rango [a,b] para una cantidad de tramos. Se obtienen tramos+1 puntos .

a = 1
b = 2
tramos = 4
x = np.linspace(a,b,tramos+1)
>>> x
array([ 1.  ,  1.25,  1.5 ,  1.75,  2.  ])

rango de valores en vector – np.arange(a,b,dt)

crea un vector con valores en el rango [a,b) y espaciados dt.

t=np.arange(0,10,2)
>>> t
array([0, 2, 4, 6, 8])

transponer vector – np.transpose()

>>> fila = np.array([1,2,3])
>>> columna = np.transpose([fila])
>>> columna
array([[1],
       [2],
       [3]])

indices para ordenar – np.argsort()

para ordenar por una columna específica:
– se obtiene un vector con la columna que se requiere ordenar: tabla[:,0]
– con el vector se determinan los índices para ordenar la tabla por filas: np.argsort()
– se aplica los índices a una copia de la matriz: tabla[orden]

tabla = np.array([[5,3],
                  [4,2],
                  [3,1],
                  [2,4],
                  [1,5]])

# ordenar por primera columna
referencia = tabla[:,0]
orden = np.argsort(referencia)
ordenada = tabla[orden]

print(orden)
print(ordenada)

resultado:

[4 3 2 1 0]
[[1 5]
 [2 4]
 [3 1]
 [4 2]
 [5 3]]
# ordenar por segunda columna
referencia = tabla[:,1]
orden = np.argsort(referencia)
ordenada = tabla[orden]
print(orden)
print(ordenada)

resultado:

[2 1 0 3 4]
[[3 1]
 [4 2]
 [5 3]
 [2 4]
 [1 5]]

Matrices en Numpy

concatenar- np.concatenate((A,b), axis=1)

concatenar usa el parámetro axis: 0 para filas, 1 para columnas.

import numpy as np
cantidad = np.array([[4,2,5],
                     [2,5,8],
                     [5,4,3]])

pagado = np.array([[60.70],
                   [92.90],
                   [56.30]])

matriz = np.concatenate((cantidad,pagado),axis=1)
>>> matriz
array([[  4. ,   2. ,   5. ,  60.7],
       [  2. ,   5. ,   8. ,  92.9],
       [  5. ,   4. ,   3. ,  56.3]])

resolver sistema de ecuaciones – np.linalg.solve(A,B)

Resuelve el sistema de ecuaciones dado por una matriz A y un vector B. siendo, por ejemplo:

 0 =  c1 +  c2
-5 = -c1 - 2c2

c1 = -5 
c2 = 5
>>> A = [[ 1, 1],
	 [-1,-2]]
>>> B = [0,-5]
>>> np.linalg.solve(A,B)
array([-5.,  5.])
>>>

Otras instrucciones

np.pi constante con valor π

>>> np.pi
3.141592653589793
np.sin(t)
np.cos(t)
función trigonométrica en radianes. La variable t puede ser un escalar o un arreglo.

>>> t=0.65
>>> np.sin(0.65)
0.60518640573603955
>>> t=[0, 0.3, 0.6]
>>> np.sin(t)
array([ 0. , 0.29552021, 0.56464247])
np.abs() obtiene el valor absoluto de un número. En el caso de un número complejo obtiene la parte real.
np.real(complejo)
np.imag(complejo)
obtiene la parte real de los números complejos en un vector. Se aplica lo mismo para la parte imaginaria del número complejo.
complex(a,b) crea el número complejo a partir de los valores de a y b.
a=2
b=3
el resultado es: 2+3j
np.piecewise(t, t>=donde, [1,0]) función que crea a partir de t, los valores de la condición t>=donde, ubicando los valores de 1, para otro caso es 0. Usada en la función escalón.
np.roots([a,b,c]) obtiene las raíces del polinomio:
ax2+bx+c
x2 + 3 x + 2 = (x+1)(x+2)

>>> np.roots([1,3,2])
array([-2., -1.])

Sympy – Fórmulas y funciones simbólicas

[ expresiones ] [ operaciones ] [ evaluar f(x) ] [ f(x) a lambda ] [ f(x) matemáticas ] [ derivadas ] [ integrales ]

SymPy es una librería usada para manejar de forma algebraica las expresiones matemáticas. Se requiere definir el símbolo que representa la variable en la expresión, por ejemplo la letra ‘x‘. Si la librería Sympy no está disponible o muestra un error la puede revisar las instrucciones del enlace instalar con pip.

Una formula o función matemática f(x) descrita como fx se puede derivar, integrar, simplificar sus términos. También se puede construir una expresión matemática, por ejemplo desarrollar los términos para un polinomio como Taylor.

Referencia: https://www.sympy.org/es/

[ expresiones ] [ operaciones ] [ evaluar f(x) ] [ f(x) a lambda ] [ f(x) matemáticas ] [ derivadas ] [ integrales ]
..


1. Expresiones con Sympy

Una función f(x) como un polinomio

f(x) = (1-x)^5 + 5 x ((1-x)^4) - 0.4

Se pueden manejar de forma algebraica con Sympy al declarar la variable independiente ‘x’ como un símbolo. La expresión se asigna a fx

import sympy as sym
x = sym.Symbol('x')
fx = (1-x)**5 + 5*x*((1-x)**4) - 0.4

Se simplifican o se expande los términos del polinomio con solo una instrucción,

fx = fx.expand()
print(fx)

mostrando el siguiente resultado:

4*x**5 - 15*x**4 + 20*x**3 - 10*x**2 + 0.6

o una presentación diferente con sym.pprint():

>>> sym.pprint(fx)
           4          5      
5*x*(1 - x)  + (1 - x)  - 0.4
>>> 

Referencia: https://docs.sympy.org/latest/tutorials/intro-tutorial/printing.html#setting-up-pretty-printing

[ expresiones ] [ operaciones ] [ evaluar f(x) ] [ f(x) a lambda ] [ f(x) matemáticas ] [ derivadas ] [ integrales ]
..


2. Operaciones, combinar otras expresiones

A una función simbólica fx se pueden añadir más términos con el mismo símbolo

>>> import sympy as sym
>>> sym.Symbol('x')
>>> fx = sym.cos(x)
>>> gx = fx + x
>>> gx
x + cos(x)
>>> gx = gx - 2
>>> gx
x + cos(x) - 2

Por lo que las funciones simbólicas son útiles cuando se construyen expresiones, como en el caso de series de Taylor descritas en la Unidad01

[ expresiones ] [ operaciones ] [ evaluar f(x) ] [ f(x) a lambda ] [ f(x) matemáticas ] [ derivadas ] [ integrales ]
..


3. Evaluar una expresión f(x) con Sympy

Las expresiones simbólicas se pueden evaluar en un punto, ejemplo x0=0.1 usando la instrucción fx.subs(x,x0), que sustituye el símbolo de la variable x con el valor definido para x0.

>>> import sympy as sym
>>> sym.Symbol('x')
>>> fx = sym.cos(x)
>>> fx.subs(x,0.1)
0.995004165278026

Referencia: https://docs.sympy.org/latest/tutorials/intro-tutorial/basic_operations.html#substitution

[ expresiones ] [ operaciones ] [ evaluar f(x) ] [ f(x) a lambda ] [ f(x) matemáticas ] [ derivadas ] [ integrales ]
..


4. Conversión de forma simbólica a forma numérica Lambda

Para evaluar varios puntos en la expresión  en forma numérica para usar ‘x’ con valores en un vector o matriz como un arreglo, se convierte a la forma numérica Lambda con la instrucción sym.lambdify(x,fx)

>>> >>> import sympy as sym
>>> sym.Symbol('x')
>>> fx = sym.cos(x)
&>>> f_x = sym.lambdify(x,fx)
>>> f_x(0.1)
0.9950041652780258
>>> f_x([0.1,0.3,0.5])
array([0.99500417, 0.95533649, 0.87758256])
>>> 

Referencia: https://docs.sympy.org/latest/tutorials/intro-tutorial/basic_operations.html#lambdify

Ejemplo: Polinomio de Taylor – Ejemplos con Sympy-Python

[ expresiones ] [ operaciones ] [ evaluar f(x) ] [ f(x) a lambda ] [ f(x) matemáticas ] [ derivadas ] [ integrales ]
..


5. expresiones de Funciones matemáticas

Las Funciones matemáticas usadas en otras librerías como Numpy tienen también su representación simbólica en Sympy. Ejemplo cos(x):

f(x) = \cos (x)
>>> import sympy as sym
>>> x = sym.Symbol('x')
>>> fx = sym.cos(x)

Realice pruebas con otras funciones: sin(x), exp(x), log(x), log10(x), Heaviside(x)

[ expresiones ] [ operaciones ] [ evaluar f(x) ] [ f(x) a lambda ] [ f(x) matemáticas ] [ derivadas ] [ integrales ]
..


6. Derivadas con Sympy

Las expresiones de la derivada se obtienen con la expresión fx.diff(x,k), indicando la k-ésima  derivada de la expresión.

>>> import sympy as sym
>>> x = sym.Symbol('x')
>>> fx = sym.cos(x)
>>> x
x
>>> fx
cos(x)
>>> fx.diff(x,1)
-sin(x)
>>> fx.diff(x,2)
-cos(x)

Referencia: https://docs.sympy.org/latest/tutorials/intro-tutorial/calculus.html#derivatives

Ejemplos: Sistemas LTI CT – Respuesta a entrada cero con Sympy-Python

Derivadas como expresión de Sympy sin evaluar

Cuando se requiere expresar tan solo la operación de derivadas, que será luego usada o reemplazada con otra expresión, se usa la derivada sin evaluar. Ejemplo:

y = \frac{d}{dx}f(x)

Para más adelante definir f(x).

En Sympy, la expresión de y se realiza indicando que f será una variable

x = sym.Symbol('x', real=True)
f = sym.Symbol('f', real=True)
y = sym.diff(f,x, evaluate=False) # derivada sin evaluar
g = sym.cos(x) + x**2
yg = y.subs(f,g).doit() # sustituye f con g y evalua .doit()
>>> y
Derivative(f, x)
>>> g
x**2 + cos(x)
>>> yg
2*x - sin(x)

Ejemplos:

Polinomio de Taylor – Ejemplos con Sympy-Python

EDO lineal – solución complementaria y particular con Sympy-Python

EDO lineal – ecuaciones auxiliar, general y complementaria con Sympy-Python

EDP Parabólica – analítico con Sympy-Python

EDP Elípticas – analítico con Sympy-Python

Evaluación de las expresiones Sympy

Se define la expresión ‘derivada’ y se la usa con la instrucción fx.subs(x,valor)

>>> fx.subs(x,0)
1
>>> fx.subs(x,1/3)
0.944956946314738
>>> derivada = fx.diff(x,1)
>>> derivada
-sin(x)
>>> derivada.subs(x,1/3)
-0.327194696796152
>>> 

[ expresiones ] [ operaciones ] [ evaluar f(x) ] [ f(x) a lambda ] [ f(x) matemáticas ] [ derivadas ] [ integrales ]
..


7. Integrales con Sympy

Sympy incorpora la operación del integral en sus expresiones, que pueden ser integrales definidas en un intervalo o expresiones sin evaluar.

>>> import sympy as sym
>>> t = sym.Symbol('t',real=True)
>>> x = 10*sym.exp(-3*t)
>>> x
10*exp(-3*t)
>>> y = sym.integrate(x,(t,0,10))
>>> y
10/3 - 10*exp(-30)/3
>>> y = sym.integrate(x,(t,0,sym.oo))
>>> y
10/3

Referencia: https://docs.sympy.org/latest/tutorials/intro-tutorial/calculus.html#integrals

Ejemplos:
Transformada de Laplace – Integral con Sympy-Python

Series de Fourier de señales periódicas con Sympy-Python

Integral de Convolución entre x(t) y h(t) causal con Sympy-Python

[ expresiones ] [ operaciones ] [ evaluar f(x) ] [ f(x) a lambda ] [ f(x) matemáticas ] [ derivadas ] [ integrales ]

Medir el tiempo de ejecución en Python

Con varios métodos para resolver un problema, una media de eficiencia es el tiempo de ejecución de un algoritmo.

Para determinar el tiempo de ejecución de un algoritmo, se toman las lecturas de tiempo antes y después del bloque, calculando el tiempo de ocupación de las diferencias entre tiempos.

La librería «time» permite obtener lectura del reloj del computador.

Como un algoritmo de prueba se usa la suma de los m primeros números enteros.

# tiempos de ejecuci n de algoritmos
import time

# INGRESO
m = 100

# PROCEDIMIENTO
t1 = time.clock()

# Ejecuta Operaciones del algoritmo
suma = 0
for i in range(0,m,1):
    suma = suma + i

t2 = time.clock()
# Tiempo para ejecutar operaciones
ocupado = t2-t1

# SALIDA
print('tiempos:')
print(t1, t2)
print('tiempo de ejecuci n:')
print(ocupado)

con lo que se obtienen los siguientes resultados:

tiempos:
8.210955878428587e-07 5.46028565915501e-05
tiempo de ejecución:
5.378176100370724e-05
>>> 

Funciones lambda vs def-return

Las dos formas de escritura de funciones matemáticas básicamente hacen lo mismo. Sin embargo, cuando la función se define por tramos, la forma def-return se convierte en la más usada.

Se adjunta un ejemplo:

Funciones Lambda

Permite describir funciones sencillas de una sola línea, que no está conformada por intervalos.

f(x) = x \cos(x) - 2 x^2 + 3 x -1
import numpy as np
fx = lambda x: x*np.cos(x) - 2*(x**2) + 3*x -1
>>> fx(0.2)
-0.28398668443175157

Funciones def-return

Permiten describir en detalle lo que sucede con una función matemática por intervalos. Tiene la ventaja de permitir definir valores por intervalos, puntos discontínuos, etc.

f(x)= \begin{cases} x \cos(x) - 2 x^2 + 3 x -1, & x>0 \\1, & x \leq 0 \end{cases}
import numpy as np
def fx(x):
    if x>0:
        fi = x*np.cos(x) - 2*(x**2) + 3*x -1
    if x<=0:
        fi = 1 
    return(fi)
>>> fx(0.2)
 -0.28398668443175157