Dinámica

Capítulo 1: Cinemática y Cinética de partículas

Movimiento rectilíneo

2021/02

MEDELLÍN - COLOMBIA

 Text provided under a Creative Commons Attribution license, CC-BY. All code is made available under the FSF-approved MIT license.(c) Carlos Alberto Alvarez Henao

***

***Docente:*** Carlos Alberto Álvarez Henao, I.C. D.Sc.

***e-mail:*** carlosalvarezh@gmail.com

***skype:*** carlos.alberto.alvarez.henao

***Linkedin:*** https://www.linkedin.com/in/carlosalvarez5/

***github:*** https://github.com/carlosalvarezh/Dinamica

***Herramienta:*** [Jupyter](http://jupyter.org/)

***Kernel:*** Python 3.9

***

Tabla de Contenidos

1  Dinámica

1.1  Ubicación de la dinámica en la Física

1.2  Definiciones

1.3  Estrategia para la solución de problemas

2  Cinemática rectilínea - Movimiento continuo

2.1  Consideraciones

2.2  Posición

2.3  Desplazamiento

2.4  Velocidad

2.5  Aceleración

2.6  Aceleración constante

2.6.1  Velocidad como función del tiempo

2.6.2  Posición como función del tiempo

2.6.3  Velocidad como función de la posición

2.6.4  Observaciones

2.7  Recapitulando

2.8  Ejemplos

2.8.1  Desplazamiento rectilíneo de un Automovil

2.8.2  Altura máxima cohete

2.8.3  Partícula en campo magnético

3  Cinemática rectilínea: Movimiento variable

3.1  Gráficas de $s-t$, $v-t$ y $a-t$

3.2  Gráficas de $v-s$ y $a-s$

3.3  Ejemplos

3.3.1  Desplazamiento en bicicleta

 Fuente: Engineer4Free

***Introducción***

Estas notas son extraídas principalmente de los textos de Dinámica de [Hibbeler](https://www.pearson.com/us/higher-education/product/Hibbeler-Engineering-Mechanics-Dynamics-14th-Edition/9780133915389.html) y [Beer&Johnston](https://www.amazon.com/Vector-Mechanics-Engineers-Ferdinand-Beer/dp/0077402324), así como también de la revisión de extensa literatura en internet. Las referencias se indicarán en cada apartado. Se hace uso de la herramienta [Jupyter Notebook](https://jupyter.org/) empleando el lenguaje de programación [python](https://python.org/) en la versión estable más reciente

## Dinámica

Parte de la física que estudia la relación existente entre las fuerzas que actúan sobre un cuerpo y los efectos que se producirán sobre el movimiento de ese cuerpo.

 Fuente: Engineer4Free

### Ubicación de la dinámica en la Física

 Fuente: Wikisabio

### Definiciones

- ***Mecánica:*** Se ocupa del estado de reposo o movimiento de cuerpos sometidos a la acción de fuerzas.

- ***Estática:*** Se ocupa del equilibrio de un cuerpo que está en reposo o que se mueve con velocidad constante.

- ***Dinámica:*** Se ocupa del movimiento acelerado de un cuerpo.

- ***Cinemática:*** Trata sólo los aspectos geométricos del movimiento.

- ***Cinética:*** Analiza las fuerzas que provocan el movimiento.

Para desarrollar estos principios, primero se analizará la dinámica de una partícula, y a continuación se abordarán temas de dinámica de un cuerpo rígido en dos y luego en tres dimensiones.

### Estrategia para la solución de problemas

- Lea el problema con cuidado y trate de correlacionar la situación física real con la teoría que haya estudiado.

- Trace todos los diagramas necesarios y tabule los datos del problema.

- Establezca un sistema de coordenadas y aplique los principios pertinentes, casi siempre en forma matemática.

- Resuelva de manera algebraica las ecuaciones necesarias hasta donde sea práctico; luego, utilice un conjunto consistente de unidades y complete la solución numéricamente. Reporte la respuesta sin más cifras significativas que la precisión de los datos dados.

- Estudie la respuesta con juicio técnico y sentido común para determinar si parece o no razonable.

- Una vez completadas las soluciones, repase el problema. Trate de pensar en otras formas de obtener la misma solución.

## Cinemática rectilínea - Movimiento continuo

### Consideraciones

 Fuente: Pinterest

- Los cuerpos se consideran de tamaño finito, como partícula, y el movimiento del cuerpo como un todo se caracteriza por el movimiento de su centro de masa, sin rotación.

- Se considera la partícula con masa, y su tamaño y forma son indiferentes.

- Se presenta la partícula moviéndose a lo largo de una trayectoria rectilínea.

- La cinemática de una partícula se caracteriza al especificar, en cualquier instante, su posición, desplazamiento, velocidad y aceleración.

### Posición

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

La trayectoria rectilínea de una partícula se definirá por medio de un solo eje de coordenadas $s$.

El origen $O$ en la trayectoria es un punto fijo, y a partir de él se utiliza la coordenada de posición s para especificar la ubicación de la partícula en cualquier instante dado. La magnitud de $s$ es la distancia de $O$ a la partícula (en unidades de longitud), y su signo algebraico define el sentido de su dirección.

La posición es una cantidad vectorial puesto que tiene tanto magnitud como dirección, aunque en este caso se representa por el escalar algebraico $s$ puesto que la dirección se mantiene a lo largo del eje de coordenadas.

### Desplazamiento

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

El desplazamiento de la partícula se define como el cambio de su posición, y es dado por:

\begin{equation*}
\Delta s= s'-s
\label{eq:Ec1_1} \tag{1.1}
\end{equation*}

En este caso $\Delta s$ es positivo puesto que la posición final de la partícula queda a la derecha de su posición inicial, es decir, $s'>s$. Asimismo, si la posición final quedara a la izquierda de su posición inicial, $\Delta s$ sería negativo.

El desplazamiento de una partícula también es una cantidad vectorial, y deberá distinguirse de la distancia que recorre la partícula. Específicamente, la distancia recorrida es un escalar positivo que representa la longitud total de la trayectoria a lo largo de la cual viaja la partícula.

### Velocidad

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

Si la partícula recorre una distancia $\Delta s$ durante el intervalo $\Delta t$, su velocidad promedio durante este intervalo es

\begin{equation*}
\textbf{v}_{prom}=\frac{\Delta s}{\Delta t}
\label{eq:Ec1_2} \tag{1.2}
\end{equation*}

La velocidad instantánea es una cantidad vectorial definida como

\begin{equation*}
\textbf{v}=\lim_{\Delta t \rightarrow 0}\frac{\Delta s}{\Delta t}=\frac{ds}{dt}
\label{eq:Ec1_3} \tag{1.3}
\end{equation*}

Como la dirección temporal siempre será positiva, entonces el signo para determinar el sentido de la velocidad le corresponderá a $ds$. La magnitud de la velocidad es lo que se conoce como *rapidez*.

### Aceleración

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

Conocida la velocidad de la partícula en dos puntos, la aceleración promedio en un intervalo de tiempo $\Delta t$ está dada por

\begin{equation*}
\textbf{a}_{prom}=\frac{\Delta \textbf{v}}{\Delta t}
\label{eq:Ec1_4} \tag{1.4}
\end{equation*}

La aceleración instantánea es una cantidad vectorial definida como

\begin{equation*}
\textbf{a}=\lim_{\Delta t \rightarrow 0}\frac{\Delta \textbf{v}}{\Delta t}=\frac{d\textbf{v}}{dt}
\label{eq:Ec1_5} \tag{1.5}
\end{equation*}

La aceleración también se puede interpretar como la segunda derivada del desplazamiento respecto al tiempo.
Una relación diferencial que incluye el desplazamiento, la velocidad y la aceleración a lo largo de una trayectoria, eliminando la dependencia del tiempo es:

\begin{equation*}
\textbf{a}ds=\textbf{v}d\textbf{v}
\label{eq:Ec1_6} \tag{1.6}
\end{equation*}

### Aceleración constante

Si la aceleración es constante, se pueden integrar las tres ecuaciones cinemáticas vistas:

$$\textbf{a}_c=\frac{d\textbf{v}}{dt}; \quad \textbf{v}=\frac{ds}{dt}; \quad \textbf{a}ds=\textbf{v}d\textbf{v}$$

#### Velocidad como función del tiempo

Integrando $a_c=\frac{d\textbf{v}}{dt}$, con condiciones iniciales $\textbf{v}=v_0$ cuando $𝑡=0$

$$\int_{v_0}^v d\textbf{v} = \int_0^t a_c dt$$

Se llega a

\begin{equation*}
\textbf{v} = v_0 + a_c t
\label{eq:Ec1_7} \tag{1.7}
\end{equation*}

#### Posición como función del tiempo

Integrando $\textbf{v}=ds/dt=v_0 + a_c t$, con condiciones iniciales $s=s_0$ cuando $𝑡=0$

$$\int_{s_0}^s ds = \int_0^t (v_0 +a_c t) dt$$

Se llega a

\begin{equation*}
s = s_0 + v_0 t +\frac{1}{2} a_c t^2
\label{eq:Ec1_8} \tag{1.8}
\end{equation*}

#### Velocidad como función de la posición

Integrando $\textbf{v}d\textbf{v}=a_c ds$, con condiciones iniciales $v=v_0$ cuando $s=s_0$

$$\int_{v_0}^v \textbf{v}d\textbf{v} = \int_{s_0}^s a_c ds$$

Se llega a

\begin{equation*}
v^2 = v_0^2 + 2a_c (s-s_0)
\label{eq:Ec1_9} \tag{1.9}
\end{equation*}

#### Observaciones

- Las ecuaciones anteriores son útiles cuando la aceleración es constante y cuando $t=0$, $s=s_0$ y $v=v_0$.

- Si se conoce una relación entre dos de las cuatro variables, $\textbf{a}$, $\textbf{v}$, $s$ y $t$, entonces se puede obtener una tercera variable con una de las ecuaciones cinemáticas, $\textbf{a}=d\textbf{v}/dt$, $\textbf{v}=ds/dt$ o $\textbf{a}ds=\textbf{v}d\textbf{v}$, puesto que cada ecuación relaciona las tres variables.

- Siempre que se realice una integración, es importante que se conozcan la posición y la velocidad en un instante dado para evaluar o la constante de integración si se utiliza una integral indefinida, o los límites de integración si se utiliza una integral definida.

### Recapitulando

- La dinámica se ocupa de cuerpos que tienen movimiento acelerado.

- La cinemática es un estudio de la geometría del movimiento.

- La cinética es un estudio de las fuerzas que causan el movimiento.

- La cinemática rectilínea se refiere al movimiento en línea recta.

- La rapidez se refiere a la magnitud de la velocidad.

- La rapidez promedio es la distancia total recorrida, dividida entre el tiempo total. Ésta es diferente de la velocidad promedio, la cual es el desplazamiento dividido entre el tiempo.

- Una partícula que reduce el paso está desacelerando.

- Una partícula puede tener una aceleración y al mismo tiempo una velocidad cero.

- La relación $\textbf{a}ds=\textbf{v} d\textbf{v}$ se deriva de $\textbf{a}=d\textbf{v}/dt$ y $\textbf{v}=ds/dt$, al eliminar $dt$.

### Ejemplos

#### Desplazamiento rectilíneo de un Automovil

 Ejemplo 12.1: Hibbeler R. Engineering Mechanics: Dynamics

El automóvil de la figura se desplaza en línea recta de modo que durante un corto tiempo su velocidad está definida por $\textbf{v}=3t^2 + 2t$ pies/s, donde $t$ está en segundos. Determine su posición y aceleración cuando $t = 3 s$. Cuando $t = 0, s = 0$.

Vamos a resolver el ejemplo de dos formas: Analítica y computacionalmente.

***Solución analítica:***

- ***Sistema de coordenadas:*** Se establece el sistema de coordenadas en sentido horizontal, con origen en el punto $O$, positivo a la derecha.

- ***Posición:*** como la velocidad es una función del tiempo, $\textbf{v}=f(t)$, la posición se determina de la  [(Ec1.3)](#Ec1_3). Reemplazando

$$\textbf{v}=3t^2 + 2t=\frac{ds}{dt}$$

realizando la separación de variables e integrando el espacio, $s$, entre $0$ y $s$ y el tiempo, $t$, entre $0$ y $t$:

$$\int_0^s ds=\int_0^t(3t^2+2t)dt$$

$$\left. s\right|_0^s= \left. t^3+t^2 \right|_0^t$$

cuando $t=3 s$

$$s(3)=3^3+3^2 =36 pies$$

- ***Aceleración***
La aceleración también es función del tiempo y se determina de ecuación [(Ec1.5)](#Ec1_5).

$$\textbf{a}=\frac{d(3t^2 + 2t)}{dt}=\frac{d\textbf{v}}{dt}$$

realizando la separación de variables e integrando:

$$\textbf{a}=6t+2$$

cuando $t=3 s$

$$a(3)=6(3)+2=20 \text{pies/s}^2$$

***Solución computacional:***

Ahora vamos a resolver el ejemplo computacionalmente empleando el módulo [`sympy`](https://www.sympy.org/en/index.html) de `python`. Primero, se carga el módulo de cálculo simbólico, que nos permitirá obtener expresiones analíticas de la posición y la aceleración, que serán evaluadas en el tiempo solicitado. Para la impresión de algunos resultados de forma analítica se empleará el módulo [`mathjax`](https://www.mathjax.org/).

```python
from sympy import *
t = symbols('t')
init_printing(use_latex='mathjax')
```

Generamos una expresión para la función velocidad, como fue dada en el enunciado

```python
def v(t):

    """
    Función velocidad
        función para determinar la velocidad en función del tiempo, t.

    Input:
        Cadena de caracteres en donde t es la varible.

    Output:
        Cadena de caracteres.

    Ejemplo:
        3 * t**2 + 2 * t
    """

    # Ingresando la función a través del teclado (descomentar las dos líneas siguientes y comentar la última línea)
    #veloc = input("Ingrese la función correspondiente a la velocidad, v(t): ")
    #return veloc

    # escribiendo la función directamente dentro del módulo (comentar las dos líneas anteriores)
    return 3 * t**2 + 2 * t
```

```python
help(v)
```

Visualizando la integral de la velocidad a ser calculada de forma analítica

```python
Integral(v(t),(t,0,t))
```

Integrando analíticamente la expresión de la velocidad, para obtener una expresión de la posición:

```python
pos = integrate(v(t),(t,0,t))
pos
```

Evaluando la expresión del espacio obtenida con la integración, en $t=3s$

```python
print("La posición que tendrá el vehículo despues de 3 seg será de {0} pies".format(pos.subs(t,3)))
```

Ahora vamos a determinar una expresión para la aceleración, derivando la expresión dada de la velocidad

```python
acel = diff(v(t),t)
print(acel)
```

Por último, evaluamos la expresión de la aceleración obtenida con la derivada de la velociad respecto al tiempo, en $t=3s$

```python
print("La aceleración del vehículo después de 3 seg es {0} pies/s^2".format(acel.subs(t,3)))
```

Compactando en una única celda el código visto:

```python
from sympy import *
t = symbols('t')

# definición de la función a evaluar
def v(t):
    return 3 * t**2 + 2 * t

# posición
pos = integrate(v(t),(t,0,t))
print("La posición que tendrá el vehículo despues de 3 seg será de {0} pies".format(pos.subs(t,3)))

# aceleración
acel = diff(v(t),t)
print("La aceleración del vehículo después de 3 seg es {0} pies/s^2".format(acel.subs(t,3)))
```

#### Altura máxima cohete

 Ejemplo 12.3: Hibbeler R. Engineering Mechanics: Dynamics

Durante una prueba un cohete asciende a $75 m/s$ y cuando está a $40 m$ del suelo su motor falla. Determine la altura máxima $s_B$ alcanzada por el cohete y su velocidad justo antes de chocar con el suelo. Mientras está en movimiento, el cohete se ve sometido a una aceleración constante dirigida hacia abajo de $9.81 m/s^2$ debido a la gravedad. Ignore la resistencia del aire.

Igual que el ejemplo anterior, se dará solución analítica y computacional.

***Solución analítica:***

- ***Sistema de coordenadas:*** Se establecerá el origen de coordenadas a nivel del suelo.

- ***Altura máxima:*** Del enunciado se establece que el cohete está a una distancia de $s_A=40m$ del suelo, con una velocidad $v_A = +75m/s$ cuando el motor falla, que es cuando se empieza a tomar el tiempo, es decir, $t=0$. La aceleración que experimenta el cohete es debida a la gravedad, $a_c=-9.81m/s^2$ (negativa pues actúa en sentido contrario al desplazamiento y velocidad). Como la aceleración es constante, la posición y velocidad del cohete se pueden relacionar directamente mediante la [Ec. 1.9](#Ec1_9), donde $A$ y $B$ son los puntos inicial y final (de máxima altura) respectivamente.

$$v_B^2=v_A^2+2a_c(s_B-s_A)$$

La velocidad en el punto $B$ es cero. Reemplazando valores se tiene:

$$0=(75m/s)^2+2(-9.81m/s^2)(s_B-40m)$$

y despejando para el valor de $s_B$

$$s_B=327m$$

- ***Velocidad:*** La velocidad final del cohete (justo antes de chocar con la tierra), punto $C$, también se puede determinar de la [Ec. 1.9](#Ec1_9). En este caso el punto $B$ será el inicial.

$$v_C^2=v_B^2+2a_c(s_C-s_B)$$

La velocidad en el punto $B$ y la distancia en el punto $C$ son cero. Reemplazando valores se tiene:

$$v_C=\pm \sqrt{(0)^2+2(-9.81m/s^2)(0-327m)}$$

y calculando para el valor de $v_C$

$$v_C=-80.1m/s$$

Se selecciona la raíz negativa pues el cohete está descendiendo.

***Solución computacional:*** Se deja al estudiante intentar una solución empleando programación con `python`.

#### Partícula en campo magnético

 Ejemplo 12.3: Hibbeler R. Engineering Mechanics: Dynamics

Una partícula metálica se somete a la influencia de un campo magnético a medida que desciende a través de un fluido que se extiende de la placa $A$ a la placa $B$. Si la partícula se libera del reposo en el punto medio $C$, $s=100 mm$ y la aceleración es $a=(4s) m/s^2$, donde $s$ está en metros, determine la velocidad de la partícula cuando llega a la placa $B$, $s=200 mm$ y el tiempo que le lleva para ir de $C$ a $B$.

***Solución analítica:***

- ***Sistema de coordenadas:*** Positivo hacia abájo (dirección del desplazamiento)

- ***Velocidad:*** Como la aceleración es dada en función del espacio, $a=f(s)$, podemos deivar la ecuación de la velocidad a partir de la [Ec. 1.6](#Ec1_6), con condiciones iniciales $v=0$ en $s=0.1m$, entonces:

$$vdv=ads$$

integrando a ambos lados, con los límites de integración correspondientes, se tien:

$$\int_0^v vdv=\int_{0.1}^s 4s ds$$

$$\left. \frac{1}{2}v^2 \right |_0^v = \left . \frac{4}{2} s^2  \right|_{0.1}^s$$

$$v=\pm 2 \sqrt{(s^2-0.01)} m/s$$

evaluando en $s=200 mm = 0.2 m$ se tiene

$$v_B=0.346 m/s=346 mm/s$$

se escoge la raíz positiva pues va en la dirección del movimiento.

- ***Tiempo:*** El tiempo de desplazamiento de $C$ a $B$ se obtiene de la [Ec. 1.3](#Ec1_3). Reemplazando la expresión del espacio, cuando $s=0.1m$ en $t=0$

$$ds=vdt=\pm 2 \sqrt{(s^2-0.01)}dt$$

integrando

$$\int_{0.1}^s \frac{ds}{2 \sqrt{s^2-0.01}}=\int_0^t dt$$

$$\left. Ln \left( 2 \sqrt{s^2-0.01} + s \right) \right|_{0.1}^s=\left. t \right|_0^t$$

$$Ln \left( 2 \sqrt{s^2-0.01} + s \right) +2.303 = t$$

evaluando en $s=0.2 m$

$$t=\frac{Ln \left( 2 \sqrt{(0.2)^2-0.01} + 0.2 \right) +2.303 }{2}=0.658s$$

***Solución computacional***

- ***Velocidad:***

Ahora vamos a plantear la solución computacional como en el primer ejemplo. Para encontrar una expresión analítica para la velocidad debemos integrar la ecuacíón $vdv=ads$.

```python
from sympy import *
t, x = symbols('t x')
a, v, s = symbols('a v s') #, cls = Function)
init_printing(use_latex='mathjax')
```

En este ejemplo se ofrece una función para la aceleración dada por $a=(4s) m/s$. Generaremos una variable en python para la aceleración

```python
a = 4 * s
```

integrando a ambos lados de la ecuación

```python
veloc = Eq(integrate(v, (v, 0, v)), integrate(a, (s, 0.1, s)))
veloc
```

Resolviendo para la variable $v$

```python
veloc = solve(veloc,v)
veloc
```

evaluando en $s=0.2 m$, para la raíz positiva (posición 1 de la lista), se tiene

```python
print("La velocidad de caída de la partícula es {0:3.0f} mm/s".format(veloc[1].subs(s,0.2)*1000))
```

- ***tiempo:*** Siguiendo lo presentado en la solución analítica

```python
space = Eq(integrate(1/(veloc[1]),(s, 0.1, s)), integrate(1, (t, 0, t)))
space
```

```python
time = solve(space,t)
time
```

```python
print("El tiempo de caída de la partícula es {0:3.3f} s".format(time[0].subs(s,0.2)))
```

## Cinemática rectilínea: Movimiento variable

Cuando el movimiento de una partícula es variable, su *posición*, *velocidad* y *aceleración* no pueden describirse mediante una sola función matemática continua a lo largo de toda la trayectoria. En su lugar, se requerirá una serie de funciones para especificar el movimiento en diferentes intervalos. Por eso, conviene representar el movimiento como una gráfica. Si se puede trazar una gráfica del movimiento que relacione dos de las variables $s$, $v$, $a$, $t$, entonces esta gráfica puede utilizarse para construir gráficas subsecuentes que relacionen otras dos variables, puesto que las variables están relacionadas por las relaciones diferenciales $v = ds/dt$, $a=dv/dt$ o $ads=vdv$. Con frecuencia ocurren varias situaciones.

### Gráficas de $s-t$, $v-t$ y $a-t$

 Hibbeler R. Engineering Mechanics: Dynamics

    La gráfica de $v-t$ se construye a partir de la gráfica de $s-t$, fig. (a), se utilizará la ecuación $v=ds/dt$, ya que relaciona las variables $s$ y $t$ con $v$. Esta ecuación establece que

    $$\underbrace{\frac{ds}{dt}}_{\text{pendiente gráfica s-t}}=\underbrace{v}_{velocidad}$$

   Por ejemplo, si se mide la pendiente en la gráfica de $s-t$ cuando $t=t_1$, la velocidad es $v_1$, la cual se traza en la fig. (b). La gráfica de $v-t$ se construye trazando ésta y otros valores en cada instante.

 Hibbeler R. Engineering Mechanics: Dynamics

    La gráfica de $a-t$ se construye a partir de la gráfica de $v-t$ del mismo modo, figs. (a) y (b) puesto que

    $$\underbrace{\frac{dv}{dt}}_{\text{pendiente gráfica v-t}}=\underbrace{a}_{acelereción}$$

Si la curva $s-t$ correspondiente a cada intervalo de movimiento puede
expresarse mediante una función matemática $s=s(t)$, entonces la ecuación
de la gráfica de $v-t$ correspondiente al mismo intervalo se obtiene
diferenciando esta función con respecto al tiempo puesto que $v=ds/dt$.

Asimismo, la ecuación de la gráfica de $a-t$ en el mismo intervalo se determina
al diferenciar $v=v(t)$ puesto que $a=dv/dt$. Como la diferenciación
reduce un polinomio de grado $n$ a uno de grado $n-1$, en tal caso si la
gráfica de $s-t$ es parabólica (una curva de segundo grado), la gráfica de
$v-t$ será una línea inclinada (una curva de primer grado) y la gráfica de $a-t$
será una constante o una línea horizontal (una curva de grado cero).

 Hibbeler R. Engineering Mechanics: Dynamics

    Si se tiene la gráfica de $a-t$, como se muestra en la figura al lado, la gráfica de $v-t$ se construye mediante $a=dv/dt$, escrita como

$$\underbrace{\Delta v}_{\text{Cambio de la velocidad}}=\underbrace{\int adt}_{\text{área bajo la curva de a-t}}$$

Para construir la gráfica $v-t$, se parte de la velocidad inicial de la partícula, $v_0$ y luego se va adicionando pequeños incrementos de área ($\Delta v$) determinados a partir de la gráfica $a-t$. Con esto, se tienen una serie de puntos sucesivos, $v_i=v_{i-1}+\Delta v$ que irán conformando la gráfica $v-t$

La adición algebráica de los incrementos de área de la gráfica $a-t$ es necesaria, ya que las áreas situadas por encima del eje $t$ corresponden a un incremento de $v$ (área "positiva"), mientras que las que quedan debajo del eje indican una reducción de $v$ (área "negativa").

 Hibbeler R. Engineering Mechanics: Dynamics

    De igual forma, si se tiene la gráfica de $v-t$, como se muestra en la figura al lado, la gráfica de $s-t$ se construye mediante $v=ds/dt$, escrita como

$$\underbrace{\Delta s}_{\text{desplazamiento}}=\underbrace{\int vdt}_{\text{área bajo la curva de v-t}}$$

igual que en la anterior gráfica, se parte de la posición inicial de la partícula, $s_0$ y luego se va adicionando pequeños incrementos de área ($\Delta s$) determinados a partir de la gráfica $v-t$.

Los segmentos de la gráfica $a-t$ pueden describirse mediante una serie de ecuaciones, que a su vez pueden integrarse para obtener los segmentos correspondientes a l gráfica $v-t$. Por lo tanto, si la gráfica $a-t$ es lineal, la integración dará una gráfica para $v-t$ cuadrática, y para $s-t$, una cúbica.

### Gráficas de $v-s$ y $a-s$

 Hibbeler R. Engineering Mechanics: Dynamics

    Los puntos de la gráfica $v-s$ se determinana por medio de la ecuación $vdv=ads$. Integrando esta ecuación en los límites $v=v_0$ con $s=s_0$ y $v=v_1$ con $s=s_1$, se tiene

$$\frac{1}{2}\left( v_1^2 - v_0^2\right)=\underbrace{\int_{s_0}^{s_1} ads}_{\text{área bajo la curva de a-s}}$$

Si se determina el área de color gris y se conoce la velocidad $v_0$ en $s_0=0$, entonces $v_1=\left( 2 \int_{s_0}^{s_1}ads+v_0^2\right)^{1/2}$. De esta forma se pueden marcar puntos sucesivos en la gráfica $v-s$.

 Hibbeler R. Engineering Mechanics: Dynamics

Si se conoce la gráfica $v-s$, la aceleración $a$ en cualquier posición $s$ se determinar por $ads=vdv$, que se escribe como

$$\underbrace{a}_\text{aceleración}=\underbrace{v \left( \frac{dv}{ds} \right)}_{\text{velocidad por la pendiente de la gráfica de v-s}}$$

Entonces, en cualquier punto $(s,v)$ se mide la pendiente $ds/dv$ de la gráfica de $v-s$. Entonces, con $v$ y $dv/ds$ conocidas, se calcula el valor de $a$.

La gráfica de $v-s$ también se construye a partir de la gráfica de $a-s$ o viceversa, por aproximación de la gráfica conocida en varios intervalos con funciones matemáticas, $v=f(s)$ o $a=g(s)$ y luego por $ads=vdv$ para obtener la otra gráfica.

### Ejemplos

#### Desplazamiento en bicicleta

 Ejemplo 12.6: Hibbeler R. Engineering Mechanics: Dynamics

Una bicicleta rueda a lo largo de una carretera recta de modo que la gráfica de la figura describe su posición. Construya las gráficas de $v-t$ y $a-t$ en el intervalo $0 \leq t \leq 30 s$

***Solución analítica:***

- Gráfica $v-t$: teniendo que $v=ds/dt$, la gráfica de $v-t$ se determina diferenciando las ecuaciones que definen la gráfica $s-t$. En la gráfica se observan dos segmentos:

  - ***Segmento 1:*** en el intervalo $0\leq t<10s$ la función de desplazamiento está dada por la ecuación $s=t^2 pies$, diferenciando esta ecuación respecto al tiempo para determinar la velocidad en ese trayecto, quedaría $v=\frac{ds}{dt}=(2t) pies/s$.

  - ***Segmento 2:*** en el intervalo $10s\leq t<30s$ la función de desplazamiento está dada por la ecuación $s=(20t-100)pies$, diferenciando esta ecuación respecto al tiempo para determinar la velocidad en ese trayecto, quedaría $v=\frac{ds}{dt}=(20)pies/s$.

|$0\leq t<s$|$s=t^2 pies$|$v=\frac{ds}{dt}=(2t) pies/s$|
|:-:|:-:|:-:|
|$10s<t\leq 30s$|$s=(20t-100)pies$|$v=\frac{ds}{dt}=(20)pies/s$|

Se observa que la primera gráfica $v-t$ es una línea recta con pendiente $+2$, y en el segundo tramo se tiene una línea recta constante. Éstas se trazan en la gráfica

- Gráfica $a-t$: Similarmente, como $a=dv/dt$, la gráfica de $a-t$ se determina diferenciando las ecuaciones que definen la gráfica $v-t$:

  - ***Segmento 1:*** en el intervalo $0\leq t<10s$ la función de velocidad está dada por la ecuación $s=2t pies/s$, diferenciando esta ecuación respecto al tiempo para determinar la aceleración en ese trayecto, quedaría $a=\frac{dv}{dt}=(2) pies/s^2$.

  - ***Segmento 2:*** en el intervalo $10s\leq t<30s$ la función de velocidad está dada por la ecuación $v=(20)pies/s$, diferenciando esta ecuación respecto al tiempo para determinar la aceleración en ese trayecto, quedaría $a=\frac{dv}{dt}=(0)pies/s^2$.

Se observa que el primer tramo de la gráfica $a-t$ es una constante de valor $2$, y en el segundo tramo también se tiene una constante, pero de valor cero, $0$.

***Solución computacional:***

Igual que en los primeros ejemplos, se empleará el módulo `sympy` de `python` para realizar los cálculos correspondientes, de forma computacional.

```python
from sympy import *
import seaborn as sns
t = symbols('t')
init_printing(use_latex='mathjax')
```

```python
# definición de las funciones a evaluar
def s1(t):
    return t**2

def s2(t):
    return 20 * t - 100
```

```python
# Gráfica s-t
sns.set()
sns.set_style("whitegrid", {'grid.linestyle': '--'})
plot((s1(t), (t,0,10)), (s2(t), (t,10,30)));
```

```python
#Gráfica v-t
plot((diff(s1(t),t), (t,0,10)), (diff(s2(t),t), (t,10,30)));
```

```python
#Gráfica a-t
plot((diff(s1(t),t,2), (t,0,10)), (diff(s2(t),t,2), (t,10,30)));
```

[nbviewer](https://nbviewer.jupyter.org/github/carlosalvarezh/Dinamica/blob/main/C01_CinematicaCineticaParticulas.ipynb)


```python
%matplotlib inline
```

```python
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
```

```python
from plotnine import *
```

```python
class theme_fs(theme_light):
    """
    A theme similar to :class:`theme_linedraw` but with light grey
    lines and axes to direct more attention towards the data.
    Parameters
    ----------
    base_size : int, optional
        Base font size. All text sizes are a scaled versions of
        the base font size. Default is 11.
    base_family : str, optional
        Base font family.
    """

    def __init__(self, base_size=11, base_family='DejaVu Sans'):
        theme_light.__init__(self, base_size, base_family)
        self.add_theme(theme(
            axis_ticks=element_line(color='#DDDDDD', size=0.5),
            panel_border=element_rect(fill='None', color='#838383',
                                      size=1),
            strip_background=element_rect(
                fill='#DDDDDD', color='#838383', size=1),
            strip_text_x=element_text(color='black'),
            strip_text_y=element_text(color='black', angle=-90),
            legend_key=element_blank(),
        ), inplace=True)
```

```python
df = pd.read_csv('./data/settles.acl16.learning_traces.13m.csv.gz')
df['delta_days'] = df['delta'].apply(lambda d: d / (60 * 60 * 24))
```

```python
# df = df.head(3000)
```

```python
(
    ggplot(df)
    + geom_bar(
        aes(x='p_recall'),
        stat=stat_bin(bins=100),
        fill='blue',
        alpha=0.5
    )
    + theme_fs()
)
```

```python
(
    ggplot(df)
    + geom_bar(
        aes(x='delta_days'),
        stat=stat_bin(bins=100),
        fill='blue',
        alpha=0.5
    )
    + scale_y_log10()
    + theme_fs()
)
```

```python
(
    ggplot(df.loc[df.delta_days < 50])
    + geom_bar(
        aes(x='delta_days'),
        stat=stat_bin(bins=100),
        fill='blue',
        alpha=0.5
    )
    + scale_y_log10()
    + theme_fs()
)
```

```python
(
    ggplot(df)
    + geom_bar(
        aes(x='history_seen'),
        stat=stat_bin(bins=100),
        fill='blue',
        alpha=0.5
    )
    + scale_y_log10()
    + theme_fs()
)
```

```python
(
    ggplot(df.loc[df.history_seen < 50])
    + geom_bar(
        aes(x='history_seen'),
        stat=stat_bin(bins=50),
        fill='blue',
        alpha=0.5
    )
    + theme_fs()
)
```

```python
(
    ggplot(df)
    + geom_bar(
        aes(x='history_correct'),
        stat=stat_bin(bins=100),
        fill='blue',
        alpha=0.5
    )
    + scale_y_log10()
    + theme_fs()
)
```

```python
(
    ggplot(df.loc[df.history_correct < 50])
    + geom_bar(
        aes(x='history_correct'),
        stat=stat_bin(bins=50),
        fill='blue',
        alpha=0.5
    )
    + theme_fs()
)
```

```python
(
    ggplot(df)
    + geom_bar(
        aes(x='session_seen'),
        stat=stat_bin(bins=15),
        fill='blue',
        alpha=0.5
    )
    + theme_fs()
)
```

```python
(
    ggplot(df)
    + geom_bar(
        aes(x='session_correct'),
        stat=stat_bin(bins=15),
        fill='blue',
        alpha=0.5
    )
    + theme_fs()
)
```

```python
def _bin_p_recall(group):
    return pd.DataFrame([{'p_recall': group.p_recall.mean()}])
(
    ggplot(
        df.groupby(
            pd.qcut(df.delta_days, 20)
        ).apply(_bin_p_recall).reset_index()
    )
    + geom_bar(
        aes(x='delta_days', y='p_recall', ymin=0.75, ymax=1.0),
        stat='identity',
        fill='blue',
        alpha=0.5
    )
    + theme_fs()
    + theme(
        axis_text_x=element_text(rotation=90)
    )
)
```

## reliability diagram, expected calibration error

In multi-class classification setting, the general idea of calibration is that confidence should match accuracy, i.e. when the model is 60% confidence, the probability of it being correct should be 60%.

reliability diagram: bin validation examples by predicted probability, then calculate the average accuracy within each bin, plot average accuracy against confidence. ideal calibration should be a diagonal line.

expected calibration error (ECE):  the difference in expectation between confidence and accuracy is
$$\mathbb{E}_{\hat{P}}[|\mathbb{P}(\hat{Y}=Y|\hat{P}=p)-p)|$$
This can be approximated by a weighted average of bins' accuracy - confidence difference (the gap showns as red bars in reliability diagrams)
$$\text{ECE}=\sum_{i}\frac{|B_i|}{n}|\text{acc}(B_m)-\text{conf}(B_m)|$$

```python
results = pd.read_csv('./results/hlr.settles.acl16.learning_traces.13m.preds', delimiter='\t')
```

```python
def _bin_prediction(group):
    return pd.DataFrame([{'prediction':  group.pp.mean()}])

(
    ggplot(
        results.groupby(
            pd.cut(results.p, 20)
        ).apply(_bin_prediction).reset_index()
    )
    + geom_bar(
        aes(x='p', y='prediction'),
        stat='identity',
        fill='blue',
        alpha=0.5
    )
    + theme_fs()
    + theme(
        axis_text_x=element_text(rotation=90)
    )
)
```

```python
def _bin_rmse(group):
    return pd.DataFrame([{
        'rmse':  ((group.pp - group.p) ** 2).mean() ** (1/2)
    }])

(
    ggplot(
        results.groupby(
            pd.cut(results.pp, 20)
        ).apply(_bin_rmse).reset_index()
    )
    + geom_bar(
        aes(x='pp', y='rmse'),
        stat='identity',
        fill='blue',
        alpha=0.5
    )
    + theme_fs()
    + theme(
        axis_text_x=element_text(rotation=90)
    )
)
```

When our model directly predicts the probability, instead of using ECE, we can directly measure the miscalibration
$$\text{ECE}=\sum_i\frac{|B_i|}{n}|\text{precition}(B_i) - \text{ground_truth}(B_i)|$$

```python
def _bin_miscalibration(group):
    return pd.DataFrame([{
        'miscalibration': (group.pp - group.p).abs().mean(),
        'prediction': group.pp.mean(),
        'ground_truth': group.p.mean()
    }])

miscalibration = results.groupby(pd.cut(results.p, 16)).apply(_bin_miscalibration).reset_index()

print('expected calibration error', miscalibration.miscalibration.mean())

(
    ggplot(miscalibration)
    + geom_bar(
        aes(x='p', y='ground_truth'),
        stat='identity',
        fill='blue',
        alpha=1.0
    )
    + geom_bar(
        aes(x='p', y='prediction'),
        stat='identity',
        fill='red',
        color='red',
        alpha=0.3
    )
    + theme_fs()
    + theme(
        axis_text_x=element_text(rotation=90)
    )
)
```

## Half-life regression (HLR)

short-hand for each record \begin{align}<\cdot>&=<\Delta,x,P[\text{recall}]\in[0,1]>\\&=<\Delta,x,y\in\{0,1\}>\end{align}

Regression against recall probability $$l_\text{recall}(<\cdot>;\theta)=(p-f_\theta(x,\Delta))^2$$

Regression against back-solved half-life $$l_\text{half-life}(<\cdot>;\theta)=(\frac{-\Delta}{\log_2{p}}-f_\theta(x,\Delta))^2$$

Binary recall classification $$l_\text{binary}(<\cdot>;\theta)=\text{xent}(f_\theta(x,\Delta),y)$$

Assume that half-life increases exponentially with each repeated exposure, with a linear approximator, you get $f_\theta(x,\Delta)=2^{\theta\cdot x}$. Use this parameterization with regression against both recall probability and back-solved half-life, you get Settles' formulation:
$$l(<\cdot>; \theta)=(p-2^{\frac{\Delta}{2^{\theta\cdot x}}})^2+\alpha(\frac{\Delta}{\log_2(p)}-2^{\theta\cdot{x}})^2+\lambda|\theta|_2^2$$

Note that this formulation incorporates two heuristics
1. the memory strength follows an exponential forgetting curve, hence the half-life
2. half-life increases exponentially with number of repetitions

But in their code the `history_seen` and `history_seen_correct` feature are squre-rooted, so essentially throwing away the second heuristic.

```python
splitpoint = int(0.9 * len(df))
train_df, test_df = df.iloc[:splitpoint], df.iloc[splitpoint:]
```

```python
df1 = pd.DataFrame({
    'pp': results.pp.tolist(),
    'hh': results.hh.tolist(),
    'p': results.p.tolist(),
    'h': results.h.tolist(),
    'history_seen': test_df.history_seen.tolist(),
    'history_correct': test_df.history_correct.tolist(),
    'session_seen': test_df.session_seen.tolist(),
    'session_correct': test_df.session_correct.tolist(),
    'delta_days': test_df.delta_days.tolist(),
})
```

```python
def _bin_delta(group):
    return pd.DataFrame([{
        'prediction': group.pp.mean(),
        'ground_truth': group.p.mean(),
        'delta': group.delta_days.mean(),
    }])

(
    ggplot(
        df1.groupby(
            pd.cut(df1.delta_days, 16)
        ).apply(_bin_delta).reset_index()
    )
    + geom_bar(
        aes(x='delta', y='ground_truth'),
        stat='identity',
        fill='blue',
        alpha=0.3
    )
    + geom_bar(
        aes(x='delta', y='prediction'),
        stat='identity',
        fill='red',
        color='red',
        alpha=0.3
    )
    + theme_fs()
    + theme(
        axis_text_x=element_text(rotation=90)
    )
)
```

```python
def _bin_history_seen(group):
    return pd.DataFrame([{
        'prediction': group.pp.mean(),
        'ground_truth': group.p.mean(),
        'seen': group.history_seen.mean(),
    }])

_df1 = df1.loc[df1.history_seen < 100]

(
    ggplot(
        _df1.groupby(
            pd.cut(_df1.history_seen, 30)
        ).apply(_bin_history_seen).reset_index()
    )
    + geom_bar(
        aes(x='seen', y='ground_truth'),
        stat='identity',
        fill='blue',
        alpha=0.3
    )
    + geom_bar(
        aes(x='seen', y='prediction'),
        stat='identity',
        fill='red',
        color='red',
        alpha=0.3
    )
    + theme_fs()
    + theme(
        axis_text_x=element_text(rotation=90)
    )
)
```

There are several knobs to be tweaked in the general formulation:
- labels: derived $p$, binary $y$
- linear, nn
- on/off: exponentially increased half-life
- on/off: loss wrt back-solved half-life (from derived $p$)

```python

```


```python
#format the book
%matplotlib inline
from __future__ import division, print_function
import sys;sys.path.insert(0,'..')
from  book_format import load_style;load_style('..')
```

<style>
@import url('http://fonts.googleapis.com/css?family=Source+Code+Pro');
@import url('http://fonts.googleapis.com/css?family=Lora');

.CodeMirror pre {
    font-family: 'Source Code Pro', Consolas, monocco, monospace;
}
    div.cell{
        //width: 950px;
        margin-left: 0% !important;
        margin-right: auto;
    }
    div.text_cell_render{
        font-family: 'Lora';
        line-height: 125%;
        font-size: 100%;
        text-align: justify;
        text-justify:inter-word;
    }
    div.text_cell code {
        background: transparent;
        color: #000000;
        font-weight: 400;
        font-size: 11pt;
        font-family:  'Source Code Pro', Consolas, monocco, monospace;
   }
    h1 {
        font-family: 'Open sans',verdana,arial,sans-serif;
	}

    div.input_area {
        background: #F6F6F9;
        border: 1px solid #586e75;
    }

    .text_cell_render h1 {
        font-weight: 200;
        font-size: 30pt;
        line-height: 100%;
        color:#c76c0c;
        margin-bottom: 0.5em;
        margin-top: 1em;
        display: block;
        white-space: wrap;
        text-align: left;
    }
    h2 {
        font-family: 'Open sans',verdana,arial,sans-serif;
        text-align: left;
    }
    .text_cell_render h2 {
        font-weight: 200;
        font-size: 16pt;
        font-style: italic;
        line-height: 100%;
        color:#c76c0c;
        margin-bottom: 0.5em;
        margin-top: 1.5em;
        display: block;
        white-space: wrap;
        text-align: left;
    }
    h3 {
        font-family: 'Open sans',verdana,arial,sans-serif;
    }
    .text_cell_render h3 {
        font-weight: 200;
        font-size: 14pt;
        line-height: 100%;
        color:#d77c0c;
        margin-bottom: 0.5em;
        margin-top: 2em;
        display: block;
        white-space: wrap;
        text-align: left;
    }
    h4 {
        font-family: 'Open sans',verdana,arial,sans-serif;
    }
    .text_cell_render h4 {
        font-weight: 100;
        font-size: 14pt;
        color:#d77c0c;
        margin-bottom: 0.5em;
        margin-top: 0.5em;
        display: block;
        white-space: nowrap;
    }
    h5 {
        font-family: 'Open sans',verdana,arial,sans-serif;
    }

    .text_cell_render h5 {
        font-weight: 200;
        font-style: normal;
        color: #1d3b84;
        font-size: 16pt;
        margin-bottom: 0em;
        margin-top: 0.5em;
        display: block;
        white-space: nowrap;
    }
    div.output_subarea.output_text.output_pyout {
        overflow-x: auto;
        overflow-y: visible;
        max-height: 5000000px;
    }
    div.output_subarea.output_stream.output_stdout.output_text {
        overflow-x: auto;
        overflow-y: visible;
        max-height: 5000000px;
    }
    div.output_wrapper{
        margin-top:0.2em;
        margin-bottom:0.2em;
}

    code{
        font-size: 6pt;

    }
    .rendered_html code{
    background-color: transparent;
    }
    ul{
        margin: 2em;
    }
    ul li{
        padding-left: 0.5em;
        margin-bottom: 0.5em;
        margin-top: 0.5em;
    }
    ul li li{
        padding-left: 0.2em;
        margin-bottom: 0.2em;
        margin-top: 0.2em;
    }
    ol{
        margin: 2em;
    }
    ol li{
        padding-left: 0.5em;
        margin-bottom: 0.5em;
        margin-top: 0.5em;
    }
    ul li{
        padding-left: 0.5em;
        margin-bottom: 0.5em;
        margin-top: 0.2em;
    }
    a:link{
       color:#447adb;
    }
    a:visited{
       color: #1d3b84;
    }
    a:hover{
       color: #1d3b84;
    }
    a:focus{
       color:#447adb;
    }
    a:active{
       font-weight: bold;
       color:#447adb;
    }
    .rendered_html :link {
       text-decoration: underline;
    }
    .rendered_html :hover {
       text-decoration: none;
    }
    .rendered_html :visited {
      text-decoration: none;
    }
    .rendered_html :focus {
      text-decoration: none;
    }
    .rendered_html :active {
      text-decoration: none;
    }
    .warning{
        color: rgb( 240, 20, 20 )
    }
    hr {
      color: #f3f3f3;
      background-color: #f3f3f3;
      height: 1px;
    }
    blockquote{
      display:block;
      background: #fcfcfc;
      border-left: 5px solid #c76c0c;
      font-family: 'Open sans',verdana,arial,sans-serif;
      width:680px;
      padding: 10px 10px 10px 10px;
      text-align:justify;
      text-justify:inter-word;
      }
      blockquote p {
        margin-bottom: 0;
        line-height: 125%;
        font-size: 100%;
      }
</style>

# Computing and plotting PDFs of discrete data

So let's investigate how to compute and plot probability distributions.

First, let's make some data according to a normal distribution. We use `numpy.random.normal` for this. The parameters are not well named. `loc` is the mean of the distribution, and `scale` is the standard deviation. We can call this function to create an arbitrary number of data points that are distributed according to that mean and std.

```python
import numpy as np
import numpy.random as random

mean = 3
std = 2

data = random.normal(loc=mean, scale=std, size=50000)
print(len(data))
print(data.mean())
print(data.std())
```

    50000
    3.00067325106
    2.00433280075

As you can see from the print statements we got 5000 points that have a mean very close to 3, and a standard deviation close to 2.

We can plot this Gaussian by using `scipy.stats.norm` to create a frozen function that we will then use to compute the pdf (probability distribution function) of the Gaussian.

```python
%matplotlib inline
import matplotlib.pyplot as plt
import scipy.stats as stats

def plot_normal(xs, mean, std, **kwargs):
    norm = stats.norm(mean, std)
    plt.plot(xs, norm.pdf(xs), **kwargs)

xs = np.linspace(-5, 15, num=200)
plot_normal(xs, mean, std, color='k')
```

But we really want to plot the PDF of the discrete data, not the idealized function.

There are a couple of ways of doing that. First, we can take advantage of `matplotlib`'s `hist` method, which computes a histogram of a collection of data. Normally `hist` computes the number of points that fall in a bin, like so:

```python
plt.hist(data, bins=200)
plt.show()
```

that is not very useful to us - we want the PDF, not bin counts. Fortunately `hist` includes a `normed` parameter which will plot the PDF for us.

```python
plt.hist(data, bins=200, normed=True)
plt.show()
```

I may not want bars, so I can specify the `histtype` as 'step' to get a line.

```python
plt.hist(data, bins=200, normed=True, histtype='step', lw=2)
plt.show()
```

To be sure it is working, let's also plot the idealized Gaussian in black.

```python
plt.hist(data, bins=200, normed=True, histtype='step', lw=2)
norm = stats.norm(mean, std)
plt.plot(xs, norm.pdf(xs), color='k', lw=2)
plt.show()
```

There is another way to get the approximate distribution of a set of data. There is a technique called *kernel density estimate* that uses a kernel to estimate the probability distribution of a set of data. SciPy implements it with the function `gaussian_kde`. Do not be mislead by the name - Gaussian refers to the type of kernel used in the computation. This works for any distribution, not just Gaussians. In this section we have a Gaussian distribution, but soon we will not, and this same function will work.

```python
kde = stats.gaussian_kde(data)

xs = np.linspace(-5, 15, num=200)
plt.plot(xs, kde(xs))
plt.show()
```

## Monte Carlo Simulations

We (well I) want to do this sort of thing because I want to use monte carlo simulations to compute distributions. It is easy to compute Gaussians when they pass through linear functions, but difficult to impossible to compute them analytically when passed through nonlinear functions. Techniques like particle filtering handle this by taking a large sample of points, passing them through a nonlinear function, and then computing statistics on the transformed points. Let's do that.

We will start with the linear function $f(x) = 2x + 12$ just to prove to ourselves that the code is working. I will alter the mean and std of the data we are working with to help ensure the numbers that are output are unique It is easy to be fooled, for example, if the formula multipies x by 2, the mean is 2, and the std is 2. If the output of something is 4, is that due to the multication factor, the mean, the std, or a bug? It's hard to tell.

```python
def f(x):
    return 2*x + 12

mean = 1.
std = 1.4
data = random.normal(loc=mean, scale=std, size=50000)

d_t = f(data) # transform data through f(x)

plt.hist(data, bins=200, normed=True, histtype='step', lw=2)
plt.hist(d_t, bins=200, normed=True, histtype='step', lw=2)

plt.ylim(0, .35)
plt.show()
print('mean = {:.2f}'.format(d_t.mean()))
print('std  = {:.2f}'.format(d_t.std()))
```

This is what we expected. The input is the Gaussian $\mathcal{N}(\mu=1, \sigma=1.4)$, and the function is $f(x) = 2x+12$. Therefore we expect the mean to be shifted to $f(\mu) = 2*1+12=14$. We can see from the plot and the print statement that this is what happened.

Before I go on, can you explain what happened to the standard deviation? You may have thought that the new $\sigma$ should be passed through $f(x)$ like so $2(1.4) + 12=14.81$. But that is not correct - the standard deviation is only affected by the multiplicative factor, not the shift. If you think about that for a moment you will see it makes sense. We multiply our samples by 2, so they are twice as spread out as before. Standard deviation is a measure of how spread out things are, so it should also double. It doesn't matter if we then shift that distribution 12 places, or 12 million for that matter - the spread is still twice the input data.

## Nonlinear Functions

Now that we believe in our code, lets try it with nonlinear functions.

```python
def f2(x):
    return (np.cos((1.5*x + 2.1))) * np.sin(0.3*x) - 1.6*x

d_t = f2(data)
plt.subplot(121)
plt.hist(d_t, bins=200, normed=True, histtype='step', lw=2)

plt.subplot(122)
kde = stats.gaussian_kde(d_t)
xs = np.linspace(-10, 10, 200)
plt.plot(xs, kde(xs), 'k')
plot_normal(xs, d_t.mean(), d_t.std(), color='g', lw=3)
plt.show()
print('mean = {:.2f}'.format(d_t.mean()))
print('std  = {:.2f}'.format(d_t.std()))
```

Here I passed the data through the nonlinear function $f(x) = \cos(1.5x+2.1)\sin(\frac{x}{3}) - 1.6x$. That function is quite close to linear, but we can see how much it alters the pdf of the sampled data.

There is a lot of computation going on behind the scenes to transform 50,000 points and then compute their PDF. The Extended Kalman Filter (EKF) gets around this by linearizing the function at the mean and then passing the Gaussian through the linear equation. We saw above how easy it is to pass a Gaussian through a linear function. So lets try that.

We can linearize this by taking the derivative of the function at x. We can use sympy to get the derivative.

```python
import sympy
x = sympy.symbols('x')
f = sympy.cos(1.5*x+2.1) * sympy.sin(x/3) - 1.6*x
dfx = sympy.diff(f, x)
dfx
```

    -1.5*sin(x/3)*sin(1.5*x + 2.1) + cos(x/3)*cos(1.5*x + 2.1)/3 - 1.6

We can now compute the slope of the function by evaluating the derivative at the mean.

```python
m = dfx.subs(x, mean)
m
```

    -1.66528051815545

The equation of a line is $y=mx+b$, so the new standard deviation should be $~1.67$ times the input std. We can compute the new mean by passing it through the original function because the linearized function is just the slope of f(x) evaluated at the mean. The slope is a tangent that touches the function at $x$, so both will return the same result. So, let's plot this and compare it to the results from the monte carlo simulation.

```python
plt.hist(d_t, bins=200, normed=True, histtype='step', lw=2)
plot_normal(xs, f2(mean), abs(float(m)*std), color='k', lw=3, label='EKF')
plot_normal(xs, d_t.mean(), d_t.std(), color='r', lw=3, label='MC')
plt.legend()
plt.show()
```

We can see from this that the estimate from the EKF (in red) is not exact, but it is not a bad approximation either.