Introducción a Integrales

Autor/a

Israel Varona, Lab25

Video

Introducción

Un entendimiento, al menos intuitivo, del concepto de la integral es fundamental para el cálculo y la ciencia en general. Dado esto, uno puede preguntarse cuál es su utilidad o qué representa. Una intengral no es otra cosa que el cáclulo de un área, pero no de cualquier área, sino el área que podemos encontrar debajo de una curva descrita por una función y delimitada en cierto intervalo.

En ciencia, encontrar el área debajo de una curva puede ser una tarea más común de lo que parece. En física, una función de velocidad cuya variable de entrada sea el tiempo describe una curva cuya área es la distancia recorrida en dicho tiempo. En probabilidad, una función de densidad de probabilidad describe una curva cuya área delimitada por un intervalo es la probabilidad de que una variable aleatoria tome un valor de dicho intervalo. En psicología también existen modelos matemáticos en donde se precisa de estimar el área descrita por una curva, pero es conveniente primero aprender como calcular dicha área.

Sumatoria de Riemann

Imagina una función constante como la siguiente:

Haz Clic para ver el Código
```{python}
#@title Código
import matplotlib as mpl
import matplotlib.pyplot as plt
import ipywidgets as ipw

plt.figure(figsize=(15,8))
ax = plt.subplot()
plt.xlim(-5, 15)
plt.ylim(0, 40)

def f(x):
  return 20

x = range(-5, 16)

plt.plot(x, [f(i) for i in x], color="red")
plt.show()
```

En este tipo de funciones no importa cual sea la variable de entrada, la variable de salida siempre será la misma, una constante.

Ahora imagina que se requiere de calcular el área debajo la “curva” que describe esta función desde el valor x = 2.5 hasta x = 12.5.

Haz Clic para ver el Código
```{python}
#@title Código
plt.figure(figsize=(15, 8))
ax = plt.subplot()
plt.xlim(-5, 15)
plt.ylim(0, 40)

def f(x):
  return 20

x = range(-5, 16)
m = range(0, 21)

plt.plot(x, [f(i) for i in x], color="red")
plt.plot([2.5 for i in m], m, color="black")
plt.plot([12.5 for i in m], m, color="black")
plt.show()
```

Esto es sumamente sencillo, pues solo requerimos de calcular el área de un rectángulo. Al multiplicar la base, 10, por la altura, 20, obtenemos 200 unidades cuadradas. Sin embargo, no siempre (más bien, casi nunca) será así de sencillo. Imaginemos que nuestra función no es una función constante, sino una función exponencial. ¿Cómo calcularíamos su área en el mismo intervalo?

Haz Clic para ver el Código
```{python}
#@title Código
def f0(x):
  return (1.27 ** x) + 5

plt.figure(figsize=(15, 8))
axes = plt.subplot()
plt.xlim(-5, 15)
plt.ylim(0, 40)

x = range(-5, 16)
a = range(int(f0(5)))
b = range(int(f0(12.75)))

plt.plot(x, [f0(i) for i in x], color="red")
plt.plot([2.5 for i in a], a, color="black")
plt.plot([12.5 for i in b], b, color="black")
plt.show()
```

Calcular el área de una figura con lados curvos no es una tarea sencilla. Un buen primer paso es intentar dar una aproximación de dicha área. Para lograr esto, nos podemos auxiliar de algo que ya conocemos: el área de un rectángulo. Por lo tanto, trazaremos un rectángulo cuya base sea la longitud del intervalo y la altura sea el valor de la función evaluada en 12.5:

Haz Clic para ver el Código
```{python}
#@title Código
plt.figure(figsize=(15, 8))
axes = plt.subplot()
plt.xlim(-5, 15)
plt.ylim(0, 40)

plt.plot(x, [f0(i) for i in x], color="black")

axes.add_patch(mpl.patches.Rectangle((2.5, 0), 10, f0(12.5), edgecolor="black", facecolor="darksalmon"))

area = 10 * f0(12.5)
plt.text(-3, 30, "Área = " + str(area), size="xx-large")
plt.show()
```

