Contenido
- Introducción a Python
- Asignación de variables
- Acceso y modificación de los elementos
- Operaciones matemáticas con arrays a nivel de elemento a elemento
- Tipos de Operadores en Python
- Estructuras de control de flujo
- Funciones en Python
- Taller de Modelamiento matemático y fenómenos de evolución
Introducción a Python
En este taller utilizaremos el lenguaje de programación Python junto con algunas de sus bibliotecas especializadas, para expresar y manipular las matemáticas relacionadas con matrices y vectores de manera eficiente. El objetivo principal es introducir herramientas útiles para implementar métodos numéricos enfocados en la resolución de sistemas de ecuaciones diferenciales ordinarias.
Revisaremos una serie de comandos y funciones que demuestran cómo trabajar de forma práctica y estructurada con escalares, vectores y matrices.
Para interactuar con el contenido de esta introducción a Python, acceda al siguiente enlace de Google Colab.
Asignación de variables
a = 1
b = 2; c = 3 # puede usar ; para definir variables en la misma linea
suma = b + c
Puedes utilizar la función print()
para visualizar el valor de un objeto, ya sea una variable, un vector, una matriz u otro tipo de dato.
print(suma)
5
El uso de vectores y matrices es esencial para este resultado de aprendizaje. Por ello, utilizaremos la biblioteca NumPy
, diseñada específicamente para cálculos numéricos y análisis de datos, especialmente cuando se trabaja con grandes volúmenes de información.
import numpy as np # llamada a la librería numpy:
A continuación, utilizaremos algunas funciones básicas para generar rápidamente arrays (vectores y matrices).
- $np.linspace(inicio, fin, n)$: Crea y devuelve una referencia a un array de una dimensión cuyos elementos son la secuencia de
n
valores equidistantes desdeinicio
hastafin
.
x = np.linspace(0,3,4)
print('x=',x) # vector fila (array de 1 dimensión) que contiene 4 números reales equidistantes desde el 0 al 3.
x = np.linspace(0,1,100) # Aquí se redefine el vector x, ya no tendremos acceso al vector x = [0 1 2 3].
print('x=',x)
x= [0. 1. 2. 3.]
x= [0. 0.01010101 0.02020202 0.03030303 0.04040404 0.05050505
0.06060606 0.07070707 0.08080808 0.09090909 0.1010101 0.11111111
0.12121212 0.13131313 0.14141414 0.15151515 0.16161616 0.17171717
0.18181818 0.19191919 0.2020202 0.21212121 0.22222222 0.23232323
0.24242424 0.25252525 0.26262626 0.27272727 0.28282828 0.29292929
0.3030303 0.31313131 0.32323232 0.33333333 0.34343434 0.35353535
0.36363636 0.37373737 0.38383838 0.39393939 0.4040404 0.41414141
0.42424242 0.43434343 0.44444444 0.45454545 0.46464646 0.47474747
0.48484848 0.49494949 0.50505051 0.51515152 0.52525253 0.53535354
0.54545455 0.55555556 0.56565657 0.57575758 0.58585859 0.5959596
0.60606061 0.61616162 0.62626263 0.63636364 0.64646465 0.65656566
0.66666667 0.67676768 0.68686869 0.6969697 0.70707071 0.71717172
0.72727273 0.73737374 0.74747475 0.75757576 0.76767677 0.77777778
0.78787879 0.7979798 0.80808081 0.81818182 0.82828283 0.83838384
0.84848485 0.85858586 0.86868687 0.87878788 0.88888889 0.8989899
0.90909091 0.91919192 0.92929293 0.93939394 0.94949495 0.95959596
0.96969697 0.97979798 0.98989899 1. ]
- $np.arange(inicio, fin, salto)$: Crea y devuelve una referencia a un array de una dimensión cuyos elementos son la secuencia desde
inicio
hastafin
tomando valores cadasalto
.
h = 0.1 # Salto
y = np.arange(0,1,h)
print(y) # vector cuyos elementos son números reales equidistantes entre 0 y 1-h cuyo salto es h.
[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
Para generar una partición del intervalo $[0,1]$ que comience en $0$ y termine en $1$ a paso $h$ fijo, puede usar:
y = np.arange(0,1+h,h)
print(y)
[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]
- $np.empty(dimensiones)$: Crea y devuelve una referencia a un array con las dimensiones especificadas en la tupla
(x,y)
dimensiones.
A = np.empty((3,3)) # tupla dimensiones (a,b): a filas, b columnas.
print(A) # Matriz con 3 filas y 3 columnas (los elementos a_{ij} se definen automáticamente)
[[0.1 0.2 0.3]
[0.4 0.5 0.6]
[0.7 0.8 0.9]]
- $np.zeros(dimensiones)$: Crea y devuelve una referencia a un array con las dimensiones especificadas en la tupla dimensiones cuyos elementos son todos ceros.
A = np.zeros((2,3)) # Matriz de dimensiones 2 x 3 (2 filas y 3 columnas) con todos los elementos a_{ij} = 0.
print(A)
[[0. 0. 0.]
[0. 0. 0.]]
- $np.ones(dimensiones)$: Crea y devuelve una referencia a un array con las dimensiones especificadas en la tupla dimensiones cuyos elementos son todos unos.
Matriz de dimensión 2x3 (2 fila y 3 columnas) con todos sus elementos iguales a 1.
A = np.ones((2,3))
print(A)
[[1. 1. 1.]
[1. 1. 1.]]
Matriz de dimensión 1x3 (1 fila y 3 columnas) con todos sus elementos iguales a 1.
A = np.ones((1,3))
print(A)
[[1. 1. 1.]]
Vector fila (matriz de 1 fila y 3 columnas) con todos sus elementos iguales a 1.
A = np.ones(3)
print(A)
[1. 1. 1.]
Vector columna (matriz de 4 fila y 1 columnas) con todos sus elementos iguales a 1.
A = np.ones((4,1))
print(A)
[[1.]
[1.]
[1.]
[1.]]
- $np.full(dimensiones, valor)$: Crea y devuelve una referencia a un array con las dimensiones especificadas en la tupla dimensiones cuyos elementos son todos valor.
A = np.full((2,4),3.0) # Matriz cuyos elementos son todos iguales a 3.0
print(A)
[[3. 3. 3. 3.]
[3. 3. 3. 3.]]
- $np.identity(n)$: Crea y devuelve una referencia a la matriz identidad de dimensión $n$.
I = np.identity(5) # Matriz identidad de orden n=5.
print(I)
[[1. 0. 0. 0. 0.]
[0. 1. 0. 0. 0.]
[0. 0. 1. 0. 0.]
[0. 0. 0. 1. 0.]
[0. 0. 0. 0. 1.]]
- $np.random.random(dimensiones)$: Crea y devuelve una referencia a un array con las dimensiones especificadas en la tupla dimensiones cuyos elementos son aleatorios.
A = np.random.random((3,2)) # Matriz de orden 3x2 con valores aleatorios entre 0 y 1 por defecto.
print('A=',A)
B = 10*A # Multiplicación de la matriz A por el escalar 10.
print('B=',B) # Matriz de orden 3x2 con valores aleatorios entre 0 y 10.
A= [[0.29944606 0.03828226]
[0.92151849 0.39298975]
[0.35294774 0.92536481]]
B= [[2.99446057 0.38282262]
[9.21518494 3.9298975 ]
[3.52947744 9.25364814]]
- $np.diag(v,k)$: Extrae una diagonal o construye una matriz diagonal.
-
v (vector o matriz)
Si v es una matriz, devuelve una copia de su k-ésima diagonal.
Si v es un vector, devuelve una matriz diagonal con v sobre la k-ésima diagonal. -
k (número entero, opcional)
Diagonal en cuestión. Por defecto es 0.
Usa k > 0 para diagonales sobre la diagonal principal, y k < 0 para diagonales bajo la diagonal principal. -
out (Matriz o vector)
Diagonal extraída o matriz diagonal construida.
-
A = np.random.random((5,5)) # Matriz random de orden 5
d_A = np.diag(A,0) # son los elementos de la diagonal principal de la matriz A.
print(A)
print('v=',d_A)
B = np.diag(d_A) # Crea una matriz diagonal (solo elementos en la diagonal principal) con los elementos de d_A.
print(B)
[[0.19732352 0.25025703 0.25959884 0.48983972 0.14132041]
[0.99847553 0.47422155 0.40698131 0.48891106 0.30007843]
[0.29969325 0.55094652 0.70773012 0.56139925 0.41237901]
[0.74852093 0.35024552 0.94323611 0.82278904 0.55021109]
[0.75295973 0.25838071 0.74783274 0.61744358 0.15099475]]
v= [0.19732352 0.47422155 0.70773012 0.82278904 0.15099475]
[[0.19732352 0. 0. 0. 0. ]
[0. 0.47422155 0. 0. 0. ]
[0. 0. 0.70773012 0. 0. ]
[0. 0. 0. 0.82278904 0. ]
[0. 0. 0. 0. 0.15099475]]
Existen varios atributos y funciones que permiten describir las características de un array. A continuación, se presentan algunas de las más comunes:
-
a.ndim
: Devuelve el número de dimensiones del arraya
. -
a.shape
: Retorna una tupla que indica las dimensiones del arraya
. -
a.size
: Proporciona el número total de elementos en el arraya
. -
a.dtype
: Indica el tipo de datos de los elementos almacenados en el arraya
. -
a.T
: Devuelve la transpuesta del arraya
(intercambia filas por columnas en el caso de matrices).
A = 3.1*np.ones((3,5)) # Matriz de orden 3x5 (3 filas, 5 columnas). Todos sus elementos son iguales a 3.1
print(A)
print(A.size) # número de elementos que tiene la matriz
print(A.shape) # orden de la matriz (3 filas y 5 columnas)
B = np.random.random((5,3))
print(B)
[[3.1 3.1 3.1 3.1 3.1]
[3.1 3.1 3.1 3.1 3.1]
[3.1 3.1 3.1 3.1 3.1]]
15
(3, 5)
[[0.42394896 0.42837491 0.89547643]
[0.12416299 0.27471687 0.21652912]
[0.79961267 0.11090453 0.44186001]
[0.65961756 0.50919244 0.27390606]
[0.20697892 0.63413266 0.4020175 ]]
print(B.T)
[[0.42394896 0.12416299 0.79961267 0.65961756 0.20697892]
[0.42837491 0.27471687 0.11090453 0.50919244 0.63413266]
[0.89547643 0.21652912 0.44186001 0.27390606 0.4020175 ]]
Acceso y modificación de los elementos
Para acceder a los elementos de un vector o una matriz, utilizamos la siguiente sintaxis.
Por ejemplo, si tenemos el vector:
v = [1, 3, 5, 2]
v[0]
representa la primera componente del vectorv
y devolverá el valor1
.v[3]
representa la cuarta componente del vectorv
y devolverá el valor2
.
Es importante recordar que en Python los índices comienzan en 0
, lo que significa que el primer elemento tiene índice 0
, el segundo elemento tiene índice 1
, y así sucesivamente.
v = np.random.random(4) # vector de 4 componentes generado aleatoriamente.
print(v)
[0.56554423 0.7158947 0.23732554 0.39578333]
print(v[0]) # primera componente del vector v.
0.5655442286233147
print(v[3]) # Cuarta componente del vector v.
0.3957833287291599
Podemos cambiar el valor de un elemento de un vector o matriz asignando un nuevo valor.
Por ejemplo, si tenemos el vector:
v = [1, 3, 5, 2]
Podemos modificar la tercera componente (índice 2
) asignándole un nuevo valor:
v[2] = 10
Después de esta asignación, el vector v
será:
v = [1, 3, 10, 2]
print(v) # vector original
[0.56554423 0.7158947 0.23732554 0.39578333]
v[2] = np.pi
print(v) # vector con la tercera componente igual a pi.
[0.56554423 0.7158947 3.14159265 0.39578333]
En forma análoga, podemos acceder a los elementos de una matriz utilizando la siguiente sintaxis:
A[i,j]
(fila i
, columna j
).
Por ejemplo, si tenemos la matriz:
A = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
A[0, 1]
devolverá el elemento de la primera fila y la segunda columna, es decir,2
.A[2, 2]
devolverá el elemento de la tercera fila y la tercera columna, es decir,9
.
Recuerda que, al igual que con los vectores, los índices en Python comienzan en 0
.
A = np.random.random((3,5))
print(A)
[[0.93974559 0.05350414 0.79262227 0.22552793 0.1799146 ]
[0.00175417 0.44495108 0.19229064 0.05121848 0.49654071]
[0.93650049 0.6865986 0.45940217 0.67444161 0.88872908]]
print(A[0,0]) # Elemento a_11 (fila 1 columna 1).
0.9397455885358104
print(A[2,3]) # Elemento de la fila 3 columna 4.
0.6744416056849745
Podemos cambiar un elemento de la matriz $A$ utilizando la siguiente sintaxis:
A[i,j] = b
Por ejemplo, si queremos cambiar el elemento de la segunda fila y tercera columna a 10
, lo hacemos así:
A[1, 2] = 10
Además, también podemos extraer elementos de la matriz $A$ de la siguiente manera:
-
Un elemento específico:
Por ejemplo,A[0, 1]
devuelve el elemento de la primera fila y segunda columna. -
Una fila completa:
UsandoA[i, :]
, dondei
es el índice de la fila. -
Una columna completa:
UsandoA[:, j]
, dondej
es el índice de la columna.
Por ejemplo, si tenemos:
A = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
A[1, :]
devolverá[4, 5, 6]
(segunda fila completa).A[:, 2]
devolverá[3, 6, 9]
(tercera columna completa).
print(A)
[[0.93974559 0.05350414 0.79262227 0.22552793 0.1799146 ]
[0.00175417 0.44495108 0.19229064 0.05121848 0.49654071]
[0.93650049 0.6865986 0.45940217 0.67444161 0.88872908]]
A[2,3] = 0 # Cambié el elemento de la fila 3 columna 4 por un 0.
print(A)
[[0.93974559 0.05350414 0.79262227 0.22552793 0.1799146 ]
[0.00175417 0.44495108 0.19229064 0.05121848 0.49654071]
[0.93650049 0.6865986 0.45940217 0. 0.88872908]]
B = A[:,2] # Extraemos toda la información correspondiente a la columna 3 (todas las filas (:), columna 3).
print(B)
[0.79262227 0.19229064 0.45940217]
B = A[0:2,3] # Extraemos toda la información correspondiente a la fila 1 hasta la 2, columna 4.
print(B)
[0.22552793 0.05121848]
B = A[2,:] # Extraemos toda la información correspondiente a la fila 3.
print(B)
[0.93650049 0.6865986 0.45940217 0. 0.88872908]
Operaciones matemáticas con arrays a nivel de elemento a elemento
Las operaciones a nivel de elemento se aplican a los elementos que ocupan la misma posición en dos arrays
. Por lo tanto, es necesario que ambos arrays
tengan las mismas dimensiones. El resultado será un array
con las mismas dimensiones que los originales.
Los operadores matemáticos +
, -
, *
, /
, %
y **
se utilizan para realizar las siguientes operaciones a nivel de elemento:
+
: Suma elemento a elemento.-
: Resta elemento a elemento.*
: Producto elemento a elemento./
: División elemento a elemento.%
: Cálculo del resto elemento a elemento.**
: Potenciación elemento a elemento.
A = np.ones((2,3))
B = np.random.random((2,3))
print(A)
print(B)
[[1. 1. 1.]
[1. 1. 1.]]
[[0.39344805 0.72132887 0.53187417]
[0.76542712 0.76330354 0.65035085]]
print(A+B) # Suma elemento a elemento
[[1.39344805 1.72132887 1.53187417]
[1.76542712 1.76330354 1.65035085]]
Es importante aclarar que la operación A * B
no realiza el producto matemático tradicional de matrices. En su lugar, aplica el producto elemento a elemento entre los arrays A
y B
. Esto significa que cada elemento de A
se multiplica por el elemento correspondiente de B
en la misma posición.
De manera similar, si A
y B
son vectores, la operación A * B
tampoco calcula el producto escalar o vectorial. En cambio, realiza una multiplicación elemento a elemento entre los dos vectores.
Por ejemplo, si tenemos:
A = [
[1, 2],
[3, 4]
]
B = [
[5, 6],
[7, 8]
]
C = A * B
El resultado será:
C = [
[1*5, 2*6],
[3*7, 4*8]
]
Esto dará como resultado:
C = [
[5, 12],
[21, 32]
]
Para realizar el producto matemático tradicional de matrices, es necesario usar la función np.dot(A, B)
o el operador @
en Python.
print(A/B) # División elemento a elemento.
[[2.54163163 1.3863302 1.88014393]
[1.3064601 1.3100948 1.53763158]]
print(B**2) # Esto no es B*B. Aquí cada elemento de B se eleva a 2.
[[0.15480136 0.52031534 0.28289014]
[0.58587868 0.5826323 0.42295622]]
Tipos de Operadores en Python
En Python, los operadores se clasifican en varias categorías dependiendo de su propósito. A continuación se presentan los principales tipos:
Operadores Aritméticos
Se usan para realizar operaciones matemáticas básicas.
Operador | Descripción | Ejemplo | Resultado |
---|---|---|---|
+ |
Suma | 5 + 3 |
8 |
- |
Resta | 5 - 3 |
2 |
* |
Multiplicación | 5 * 3 |
15 |
/ |
División | 5 / 3 |
1.6667 |
% |
Módulo (resto) | 5 % 3 |
2 |
** |
Potenciación | 5 ** 3 |
125 |
// |
División entera | 5 // 3 |
1 |
Operadores Relacionales
Se usan para comparar valores y retornan un valor booleano (True
o False
).
Operador | Descripción | Ejemplo | Resultado |
---|---|---|---|
< |
Menor que | 5 < 3 |
False |
<= |
Menor o igual que | 5 <= 5 |
True |
> |
Mayor que | 5 > 3 |
True |
>= |
Mayor o igual que | 5 >= 6 |
False |
== |
Igualdad | 5 == 3 |
False |
!= |
Diferente | 5 != 3 |
True |
Operadores Lógicos
Se usan para combinar condiciones lógicas.
Operador | Descripción | Ejemplo | Resultado |
---|---|---|---|
and |
AND lógico | (5 > 3) and (5 < 10) |
True |
or |
OR lógico | (5 > 3) or (5 > 10) |
True |
not |
NOT lógico | not(5 > 3) |
False |
Para el trabajo con vectores (por ejemplo, arrays de numpy
) usar:
Operador | Nombre | Uso | Ejemplo | Descripción |
---|---|---|---|---|
& |
AND lógico | (cond1) & (cond2) |
(v > 0.1) & (v < 0.4) |
Retorna True si ambas condiciones son verdaderas. |
\| |
OR lógico | (cond1) \| (cond2) |
(v < 0.1) \| (v > 0.4) |
Retorna True si al menos una de las condiciones es verdadera. |
~ |
NOT lógico | ~(cond) |
~(v < 0.4) |
Invierte el resultado lógico de la condición (True ↔ False ). |
Operadores de Asignación
Se usan para asignar valores a variables, con combinaciones de operaciones.
Operador | Descripción | Ejemplo | Resultado |
---|---|---|---|
= |
Asignación simple | x = 5 |
x = 5 |
+= |
Suma y asignación | x += 3 |
x = x + 3 |
-= |
Resta y asignación | x -= 2 |
x = x - 2 |
*= |
Multiplicación y asignación | x *= 4 |
x = x * 4 |
/= |
División y asignación | x /= 2 |
x = x / 2 |
//= |
División entera y asignación | x //= 3 |
x = x // 3 |
%= |
Módulo y asignación | x %= 2 |
x = x % 2 |
**= |
Potencia y asignación | x **= 2 |
x = x ** 2 |
&= |
AND bit a bit y asignación | x &= 2 |
x = x & 2 |
\|= |
OR bit a bit y asignación | x |= 2 |
x = x | 2 |
^= |
XOR bit a bit y asignación | x ^= 3 |
x = x ^ 3 |
<<= |
Desplazamiento izquierda y asignación | x <<= 2 |
x = x << 2 |
>>= |
Desplazamiento derecha y asignación | x >>= 1 |
x = x >> 1 |
Operadores de Identidad
Se usan para verificar si dos objetos son iguales (mismo objeto en memoria).
Operador | Descripción | Ejemplo | Resultado |
---|---|---|---|
is |
Verifica identidad | x is y |
True o False |
is not |
Verifica no identidad | x is not y |
True o False |
Operadores de Pertenencia
Se usan para verificar si un valor está presente en una colección.
Operador | Descripción | Ejemplo | Resultado |
---|---|---|---|
in |
Verifica pertenencia | "a" in "abc" |
True |
not in |
Verifica no pertenencia | "x" not in "abc" |
True |
print(2<3)
True
print(5!=1)
True
print(6==3)
False
v = np.random.random(4)
print(v)
print(v>0.4)
[0.81370763 0.59142879 0.46424298 0.66206272]
[ True True True True]
# Uso con vectores y matrices
v = np.array([0.2, 0.05, 0.6, 0.9])
# AND lógico (&): Elementos entre 0.1 y 0.5
and_result = (v > 0.1) & (v < 0.5)
print("AND lógico: (v > 0.1) & (v < 0.5)")
print(and_result) # Resultado: [ True False False False]
# OR lógico (|): Elementos menores a 0.1 o mayores a 0.5
or_result = (v < 0.1) | (v > 0.5)
print("\nOR lógico: (v < 0.1) | (v > 0.5)")
print(or_result) # Resultado: [False True True True]
# NOT lógico (~): Elementos que NO son menores a 0.4
not_result = ~(v < 0.4)
print("\nNOT lógico: ~(v < 0.4)")
print(not_result) # Resultado: [ True False True True]
AND lógico: (v > 0.1) & (v < 0.5)
[ True False False False]
OR lógico: (v < 0.1) | (v > 0.5)
[False True True True]
NOT lógico: ~(v < 0.4)
[False False True True]
Estructuras de control de flujo
Ciclo for en python
El ciclo for se utiliza para recorrer los elementos de un objeto iterable (lista, tupla, conjunto, diccionario, vectores, matrices) y ejecutar un bloque de código. En cada paso de la iteración se tiene en cuenta a un único elemento del objeto iterable, sobre el cuál se pueden aplicar una serie de operaciones.
Su sintaxis es la siguiente:
for <elem> in <iterable>:
<Tu código>
Aquí, $elem$ es la variable que toma el valor del elemento dentro de $iterable$ en cada paso del bucle. Este finaliza su ejecución cuando se recorren todos los elementos.
nums = [4, 5, 3, 25]
for n in nums:
print(n)
4
5
3
25
a = np.arange(0,5,1) # Vector de enteros. Estas serán las posiciones de los elementos del vector b
print(a)
b = np.zeros(a.size) # Defino el vector b del mismo tamaño que el vector a pero con elementos todos iguales a 0.
for i in a:
b[i] = i**2 + 2 # Lleno componente a componente el vector b.
print(b)
[0 1 2 3 4]
[ 2. 3. 6. 11. 18.]
Sentencias if else
“Cuando la expresión if se evalúa como True, entonces ejecuta el código que le sigue. Pero si se evalúa como False, entonces ejecuta el código que sigue después de la sentencia else .”
Su sintaxis es la siguiente:
if condicion:
ejecutar codigo si la condicion es True
else:
ejecutar codigo si la condicion es False
a = np.pi
b = np.exp(1)
if a < b:
print(" b es mayor que a")
else:
print("a es mayor que b")
a es mayor que b
coleccion = [2, 4, 5, 7, 8, 9, 3, 4]
for e in coleccion: # Note el uso del operador de identidad `is`
if e == 7:
break # Break permite salir del ciclo for.
print(e)
2
4
5
coleccion = [2, 4, 5, 7, 8, 9, 3, 4]
for e in coleccion:
if e <= 7:
print('True')
else:
print('False')
True
True
True
True
False
False
True
True
Sentencia elif
La sintaxis básica es similar a la siguiente:
if primera_condicion:
ejecutar sentencia
elif segunda_condicion:
ejecutar sentencia
else:
ejecutar sentencia alternativa si todas las condiciones previas son son evaluadas como False
x = 11
if x > 10:
print(" x es mayor que 10!")
elif x < 10:
print("x es menor que 10!")
elif x < 20 :
print("x es menor que 20!")
else:
print("x es igual a 10")
x es mayor que 10!
x = 20
if x > 10 and x < 20:
print(" 10 < x < 20")
elif x <= 10:
print("x <= 10")
else:
print("x >= 20")
x >= 20
Bucle while de Python
El bucle while de Python hace que se ejecute un bloque de código repetidamente mientras una condición sea verdadera. En Python, los bucles while se utilizan principalmente cuando el número de iteraciones necesarias no viene determinado de antemano.
i = 1
while i < 6:
print(i)
if i == 3:
break
i = i + 1
1
2
3
Funciones en Python
Las funciones son una herramienta fundamental en Python que te permiten estructurar y organizar tu código de forma más eficiente. Una de sus principales ventajas es que ayudan a reducir el número total de líneas de código en tu proyecto, mejorando su legibilidad y mantenimiento.
En Python, una definición de función tiene las siguientes características:
- La palabra clave
def
para indicar que estás definiendo una función. - Un nombre de función que describe su propósito.
- Paréntesis
()
, dentro de los cuales se pueden incluir los parámetros de entrada (opcionales). - Dos puntos
:
para indicar el inicio del bloque de código de la función. - Un bloque de código con las instrucciones a ejecutar.
- Una sentencia de retorno
return
(opcional), que especifica el valor que la función devolverá.
Sintaxis básica:
def nombre_funcion():
# Aquí va el algoritmo
# Más instrucciones
return # Retorno opcional
def multiplicacion(input1, input2):
y = input1 * input2
return y
result = multiplicacion(3,5)
print(result)
15
def area_circulo(radio):
"""
Calcula el área de un círculo dado su radio.
Parámetros:
radio (float): El radio del círculo.
Retorna:
float: El área del círculo.
"""
if radio < 0:
raise ValueError("El radio no puede ser negativo.")
return np.pi * radio**2 # Fórmula: π * r^2
area_c = area_circulo(2)
print(area_c)
12.566370614359172
Fibonacci con la Fórmula de Binet
Aquí calculamos el n-ésimo término en la secuencia de Fibonacci utilizando la famosa Fórmula de Binet.
Secuencia de Fibonacci
La secuencia de Fibonacci es una sucesión matemática en la que cada número es la suma de los dos anteriores. Se define como:
$ F(0) = 0, \quad F(1) = 1, \quad F(n) = F(n-1) + F(n-2) \; \text{para } n \geq 2 $
Fórmula de Binet
La fórmula de Binet permite calcular directamente el valor de ( F(n) ) sin necesidad de realizar un bucle. Está definida como:
$ F(n) = \frac{\phi^n - \psi^n}{\sqrt{5}} $
Donde:
- $\phi = \frac{1 + \sqrt{5}}{2}$ es el número áureo.
- $\psi = \frac{1 - \sqrt{5}}{2}$ es el complemento.
def fibonacci_binet(n):
"""
Calcula el n-ésimo término de Fibonacci usando la fórmula de Binet.
Parámetros:
n (int): El índice del número de Fibonacci a calcular (debe ser >= 0).
Retorna:
int: El n-ésimo número de Fibonacci.
"""
if n < 0:
raise ValueError("El índice n debe ser un número entero no negativo.")
# Cálculo de Fibonacci usando la fórmula de Binet
phi = (1 + np.sqrt(5)) / 2 # Número áureo (phi)
psi = (1 - np.sqrt(5)) / 2 # Complemento
fibonacci = (phi**n - psi**n) / np.sqrt(5)
return round(fibonacci) # Redondeamos al entero más cercano
# Ejemplo de uso
n = 10
fibo_num = fibonacci_binet(n)
print(f"El {n}-ésimo término de Fibonacci es: {fibo_num}")
El 10-ésimo término de Fibonacci es: 55
Taller de Modelamiento matemático y fenómenos de evolución
- Construya una función en python que evalúe la función [3 pts.] $$f(x)= \begin{cases}2 \operatorname{sen}^{2}(2 x), & x \leq 0, \\ 1-\mathrm{e}^{-x}, & x>0.\end{cases}$$ Indicación: Dado un vector $x$, su función debe evaluar $f$ en cada elemento de $x$. La función debe retornar un vector $y$ del mismo tamaño con la evaluación de $f$ en cada $x_i$.
- Investigue la librería matplotlib y úsela para gráficar la función $f$ del problema 1. en el intervalo $[-5, 6]$. [3 pts.]
- Construya una función en Python, que evalúe la función: [4 pts.] $$f(x)=\begin{cases} x-1, & x \leq -2, \\ 1-x^2, & -2 < x < 0, \\ -\displaystyle\frac{1}{x+1}, & x \geq 0 \end{cases}$$ Grafique la función $f$ en $[-6,10]$.
- Construya una función que reciba como entrada $n$ y que genere una matriz de la forma [10 pts.] $$\boldsymbol{A}=\left(\begin{array}{cccc}2 & -1 & & 0 \\ -1 & \ddots & \ddots & \\ & \ddots & \ddots & -1 \\ 0 & & -1 & 2\end{array}\right) \in \mathbb{R}^{n \times n}.$$ Indicación: La matriz $A$ es una matriz tridiagonal, solo tiene información distinta de 0 en las tres diagonales. En el resto de posiciones los coeficientes son iguales a 0.
- Haga una función que reciba como entrada $n$, $varepsilon$ y $\alpha$, que genere una matriz de la forma [10 pts.] $$ A=\left(\begin{array}{cc} \alpha \mathbf{I} & \varepsilon \mathbf{1} \\ \varepsilon \mathbf{1} & \alpha \mathbf{I} \end{array}\right) \in \mathbb{R}^{2 n \times 2 n}, $$ donde $\mathbf{1}$ denota la matriz de elementos todos 1 . $\mathbf{I}$ denota a la matriz identidad de $\mathbb{R}^{n \times n}, \alpha, \varepsilon$ y $n$ deben ser parámetros de la función.
- Haga una función que reciba como entrada $n$ y que genere una matriz de la forma [10 pts.] $$ A=\left(\begin{array}{ccc} 2 n & & \mathbf{1}\\ & \ddots & \\ \mathbf{1} & & 2 n \end{array}\right) \in \mathbb{R}^{2 n \times 2 n} $$ donde $\mathbf{1}$ indica que los elementos fuera de la diagonal principal de la matriz $A$ son unos. Haga una función que genere una matriz de la forma
- a) Diseñe una función en Python que reciba como entrada el orden $n$ de una matriz simétrica cuyas entradas son definidas por: [5 pts.] \[ A_{ij} = \begin{cases} i + j, & \text{si } i \neq j, \\ 2i, & \text{si } i = j. \end{cases} \] b) Análogamente, construya una función en Python que dado $n$ entregue la matriz $E \in \mathbb{R}^{n \times n}$ donde cada entrada $E_{ij}$ se defina como: [5 pts.] \[ E_{ij} = i^2 - j^2. \]
-
Usando la fórmula: [10 pts.]
\[ \frac{\sin(x + h) - \sin(x)}{h}, \] aproxime la derivada de $\sin(x)$ (es decir, $\cos(x)$) en $x = 0.5$, usando $h = 10^{-p}$ para $p = 1, \ldots, 10$ y calcule el error al usar esta aproximación.