Nuestra aproximación está hecha, pero es sumamente mala. Gran parte de nuestro rectángulo sobrepasa la curva, por lo que una buena proporción de nuestra área predicha está de sobra. Necesitamos hacer algo más. ¿Qué puede ser mejor que un rectángulo? Exacto, dos rectángulos, así que dividiremos en dos el intervalo y haremos un rectángulo con cada segmento. La altura de cada rectángulo será el valor de la función evaluada en el valor que resulte en dividir el intervalo en 2, que es 7.5, para el primer rectángulo y 12.5 para el segundo.

Haz Clic para ver el Código
```{python}
#@title Código
plt.figure(figsize=(15, 8))
axes = plt.subplot()
plt.xlim(-5, 15)
plt.ylim(0, 40)

plt.plot(x, [f0(i) for i in x], color="black")

axes.add_patch(mpl.patches.Rectangle((2.5, 0), 5, f0(7.5), edgecolor="black", facecolor="darksalmon"))
axes.add_patch(mpl.patches.Rectangle((7.5, 0), 5, f0(12.5), edgecolor="black", facecolor="darksalmon"))

area = (5 * f0(7.5)) + (5 * f0(12.5))
plt.text(-3, 30, "Área = " + str(area), size="xx-large")
plt.show()
```

Es evidente que nuestra aproximación mejoró, pues una parte de ese excedente de nuestro primer intento se ha ido, ¿pero qué sucedera cuando ahora, en lugar de dividir el intervalo en dos y hacer dos rectángulos, hagamos cuatro de ellos? Seguiremos el mismo método para trazar los rectángulos que ya hemos ocupado y obtendremos lo siguiente:

Haz Clic para ver el Código
```{python}
#@title Código
plt.figure(figsize=(15, 8))
axes = plt.subplot()
plt.xlim(-5, 15)
plt.ylim(0, 40)

plt.plot(x, [f0(i) for i in x], color="black")

axes.add_patch(mpl.patches.Rectangle((2.5, 0), 2.5, f0(5), edgecolor="black", facecolor="darksalmon"))
axes.add_patch(mpl.patches.Rectangle((5, 0), 2.5, f0(7.5), edgecolor="black", facecolor="darksalmon"))
axes.add_patch(mpl.patches.Rectangle((7.5, 0), 2.5, f0(10.5), edgecolor="black", facecolor="darksalmon"))
axes.add_patch(mpl.patches.Rectangle((10, 0), 2.5, f0(12.5), edgecolor="black", facecolor="darksalmon"))

area = (2.5 * f0(5)) + (2.5 * f0(7.5)) + (2.5 * f0(10)) + (2.5 * f0(12.5))
plt.text(-3, 30, "Área = " + str(area), size="xx-large")
plt.show()
```

Tal parece que nuestra predicción mejoró aún más, lo cual sugiere que entre más rectángulos tengamos, más precisa será nuestra estimación.

En la siguiente gráfica podras poner a prueba la afirmación anterior. Desplaza el widget para manipular el número de rectángulos a ocupar y observa como el error de la predicción disminuye cada vez más.

Haz Clic para ver el Código
```{python}
#@title Código
def f1(n):
  plt.figure(figsize=(15, 8))
  axes = plt.subplot()
  plt.xlim(-5, 15)
  plt.ylim(0, 40)
  plt.plot(x, [f0(i) for i in x], color="black")

  rectangulos = range(n)
  area = 0
  
  for rectangulo in rectangulos:
    axes.add_patch(mpl.patches.Rectangle(
        ((2.5 + ((10/n) * rectangulo)), 0), 
        (10/n), 
        f0(2.5 + ((10/n) * (rectangulo + 1))), 
        edgecolor="black", 
        facecolor="darksalmon"
    ))
    area += (10/n) * f0(2.5 + ((10/n) * (rectangulo + 1)))
  plt.text(-3, 30, "Área = " + str(area), size="xx-large")

plot = ipw.interactive(f1, n=(5, 200, 15))
plot
```

Esto confirma nuestra afirmación. Ahora, ¿qué pasaría si en lugar de tener solo 200 rectángulos, tuvieramos un número tan grande de ellos que sería equivalente a tener rectángulos infinitos? Esta es la idea detrás de la sumatoria de Riemann:

\(\displaystyle \lim_{n \to \infty}\sum_{i=1}^{n}f(x_{i})\tfrac{b-a}{n}\)

Dicha sumatoria nos permite calcular una suma compuesta de una cantidad infinita de áreas de rectángulos, lo cual, como ya vimos, nos da una aproximación bastante certera del área bajo la curva y también dicha sumatoria es a lo que conocemos como una integral definida de la función f en el intervalo que va desde a hasta b.

\(\int_{a}^{b}f(x)dx = \displaystyle \lim_{n \to \infty}\sum_{i=1}^{n}f(x_{i})\tfrac{b-a}{n}\) donde \(x_{1}\) es igual a \(a\).

Un ejemplo en psicología: modelo matemático de acumulación de excitación en conducta adjuntiva.

En 1961, Falk descubrió que las ratas que estaban siendo reforzadas en programas intermitentes con comida mostraban un consumo de agua excesivo, casi de la mitad de su peso en tres horas de exposición al programa. A este tipo de conducta se le llamó conducta adjuntiva y fue encontrada en otras especies, con otras topografías y con otros tipos de reforzadores. Esto representó un reto para el análisis experimental de la conducta, pues estas conductas no tenían sentido bajo su marco teórico. En 1975, Peter Killeen propuso una explicación a este fenómeno: estas conductas formaban parte del repertorio común del organismo, pero su aparición supranormal era producto de un incremento en el nivel de exitación producto de la entrega periodica de reforzadores. Además, si la entrega de reforzadores no era tan alejada temporalmente, esta excitación se acumulaba. Propuso un modelo matemático en el que para obtener el nivel de excitación acumulado en un determinado ensayo o entrega de reforzador, se debía integrar una función:

\(\bar{A}_{n} = \int_{0}^{T}\frac{A_{1}(1-e^{\frac{-nT}{\alpha}})e^{\frac{-t}{\alpha}}}{e^{\frac{-T}{\alpha}}}dt\)

lo cual nos daba la siguiente expresión general:

\(\bar{A}_{n} = \frac{A_{1}\alpha}{T}(1-e^{\frac{-nT}{\alpha}})\).

En dicha expresión:

  • \(\alpha\) representa el tiempo que se requiere para que la excitación decaiga a su valor inicial en minutos.
  • \(A_{1}\) representa el nivel de excitación en el primer ensayo operacionalizado como respuestas por minuto.
  • \(n\) es el número de ensayo o reforzador.
  • \(T\) es el intervalo entre reforzadores en minutos.

Al sustituir valores en esta última expresión se puede encontrar el nivel de excitación en cualquier ensayo. En la siguiente gráfica interactiva los widgets permiten manipular estos valores. Los correspondientes a \(\alpha\), \(A\) y \(T\) determinan la forma de la función, mientras que \(n\), el ensayo del que queremos saber el nivel de excitación, controla un punto rojo que se desplaza a lo largo de la función mostrando el nivel de excitación en ese ensayo.

Haz Clic para ver el Código
```{python}
#@title Código
e = 2.72
def f2(Alfa, A, n, T):
  Arousal = ((A * Alfa) / T) * (1 - e ** ((-n * T) / Alfa))
  return Arousal

n_reforzador = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

def f3(Alfa, A, n, T):
  plt.figure(figsize=(15,8))
  axes = plt.subplot()
  plt.xlim(0, 14)
  plt.ylim(0, 200)
  plt.xlabel("Número de incentivo", labelpad=15, size="large")
  plt.ylabel("Excitación (Respuestas/minuto)", labelpad=15, size="large")
  plt.plot(n_reforzador, [f2(Alfa, A, i, T) for i in n_reforzador], color="black")
  plt.scatter(n, f2(Alfa, A, n, T), color="red")

plot1 = ipw.interactive(f3, Alfa=(3, 9, 1), A=(4, 16, 0.3), n=(0, 14, 1), T=(0.25, 5, 0.25))
plot1
```

Referencias.

  • Killeen, P. (1975). On the temporal control of behavior. Psychological Review, 82(2), 89–115. doi:10.1037/h0076820
  • Killeen, P. R., Hanson, S. J., & Osborne, S. R. (1978). Arousal: Its genesis and manifestation as response rate. Psychological Review, 85(6), 571–581. doi:10.1037/0033-295x.85.6.571
  • Killeen, P. R., & Sitomer, M. T. (2003). MPR. Behavioural Processes, 62(1-3), 49–64. doi:10.1016/s0376-6357(03)00017-2
  • Stewart, J. (2008). Cálculo de una variable: Trascendetes tempranas (6a Ed.). Cengage Learning.