##### Copyright 2020 The Cirq Developers

```
#@title Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
```

# QAOA: Max-Cut

    View on QuantumAI

    Run in Google Colab

    View source on GitHub

    Download notebook

In this tutorial, we implement the quantum approximate optimization algorithm (QAOA) for determining the Max-Cut of the Bristlecone processor's hardware graph (with random edge weights). To do so, we will:

1. Define a random set of weights over the hardware graph.
2. Construct a QAOA circuit using Cirq.
3. Calculate the expected value of the QAOA cost function.
4. Create an outer loop optimization to minimize the cost function.
5. Compare cuts found from QAOA with random cuts.

```
try:
    import cirq
except ImportError:
    print("installing cirq...")
    !pip install --quiet cirq
    print("installed cirq.")
```

## 1. Defining a random set of weights over the hardware graph
In order to make the problem easily embeddable on a quantum device, we will look at the problem of Max-Cut on the same graph that the device's qubit connectivity defines, but with random valued edge weights.

```
import cirq
import sympy
import numpy as np
import matplotlib.pyplot as plt
working_device = cirq.google.Bristlecone
print(working_device)
```

                                                 (0, 5)────(0, 6)
                                                 │         │
                                                 │         │
                                        (1, 4)───(1, 5)────(1, 6)────(1, 7)
                                        │        │         │         │
                                        │        │         │         │
                               (2, 3)───(2, 4)───(2, 5)────(2, 6)────(2, 7)───(2, 8)
                               │        │        │         │         │        │
                               │        │        │         │         │        │
                      (3, 2)───(3, 3)───(3, 4)───(3, 5)────(3, 6)────(3, 7)───(3, 8)───(3, 9)
                      │        │        │        │         │         │        │        │
                      │        │        │        │         │         │        │        │
             (4, 1)───(4, 2)───(4, 3)───(4, 4)───(4, 5)────(4, 6)────(4, 7)───(4, 8)───(4, 9)───(4, 10)
             │        │        │        │        │         │         │        │        │        │
             │        │        │        │        │         │         │        │        │        │
    (5, 0)───(5, 1)───(5, 2)───(5, 3)───(5, 4)───(5, 5)────(5, 6)────(5, 7)───(5, 8)───(5, 9)───(5, 10)───(5, 11)
             │        │        │        │        │         │         │        │        │        │
             │        │        │        │        │         │         │        │        │        │
             (6, 1)───(6, 2)───(6, 3)───(6, 4)───(6, 5)────(6, 6)────(6, 7)───(6, 8)───(6, 9)───(6, 10)
                      │        │        │        │         │         │        │        │
                      │        │        │        │         │         │        │        │
                      (7, 2)───(7, 3)───(7, 4)───(7, 5)────(7, 6)────(7, 7)───(7, 8)───(7, 9)
                               │        │        │         │         │        │
                               │        │        │         │         │        │
                               (8, 3)───(8, 4)───(8, 5)────(8, 6)────(8, 7)───(8, 8)
                                        │        │         │         │
                                        │        │         │         │
                                        (9, 4)───(9, 5)────(9, 6)────(9, 7)
                                                 │         │
                                                 │         │
                                                 (10, 5)───(10, 6)

Since a circuit covering the entire Bristlecone device cannot be easily simulated, a small subset of the device graph will be used instead.

```
import networkx as nx

# Set the seed to determine the problem instance.
np.random.seed(seed=11)

# Identify working qubits from the device.
device_qubits = working_device.qubits
working_qubits = sorted(device_qubits)[:12]

# Populate a networkx graph with working_qubits as nodes.
working_graph = nx.Graph()
for qubit in working_qubits:
  working_graph.add_node(qubit)

# Pair up all neighbors with random weights in working_graph.
for qubit in working_qubits:
  for neighbor in working_device.neighbors_of(qubit):
    if neighbor in working_graph:
      # Generate a randomly weighted edge between them. Here the weighting
      # is a random 2 decimal floating point between 0 and 5.
      working_graph.add_edge(
          qubit, neighbor, weight=np.random.randint(0, 500) / 100
      )

nx.draw_circular(working_graph, node_size=1000, with_labels=True)
plt.show()
```

## 2. Construct the QAOA circuit
Now that we have created a Max-Cut problem graph, it's time to generate the QAOA circuit following [Farhi et al.](https://arxiv.org/abs/1411.4028). For simplicity $p = 1$ is chosen.

```
from cirq.contrib.svg import SVGCircuit

# Symbols for the rotation angles in the QAOA circuit.
alpha = sympy.Symbol('alpha')
beta = sympy.Symbol('beta')

qaoa_circuit = cirq.Circuit(
    # Prepare uniform superposition on working_qubits == working_graph.nodes
    cirq.H.on_each(working_graph.nodes()),

    # Do ZZ operations between neighbors u, v in the graph. Here, u is a qubit,
    # v is its neighboring qubit, and w is the weight between these qubits.
    (cirq.ZZ(u, v) ** (alpha * w['weight']) for (u, v, w) in working_graph.edges(data=True)),

    # Apply X operations along all nodes of the graph. Again working_graph's
    # nodes are the working_qubits. Note here we use a moment
    # which will force all of the gates into the same line.
    cirq.Moment(cirq.X(qubit) ** beta for qubit in working_graph.nodes()),

    # All relevant things can be computed in the computational basis.
    (cirq.measure(qubit) for qubit in working_graph.nodes()),
)
SVGCircuit(qaoa_circuit)
```

    findfont: Font family ['Arial'] not found. Falling back to DejaVu Sans.

## 3. Calculating the expected value of the QAOA cost Hamiltonian
Now that we have created a parameterized QAOA circuit, we need a way to calculate expectation values of the cost Hamiltonian. For Max-Cut, the cost Hamiltonian is

$$
    H_C = \frac{1}{2} \sum_{\langle i, j\rangle} w_{ij} (1 - Z_i Z_j )
$$

where $\langle i, j \rangle$ denotes neighboring qubits, $w_{ij}$ is the weight of edge $ij$, and $Z$ is the usual Pauli-$Z$ matrix. The expectation value of this cost Hamiltonian is $\langle \alpha, \beta | H_C | \alpha, \beta \rangle$ where $|\alpha, \beta\rangle$ is the quantum state prepared by our `qaoa_circuit`. This is the cost function we need to estimate.

> Pauli-$Z$ has eigenvalues $\pm 1$. If qubits $i$ and $j$ are in the same eigenspace, then $\langle Z_i Z_j \rangle = 1$ and so $\frac{1}{2} w_{ij} \langle 1 - Z_i Z_j \rangle = 0$. In the Max-Cut language, this means that edge $ij$ does not contribute to the cost. If qubits $i$ and $j$ are in the opposite eigenspace, then $\langle Z_i Z_j \rangle = -1$ and so $\frac{1}{2} w_{ij} \langle 1 - Z_i Z_j \rangle = w_{ij}$. In the Max-Cut language, this means that edge $ij$ contributes its weight $w_{ij}$ to the cost.

To estimate the cost function, we need to estimate the (weighted) sum of all $ZZ$ pairs in the graph. Since these terms are diagonal in the same basis (namely, the computational basis), they can measured simultaneously. Given a set of measurements (samples), the function below estimates the cost function.

> *Note*: We say "estimate the cost" instead of "compute the cost" since we are sampling from the circuit. This is how the cost would be evaluated when running QAOA on a real quantum processor.

```
def estimate_cost(graph, samples):
    """Estimate the cost function of the QAOA on the given graph using the
    provided computational basis bitstrings."""
    cost_value = 0.0

    # Loop over edge pairs and compute contribution.
    for u, v, w in graph.edges(data=True):
      u_samples = samples[str(u)]
      v_samples = samples[str(v)]

      # Determine if it was a +1 or -1 eigenvalue.
      u_signs = (-1)**u_samples
      v_signs = (-1)**v_samples
      term_signs = u_signs * v_signs

      # Add scaled term to total cost.
      term_val = np.mean(term_signs) * w['weight']
      cost_value += term_val

    return -cost_value
```

Now we can sample from the `qaoa_circuit` and use `estimate_expectation` to calculate the expectation value of the cost function for the circuit. Below, we use arbitrary values for $\alpha$ and $\beta$.

```
alpha_value = np.pi / 4
beta_value = np.pi / 2
sim = cirq.Simulator()

sample_results = sim.sample(
    qaoa_circuit,
    params={alpha: alpha_value, beta: beta_value},
    repetitions=20_000
)
print(f'Alpha = {round(alpha_value, 3)} Beta = {round(beta_value, 3)}')
print(f'Estimated cost: {estimate_cost(working_graph, sample_results)}')
```

    Alpha = 0.785 Beta = 1.571
    Estimated cost: -0.22279300000000013

## 4. Outer loop optimization
Now that we can compute the cost function, we want to find the optimal cost. There are lots of different techniques to choose optimal parameters for the `qaoa_circuit`. Since there are only two parameters here ($\alpha$ and $\beta$), we can keep things simple and sweep over incremental pairings using `np.linspace` and track the minimum value found along the way.

```
# Set the grid size = number of points in the interval [0, 2π).
grid_size = 5

exp_values = np.empty((grid_size, grid_size))
par_values = np.empty((grid_size, grid_size, 2))

for i, alpha_value in enumerate(np.linspace(0, 2 * np.pi, grid_size)):
  for j, beta_value in enumerate(np.linspace(0, 2 * np.pi, grid_size)):
    samples = sim.sample(
        qaoa_circuit,
        params={alpha: alpha_value, beta: beta_value},
        repetitions=20000
    )
    exp_values[i][j] = estimate_cost(working_graph, samples)
    par_values[i][j] = alpha_value, beta_value
```

We can now visualize the cost as a function of $\alpha$ and $\beta$.

```
plt.title('Heatmap of QAOA Cost Function Value')
plt.xlabel(r'$\alpha$')
plt.ylabel(r'$\beta$')
plt.imshow(exp_values);
```

This heatmap is coarse because we selected a small `grid_size`. To see more detail in the heatmap, one can increase the `grid_size`.

## 5. Compare cuts

We now compare the optimal cut found by QAOA to a randomly selected cut. The helper function draws the `working_graph` and colors nodes in different sets different colors. Additionally, we print out the cost function for the given cut.

```
def output_cut(S_partition):
  """Plot and output the graph cut information."""

  # Generate the colors.
  coloring = []
  for node in working_graph:
    if node in S_partition:
      coloring.append('blue')
    else:
      coloring.append('red')

  # Get the weights
  edges = working_graph.edges(data=True)
  weights = [w['weight'] for (u,v, w) in edges]

  nx.draw_circular(
      working_graph,
      node_color=coloring,
      node_size=1000,
      with_labels=True,
      width=weights)
  plt.show()
  size = nx.cut_size(working_graph, S_partition, weight='weight')
  print(f'Cut size: {size}')
```

As an example, we can test this function with all nodes in the same set, for which the cut size should be zero.

```
# Test with the empty S and all nodes placed in T.
output_cut([])
```

To get cuts using the QAOA we will first need to extract the best control parameters found during the sweep:

```
best_exp_index = np.unravel_index(np.argmax(exp_values), exp_values.shape)
best_parameters = par_values[best_exp_index]
print(f'Best control parameters: {best_parameters}')
```

    Best control parameters: [3.14159265 6.28318531]

Each bitstring can be seen as a candidate cut in the graph. The qubits that measured 0 correspond to that qubit being in one cut partition and a qubit that measured to 1 corresponds to that qubit being in the other cut partition. Now that we've found good parameters for the `qaoa_circuit`, we can just sample some bistrings, iterate over them and pick the one that gives the best cut:

```
# Number of candidate cuts to sample.
num_cuts = 100
candidate_cuts = sim.sample(
    qaoa_circuit,
    params={alpha: best_parameters[0], beta: best_parameters[1]},
    repetitions=num_cuts
)

# Variables to store best cut partitions and cut size.
best_qaoa_S_partition = set()
best_qaoa_T_partition = set()
best_qaoa_cut_size = -np.inf

# Analyze each candidate cut.
for i in range(num_cuts):
  candidate = candidate_cuts.iloc[i]
  one_qubits = set(candidate[candidate==1].index)
  S_partition = set()
  T_partition = set()
  for node in working_graph:
    if str(node) in one_qubits:
      # If a one was measured add node to S partition.
      S_partition.add(node)
    else:
      # Otherwise a zero was measured so add to T partition.
      T_partition.add(node)

  cut_size = nx.cut_size(
      working_graph, S_partition, T_partition, weight='weight')

  # If you found a better cut update best_qaoa_cut variables.
  if cut_size > best_qaoa_cut_size:
    best_qaoa_cut_size = cut_size
    best_qaoa_S_partition = S_partition
    best_qaoa_T_partition = T_partition
```

The QAOA is known to do just a little better better than random guessing for Max-Cut on 3-regular graphs at `p=1`. You can use very similar logic to the code above, but now instead of relying on the QAOA to decied your `S_partition` and `T_partition` you can just pick then randomly:

```
import random

best_random_S_partition = set()
best_random_T_partition = set()
best_random_cut_size = -9999

# Randomly build candidate sets.
for i in range(num_cuts):
  S_partition = set()
  T_partition = set()
  for node in working_graph:
    if random.random() > 0.5:
      # If we flip heads add to S.
      S_partition.add(node)
    else:
      # Otherwise add to T.
      T_partition.add(node)

  cut_size = nx.cut_size(
      working_graph, S_partition, T_partition, weight='weight')

  # If you found a better cut update best_random_cut variables.
  if cut_size > best_random_cut_size:
    best_random_cut_size = cut_size
    best_random_S_partition = S_partition
    best_random_T_partition = T_partition
```

```
print('-----QAOA-----')
output_cut(best_qaoa_S_partition)

print('\n\n-----RANDOM-----')
output_cut(best_random_S_partition)
```

For this problem instance, one should see that $p = 1$ QAOA performs better, on average, than randomly guessing.


```python
from IPython.core.display import display_html
from urllib.request import urlopen

cssurl = 'http://j.mp/1DnuN9M'
display_html(urlopen(cssurl).read(), raw=True)
```

<link href='http://fonts.googleapis.com/css?family=EB+Garamond' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Lato:100,100italic' rel='stylesheet' type='text/css'>

<style>
	@font-face{
   		font-family: "Computer Modern";
        	src: url('http://mirrors.ctan.org/fonts/cm-unicode/fonts/otf/cmunss.otf');}

        div.cell{
	        max-width:    800px;
	        margin-left:  auto;
	        margin-right: auto;}

	h1 {
        	font-family: 'Lato', sans-serif;}

	h2 {
        	font-family: 'Lato', serif;}

	h3{
		font-family:   'Lato', serif;
        	margin-top:    12px;
		margin-bottom: 3px;}

        h4{
		font-family: 'Lato', serif;}

	h5 {
        	font-family: 'Lato', serif;}

	div.text_cell_render{
        	font-family:  'EB Garamond', 'Computer Modern', 'Helvetica Neue', Arial, Helvetica, Geneva, sans-serif;
	        line-height:  140%;
	        font-size:    14pt;
		max-width:    650px;
		margin-left:  auto;
        	margin-right: auto;}

	.CodeMirror{
        	font-family: 'Consolas';}

	.text_cell_render h1 {
	        font-weight:   100;
	        font-size:     48pt;
		line-height:   100%;
	        color:         #CD2305;
	        margin-bottom: 0.5em;
	        margin-top:    0.5em;
	        display:       block;}

	.text_cell_render h2 {
        	font-weight:   100;
        	font-size:     36pt;}

	.text_cell_render h3 {
        	font-weight:   100;
        	font-size:     21pt;}

	.text_cell_render h4 {
        	font-weight:   100;
        	font-size:     18pt;}

	.text_cell_render h5 {
	        font-weight:   100;
	        font-size:     16pt;
	        color:         #CD2305;
	        font-style:    italic;
	        margin-bottom: 0.5em;
	        margin-top:    0.5em;
	        display:       block;}

	.text_cell_render h6 {
	        font-weight:   100;
	        font-size:     14pt;
	        color:         #CD2305;
	        font-style:    italic;
	        margin-bottom: 0.5em;
	        margin-top:    0.5em;
	        display:       block;}

	.warning{
	    	background-color: #FFFFE0;
	    	border-color: #FFCC99;
	    	border-left: 5px solid #FFCC99;
	    	padding: 0.5em;}

	.error{
	    	background-color: #fcf2f2;
	    	border-color: #dFb5b4;
	    	border-left: 5px solid #dfb5b4;
	    	padding: 0.5em;}

</style>

# Tarea 8

## Transformada de Laplace de una integral de convolución

Queremos obtener:

$$
\mathcal{L} \left\{ \int_{-\tau}^0 G(\theta) x(\tau + \theta) d\theta \right\}
$$

Podemos definir la integral de convolución para dos funciones continuas $f(t)$ y $g(t)$, tales que la convolución $(f*g)(t)$ es de la forma:

$$
(f*g)(t) = \int_0^t f(t - \tau) g(\tau) d\tau
$$

y la transformada de Laplace de esta integral de convolución es:

$$
\mathcal{L} \left\{ (f*g)(t) \right\} = F(s)G(s)
$$

por lo que nos interesa poner nuestra integral original de manera que sea una integral de convolución.

Podemos ver que al aplicar el cambio de variable $\delta = \theta + \tau$, cuando $\theta$ variaba de $-\tau \to 0$, $\delta$ variará de $0 \to \tau$ y el diferencial $d\theta$ es equivalente a $d\delta$, por lo que nuestra integral quedará:

$$
\mathcal{L} \left\{ \int_{0}^{\tau} G(\delta - \tau) x(\tau + \delta - \tau) d\delta \right\} = \mathcal{L} \left\{ \int_{0}^{\tau} G(\delta - \tau) x(\delta) d\delta \right\}
$$

y etsa integral ya es de la forma de la integral de convolución, por lo que podemos escribirla como:

$$
\mathcal{L} \left\{ (G*x)(t) \right\} = G(s) x(s)
$$

## Diseño de un controlador predictivo para un sistema con retardo en la entrada

Dado el sistema con retardo en la entrada:

$$
\dot{x}(t) = A x(t) + B u(t - h)
$$

$$
y(t) = C x(t)
$$

Empezaremos creando un modelo sin retardo para el diseño del controlador predictor de Smith. Si logramos diseñar un controlador $C(s)$ que estabilice de manera aceptable al sistema sin retardos, podremos diseñar otro $\tilde{C}(s)$ que tenga el mismo comportamiento agregado el efecto del retardo.

en donde $\tilde{C}(s)$ será de la forma:

es decir:

$$
\tilde{C}(s) = \frac{C(s)}{1 + C(s) \hat{G}(s) \left( 1 - e^{-sh} \right)}
$$

en donde $\hat{G}(s)$ es la parte de la función de transferencia del sistema que no incluye al retardo. Por lo que nuestra primera tarea es encontrar la función de transferencia para nuestro sistema sin el efecto del retardo.

Consideremos pues el sistema

$$
\dot{x}(t) = A x(t) + B u(t)
$$

$$
y(t) = C x(t)
$$

para el cual la función de transferencia se puede obtener por la siguiente ecuación:

$$
\hat{G}(s) = C \left( sI - A \right)^{-1} B
$$

cabe mencionar que la función de transferencia para el sistema con retardo es:

$$
G(s) = C \left( sI - A \right)^{-1} B e^{-sh}
$$

por lo que en efecto $\hat{G}(s)$ es la parte de la función de transferencia del sistema sin el efecto del retardo:

$$
G(s) = \hat{G}(s) e^{-sh}
$$

```python
# Se importan las librerias para calculo simbolico
from IPython.display import display

from sympy import var, simplify, collect, expand, solve, sin, cos, Matrix, eye, diff, Function, expand_power_base
from sympy.physics.mechanics import mlatex, mechanics_printing
mechanics_printing()
```

```python
%matplotlib inline
from matplotlib.pyplot import plot, style, figure, legend
style.use("ggplot")
```

```python
from control import tf, step, pade, acker, ss, feedback
from numpy import linspace, matrix, eye
```

```python
var("s")
```

Empezaremos con el sistema $A_1 = \begin{pmatrix} 0 & 1 \\ 0 & 0 \end{pmatrix}$, $B_1 = \begin{pmatrix} 0 \\ 1 \end{pmatrix}$, $C_1 = \begin{pmatrix} 1 & 0 \end{pmatrix}$ y $h = 1$.

```python
A1 = Matrix([[0, 1], [0, 0]])
B1 = Matrix([[0], [1]])
C1 = Matrix([[1, 0]])

G1 = (C1*(s*eye(2) - A1).inv()*B1)[0]
G1
```

```python
t = linspace(0, 10, 100)
t.max()
```

Podemos notar que la función de transferencia de este sistema es:

$$
G(s) = \frac{1}{s^2}
$$

```python
# Convertimos las matrices simbolicas en matrices de tipo numerico
A1 = matrix(A1.tolist(), dtype=float)
B1 = matrix(B1.tolist(), dtype=float)
C1 = matrix(C1.tolist(), dtype=float)
```

Para obtener dos polos en $-1$ podemos usar la función ```acker()``` para obtener las ganancias de nuestro controlador PD, el cual utilizaremos para estabilizar nuestro sistema.

```python
k1 = acker(A1, B1, (-1, -1))
k1
```

    matrix([[ 1.,  2.]])

Definimos una función que calculará todos los controladores que deseamos, segun la ecuación que ya dimos:

$$
\tilde{C}(s) = \frac{C(s)}{1 + C(s) \hat{G}(s) \left( 1 - e^{-sh} \right)}
$$

Al final gráfica la respuesta del sistema con y sin efecto del retardo, asi como con y sin controlador.

```python
def smith_predictor(A, B, C, D, k, tau=1, t=(0, 10)):
    '''Predictor de Smith

    Esta función toma los arreglos A, B, C, D de un sistema con retardo en la entrada
    y crea un controlador PD con los valores de k = [kp, kd] que estabiliza al sistema
    sin retardos. Ademas crea un controlador que estabiliza al sistema con retardo,
    dada la condición de que este sistema sea estable, y grafica la salida de los
    con y sin realimentación y con y sin retardo tau del tiempo t0 al tiempo t1
    especificados en t = (t0, t1).

    Ejemplo
    -------
    >>> A1 = [[0, 1], [0, 0]]
    >>> B1 = [[0], [1]]
    >>> C1 = [[1, 0]]
    >>> D1 = 0
    >>> tau1 = 1
    >>> t = (0, 10)
    >>> smith_predictor(A1, B1, C1, D1, [1, 2], tau, t)
    '''
    from control import ss, tf, pade, step, feedback
    from numpy import linspace
    from matplotlib.pyplot import figure, plot, legend

    kp, kd = k
    ts = linspace(t[0], t[1], 1000)

    sis = ss(A, B, C, D)
    cont = tf([kd, kp], [0, 1])

    num, den = pade(T=tau, n=10)
    delay = tf(num, den)

    delcont = ((1 - delay)*sis)

    y, t1 = step(sis, ts)
    yd, td = step(sis*delay, ts)
    ycont, tcont = step((cont*sis).feedback(), ts)
    ycontdel, tcontdel = step(feedback(feedback(cont, delcont)*sis), ts)

    f = figure(figsize=(10, 6))

    p1, = plot(td, yd)
    p2, = plot(t1, y)
    p3, = plot(tcont, ycont)
    p4, = plot(tcontdel, ycontdel)

    ax = f.gca()
    ax.set_xlim(t[0] - 0.1, t[1])
    ax.set_ylim(-0.10*ycont.max(), 1.1*ycont.max())

    ax.set_ylabel(r"$y(t)$", fontsize=20)
    ax.set_xlabel(r"$t$", fontsize=20)

    legend([p1, p2, p3, p4],
           [r"$G(s)$",
            r"$\hat{G}(s)$",
            r"$\hat{G}_F(s)$",
            r"$G_F(s)$"], loc=4, fontsize=16);
```

Por lo que si le damos nuestro sistema con las ganancias deseadas, asi como el tiempo para el que nos interesa, y el retardo, tendremos:

```python
smith_predictor(A1, B1, C1, 0, k=[3, 3], t=(0, 7), tau=1)
```

Ahora definimos el sistema $A_2 = \begin{pmatrix} 0 & 1 \\ -1 & 0 \end{pmatrix}$, $B_2 = \begin{pmatrix} 0 \\ 1 \end{pmatrix}$, $C_2 = \begin{pmatrix} 1 & 0 \end{pmatrix}$ y $h = 1$.

```python
A2 = Matrix([[0, 1], [-1, 0]])
B2 = Matrix([[0], [1]])
C2 = Matrix([[1, 0]])

G2 = (C2*(s*eye(2) - A2).inv()*B2)[0]
G2
```

Por lo que la función de transferencia de este sistema es:

$$
G(s) = \frac{1}{s^2 + 1}
$$

```python
# Convertimos las matrices simbolicas en matrices de tipo numerico
A2 = matrix(A2.tolist(), dtype=float)
B2 = matrix(B2.tolist(), dtype=float)
C2 = matrix(C2.tolist(), dtype=float)
```

Para obtener dos polos en $-1$ podemos usar la función ```acker()``` para obtener las ganancias de nuestro controlador PD.

```python
k2 = acker(A2, B2, (-1, -1))
k2
```

    matrix([[ 0.,  2.]])

Y la respuesta del sistema es:

```python
smith_predictor(A2, B2, C2, 0, k=[3, 3], t=(0, 8))
```

Puedes acceder a este notebook a traves de la página

http://bit.ly/1wiwlpl

o escaneando el siguiente código:

```python
# Codigo para generar codigo :)
from qrcode import make
img = make("http://bit.ly/1wiwlpl")
img.save("codigos/codigo8.jpg")
```

IPythonNotebooks/Sistemas con retardo en la entrada/Tarea 8.ipynb


Project 1: Arduino as a Laboratory Interface
========================

The purpose of this project is twofold:

1. to familiarize yourself with some of the tools we'll be using in this course: the Arduino compiler, simulator, and microcontroller, electronic breadboards, oscilloscopes, "C" programming, "python" programming and jupyter notebooks, AND

2. to build a simple circuit that enables us to study the behvior of an LED.

As you progress through the project please be sure to ask questions and get help if you are confused or unclear on how to proceed. Since most students taking this course have used python in intro physics, and have at least one course in programming computers in "c" or "c++". As a result the treatment of those topics will be fairly brief. If you have not use python and/or c/c++ before please alert your instructor and they will provide you with extra materials and instruction as necessary.

Here are some references you may find helpful:

1. [Dive into python](https://diveintopython3.problemsolving.io) (intro to the python language) [http://python.org](http://python.org)
2. Arduino Simulator [http://tinkercad.com](http://tinkercad.com) (this simulator also simulates components and breadboards!)
3. Arduino programming [http://arduino.cc](http://arduino.cc)
4. Intro to C programming: [C programming text](http://www-personal.acfr.usyd.edu.au/tbailey/ctext/ctext.pdf)

We're going to jump right into using python and "C". You should consult the references here to dig deeper, but we'll go over what you need for now. For this project we'll be completing a series of tasks:

Tasks:
-------

1. Set up the circuit [shown below](#Project-1-Schematic-Diagram). Choose values for R1 and R2 that make sense. Ask if you need help!

2. [Program your Arduino](#Arduino-Programming) to collect data as you adjust the driving current through the diode.

2. Run the program to collect voltage vs. time data from the Arduino

3. Analyze (you may read the data into excel, but please use jupyter to do any fitting).

4. Compare results with expectations. See the example [linear](#Linear-Analysis) and [non-linear](#Non-Linear-Analysis) analysis python programs given below.

5. Carry out the [Statistical Exercises](Normal%20Distribution%20and%20Estimation%20of%20Parameters.ipynb) for project one.

6. Submit a project report describing your results.

Criteria for success:

See the [rubric](../report_rubric.pdf) and the [sample](../sample/Sample%20Report.ipynb).

Controlling a Voltage with Arduino
--------------------------------

The next few cells we'll be reviewing the charging and discharging of capacitors. We need this because we'll be using an RC circuit to control the driving voltage across the diode circuit that forms the core of this project.

Charging and Discharging Capacitors
---------------------------------

Let's start with RC Circuits. Suppose we have a charging circuit like that shown in Fig 1 where the voltage source (V1 in Fig. 1) can be turned on and off periodicallly. This produces a current that alternately charges and discharges the capacitor. Suppose the voltage supplied by V1 is 10V when it's "on" and 0V when it's "off". If we assume the capacitor is initially uncharged when V1 is first turned on, there will be a potential drop of 10V across the resistor R1 initially. This will produce an initial current of 10V/10k$\Omega$ = 1mA. As the capacitor charges this current will diminish, approaching zero in a few RC time constants (in this case, as you can see from Fig. 1, RC=50ms). If the source is set up to toggle between "on" and "off" every 500ms, there will be ample time for the capacitor to become very nearly fully charged before the voltage toggles to "off". When the voltage does toggle "off" the current will flow in the opposite direction slowly draining the charge on the capacitor. As you learned in intro physics the voltage on the capacitor as a function of time during the charging and discharging cycles is exponential (see e.g., Chabay & Sherwood, vII, 4th ed, pp785-786).

\begin{equation}
V(t) = V_0\left(1-e^{-t/RC}\right); {\rm (charging)}
\end{equation}

\begin{equation}
V(t) = V_0 e^{-t/RC}; {\rm (discharging)}
\end{equation}

Let's use some python to visualize this result.

```python
# invoke the matplotlib magic to get access to plot inline
#
%matplotlib inline
import matplotlib.pyplot as pl # plotting library
import numpy as np             # numerical library

#
# Set up some constants
#
V0=10.0 # Volts
R1=10e3 # Ohms
C1=5e-6 # Farads

"""
for the first 0.25 sec we'll be charging.
"""
t1 = np.linspace(0, 0.25, 100)     # time array, 100 values evenly spaced beteen 0 and 0.25 seconds
Vc = V0*(1.0-np.exp(-t1/(R1*C1)))  # array of voltages on the capacitor at different times
pl.xlabel('time (s)')              # make the graph purty, give it x and y labls and a title
pl.ylabel('capacitor voltage (V)')
pl.title("Voltage on capacitor during charging cycle")
pl.grid()                          # add a grid so it's easier to read
pl.plot(t1, Vc, 'b-')              # plot the data, t1 on the horizontal, Vc on the vertical, using a blue line
```

You can see how the capacitor voltage is very close to 10V at the end of the 250ms charging cycle.

```python
Vf = Vc[-1]   # take the last voltage in the Vc array and check it. Note that a '-1' index gets the last value
print(Vf)
```

    9.932620530009146

So, the voltage on the capacitor is about 68mV shy of 10V. Or, if you'd like (using a cash analog) we could've gotten up to a \$10 reward, but we still have a mere 7 cents to go.

Close!

What about the discharging?

```python
Vc2 = Vf*np.exp(-t1/(R1*C1))       # compute the voltage during the discharge cycle.
pl.xlabel('time (s)')              # make the graph purty
pl.ylabel('capacitor voltage (V)')
pl.title("Voltage on capacitor during discharge cycle")
pl.grid()
pl.plot(t1, Vc2, 'b-') # plot the data, t1 on the horizontal, Vc2 on the vertical using a blue line

Vf2 = Vc2[-1] # take the last voltage
print("The final voltage after 250ms of discharge is:", Vf2)
```

Again (using a cash analogy), here we started with \$9.93 and we ended up with less than 7 cents in the end.

Practically nothing. ;-)

You should familiarize yourself with these equations. Here are some questions to help you check your understanding:

1. What is the voltage on the capacitor at 0.1s after the voltage source turns "on"? (ans 8.65V)

2. What is the voltage on the capacitor at 0.15s after the voltage source turns "off"? (ans 0.50V)

3. How long after the voltage source turns "on" does the voltage on the capacitor reach 5V? (ans 0.035s)

4. How long after the voltage source turns "off" does the voltage on the capacitor reach 2V? (ans 0.080s)

We can also use LTSpice to simulate this circuit.

How is this relevant?
------------------------

The output pins on a basic Arduino are digital. This means they can either be set "high" (typically 5V, or sometimes 3.3V) or "low" (usually 0V), but nothing in-between. We wish to adjust the current flowing through a device (in this case, an LED) and make simultaneous measurements of the voltage drop across the diode over a range of voltages and currents.

# So what are we doing?

This week we'll be using the Arduino <http://arduino.cc> microcontroller to study the behavior of an LED. The idea is to drive the LED with different currents and to measure the voltage drop across the LED. There is a standard model ([https://en.wikipedia.org/wiki/Shockley_diode_equation](https://en.wikipedia.org/wiki/Shockley_diode_equation)) for this relationship:

$$ I = I_o (e^{\frac{q V_d}{\eta k_b T}}-1) $$

We'll want to compare the data we collect with the predictions of this model.

What follows is an introduction to Arduino programming. If you've already coded a lot in "C" or "C++" this should all be pretty easy. If you haven't, it's time to learn! The good news is that our coding will be pretty elementary. All we really need are simple loops, variables, arrays and functions.

Arduino Programming
------------------

If you open the Arduino IDE and choose File -> Examples -> Basic -> Blink you'll find this code in your IDE window:

    /*
      Blink
      Turns on an LED on for one second, then off for one second, repeatedly.

      Most Arduinos have an on-board LED you can control. On the Uno and
      Leonardo, it is attached to digital pin 13. If you're unsure what
      pin the on-board LED is connected to on your Arduino model, check
      the documentation at http://arduino.cc

      This example code is in the public domain.

      modified 8 May 2014
      by Scott Fitzgerald
     */

    // the setup function runs once when you press reset or power the board
    void setup() {
      // initialize digital pin 13 as an output.
      pinMode(13, OUTPUT);
    }

    // the loop function runs over and over again forever
    void loop() {
      digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(1000);              // wait for a second
      digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
      delay(1000);              // wait for a second
    }

You can actually run this on your Arduino right away! Make sure you go to Tools -> Board and select the correct Arduino type. Then go to "Tools -> Port" and select the serial port to which your Arduino is assigned. (If you diconnect, then check "Tools -> Port", then reconnect and check "Tools -> Port" again you shoud be able to see which is the "new" port in the list the corresponds to your Arduino.)

Let's go through this code and describe what's happening.

If you've already taken "c/c++" programming you'll be familiar with most of these ideas right away. If you've not taken a programming course you may need some extra support/documentation. Please see me if this is the case and I'll be sure to provide some additional resources.

First the program is processed by a 'compiler' that reads the text and interprets it as a set of steps to be translated into machine instructions for the microcontroller. Lines in the text that start with a "#" are meant to be processed *before* the translation process begins, so these are called "compiler directives" rather than instructions.

Next, anything between '/*' and '*/' is a comment. Anything after '//' on a line, is a comment.

There are two critical functions in an Ardiuno program 'setup' and 'loop'.

Setup
-----

The 'setup' function is executed any time the Arduino is reset. This happens:

1. when you upload a new program
2. when you first connect with a serial port
3. when you push the reset button, or
4. when ground the reset pin.

Let's look at the setup function for this example. Note that it only does one thing: declare that pin 13 on the Arduino is going to be used for output.  It turns out pin 13 on most Arduinos is connected to an LED, so when the pin goes high, you can see light. Other things that typically happen in setup are initialization of variables, arrays, setting various ports' intial values and generally getting things ready to go.

    void setup() {
      // initialize digital pin 13 as an output.
      pinMode(13, OUTPUT);
    }

Loop
----

The 'loop' function is called immediately after 'setup'. After loop completes it is called again, and again, and again, forever (or until power is removed/lost, or the board is reset). The loop function is where most of the work of the program happens.

    void loop() {
      digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(1000);              // wait for a second
      digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
      delay(1000);              // wait for a second
    }

This program's 'loop' function first sets pin 13 high, waits for 1 sec, then sets pin 13 low, waits another second, then exits. This lights the LED, then turns it off, over and over, each second, forever. Notice that this is a *lot* like the voltage source in our example circuit! In fact, that similarity is exactly what we'll use to develop this project.

Basic Concepts in "c"
===========

In case you're not very familiar with the "c" programming language, these explanations may help get you up to speed.

Macros
------

In the example program there is a line:

    digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)

it's a bit hard to tell what's going on. The reader may not remember/realize that pin 13 is connected to the built-in LED on the Arduino. Wouldn't it be nice if we could communicate that to them in some simple way? That's one of the most useful applications of a commonly used compiler directive called a "macro". You can create your own macros (I like to do this at the very beginning of my programs, so they are easy to find). Here's how it works:

    #define LED 13            // Pin 13 is the LED

The first character on the line is '#', which tells the compiler that it's a special directive, not a step in the program. The 'define' means we're defining a macro, in this case a constant. When the compiler sees this macro it then knows that anywhere in the program that has 'LED' it's to be replaced by the value '13'. Then our digitalWrite function call looks like this:

    digitalWrite(LED, HIGH);   // turn the LED on (HIGH is the voltage level)

Isn't that clearer? Of course it is. ;-) Below is a list of macros that we can use to define constants needed by the program to run project 1.

    #define OUTPIN 3          // apply output voltage to pin 3
    #define IN_ANALOG 0       // which analog pin are we reading?
    #define NUMVALUES 40      // how much data to collect?
    #define STARTUP_DELAY 500 // how long to hold voltage high initially
    #define DECAY_DELAY   10  // how long to measure
    #define LOOP_DELAY 500    // how many millis to delay each time

Because these definitions are constant, they can't be changed during execution. It is a convention to use all upper case characters in the names of constants so the reader can tell that these things are not variable in the context in which they appear.

Variables
---------

Most programs need some values that can change. These are *variables*. A variable needs to be decared with a type and within a scope. The *type* of a variable determines the amount of memory required for the variable's value and the scope determines the times during which the variable is needed during program execution. Basically if the variable is declared outside of any function, it's scope is *global* and it is always available. If it is declared within a function it's scope is *local* (only within the function). It's memory is 'allocated' within the function, and 'released' outside the function. Let's look at an example:

    int x;

This declares `x` to be an integer (16 bits on the Arduino) and since it's not inside a function, it's scope is global. Here's another:

    int foo(int y) {
        int x=y;

        if (y>9) {
            x = 3*y;
        }

        return 100 - x;
    }

Here `x` is a local variable that is only defined within the function `foo`. You can see that it is used as a part of computing the result of the function. If you tried to access the value of `x` outside this function the compiler would complain that `x` is undefined.

Arrays
------

An array is a collection of memory of a particular type. An array is declared using square brakets: `[]` like so:

    int myArray[16];

this would allocated an array called `myArray` with space for 16 integers. You can access individual elements within the array by using that particular element's address or `index`. The index values start at zero and go up to one less than the number of elements, in this case, 15. For example to set the `zeroth` element of `myArray` to 9 you'd use:

    myArray[0] = 9;

An array element can be use just like a normal variable. We will find an array useful so that we can aqcuire and save data quickly.

Handling Conditions
------------------

Sometimes we want one thing to happen `if` a variable has one value, and something `else` to happen if it has a different value. This is most easily accomplished using an `if` statement. Here is a simple example. Suppose we have a heater and a temperature sensor. We decide that we want the heater to run if the temperature sensor measures any voltage *below* 0.488V, and we want to turn it off if it measures *above* 0.488V. Suppose further that the temperature sensor is connected to analog input pin 0, and the heater is connected to digital output pin 3. This code would do the trick:

    #define IN_ANALOG 0
    #define OUT_DIGITAL 3

    int val;  // val will get the integer representation of the input voltage

    val = analogRead(IN_ANALOG);  // read current value on IN_ANALOG pin, val is between 0 and 1023.

    if (val < 100) {
        Serial.println("Voltage is below 0.488 Volts");
        digitalWrite(OUT_DIGITAL, HIGH);  // turn the heater on
    } else {
        Serial.println("Volgate is above 0.488 Volts");
        digitalWrite(OUT_DIGITAL, LOW);   // turn the heater off
    }

The `AnalogRead` function is used to measure analog voltages on the analog input pins of the Arduino Microcontroller. Voltages bewteen 0.0V and 5.0V are mapped onto integer values between 0 and 1023. The `DigitalWrite` function sets an output pin `high` (which is 5.0V) or `low` (which is 0.0V) as shown. This example sets pin 3 high (5V) if the voltage on analog input 0 is below 0.488 Volts and sets pin 3 low (0V) if the voltage on analog input 0 is above 0.488 V.

For Loops
---------

There are several different ways to create looping behaviors in "c", but the most common is the `for` loop. Here is an example `for` loop that sets all the elements of `myArray` to zero.

    #define N 16

    int i;
    int myArray[N];

    for (i=0; i<N; i++) {
        myArray[i] = 0;
    }

The `for` loop begins with `for` and contains a set of three expressions (clauses) separated by semi-colons. The three expressions:

1. initialize the loop control variable(s), `(i=0)`
2. check to see if the loop should continue and `(i<N)`
3. update the loop control variables `(i++)`

respectively. Let's look at those parts one at a time. First `i` is initialized to zero. This way we know where things are starting. Since the goal of this loop is to set all the elements of `myArray` to zero this means we'll be starting with the `zeroth` element. Before the loop exectutes each iteration it evaluates the middle clause to see if it should continue execution. In this case it checks to see if `i<N`. Since `N` is `#define`ed to be 16, this is checking to make sure `i<16`. The first time through the loop `i=0` so this is clearly satisfied. Remeber that the last element of the array has an index `i=15` so checking that `i<16` will allow no higher index than this. Good! Each time the loop completes the `update` clause `(i++)` is exectuted. `i++` is shorthand in "c" for `i=i+1`. This increments the loop control variable `i` by one at the end of each iteration. Note the net effect is that the loop is exectuted once for each value of `i` from `i=0` to `i=15`.

Functions
---------

A function is a body of code that encapsulates some operation. Sometimes functions produce a result that is desired, sometimes they produce side effects that are needed. Here is an example function that produces a result:

    int foo(x) {
        return 3*x;
    }

The function `foo` accepts an integer argument and returns a result that is three times the value of the argument passed. Yes, it's a silly function, but you get the idea. Here is a function that has a side effect:

    void updateHeater(int threshold) {
        int val;  // val will get the integer representation of the input voltage

        val = analogRead(IN_ANALOG);  // read current value on IN_ANALOG pin, val is between 0 and 1023.

        if (val < threshold) {
            digitalWrite(OUT_DIGITAL, HIGH);  // turn the heater on if val < threshold
        } else {
            digitalWrite(OUT_DIGITAL, LOW);   // otherwise turn the heater off
        }
    }

So you can call `updateHeater(100)` and it will turn the heater on or off based on a threshold of 100. Note that as a general rule of coding *style* it's preferable to create functions that

1. return a result, but have no side effects OR
2. have side effects, but return no result

Communication
------------

You can send and receive data over the serial port using the [Serial object](https://www.arduino.cc/en/Reference/Serial) on the Arduino. We'll learn more of the details as the course continues. For this week we only need two functions: `print` [(documentation)](https://www.arduino.cc/en/Serial/Print) and: `println` [(documentation)](https://www.arduino.cc/en/Serial/Println). The primary difference between these is that the `println` version sends a carriage return/linefeed so that the next thing printed will be on a new line. You can print(ln) any single value, integer, float or a string of characters. For floating point values you can specify the number of digits past the decimal point as an optional second argument. So, the following program:

    int x=3;
    float y=2.345;

    void setup() {
      Serial.begin(9600);
      Serial.print("The answer is:");
      Serial.print(x);
      Serial.print(",");
      Serial.println(y, 2);
    }

would print out:

    The answer is:3,2.35

Note that the floating point value is rounded to 2 digits as requested.

## Wait, What am I actually supposed to do?

Your tasks:

1. Set up the circuit shown below. Choose values for R1 and R2 that make sense. Ask if you need help!

2. Program your Arduino to collect data as you adjust the driving current through the diode.

2. Run the program to collect voltage vs. time data from the Arduino

3. Analyze (you may read the data from excel, but please use jupyter to do any fitting).

4. Compare results with expectations. See the example linear and non-linear analysis python programs given below.

5. Carry out the [Statistical Exercises](Normal%20Distribution%20and%20Estimation%20of%20Parameters.ipynb) for project one.

6. Submit a project report (see sample) describing your results.

## Project 1 Schematic Diagram

# Linear Analysis

```python
#
# Example "straight line" fit. This example is from the "RC" lab you may have done in PHYS-163.
# You'll be using diode data, but the concept is the same so long as you can manipulate the data
# so that it's susceptible to a straight line snalysis.
#
#
# This cell loads the data taken earlier and analyzes it by fitting the ln(Vc) vs. t to a straight line.
#
# You are welcome to use this approach if you like
#

import pandas as pd  # load up the pandas (pyData) package
data = pd.read_csv('data.csv')  # read in the data taken previously
from scipy.optimize import curve_fit  # get the curve_fit function from the scipy.optimize library

def fLinear(x, m, b):
    return m*x + b

sigma = (5.0/1023.0)/(data.voltage.values)  # why am I doing this? If you're not sure, ask! You'll learn something.
popt, pcov = curve_fit(fLinear, data.time.values, np.log(data.voltage.values), sigma=sigma)  # do the fit

m=popt[0]          # get the slope
b=popt[1]          # get the intercept

dm = np.sqrt(pcov[0,0]) # uncertainty in the slope
db = np.sqrt(pcov[1,1]) # uncertainty in the intercept

ystar=fLinear(data.time.values, m, b)  # use m & b

pl.title("Decay of charge on a capacitor")
pl.ylabel("ln(V)")
pl.xlabel("time (ms)")
pl.errorbar(data.time.values, np.log(data.voltage.values), fmt='b.', yerr=sigma)
pl.plot(data.time.values, ystar,'r-')
pl.grid()
print("m = %2.3f +/- %2.3f" % (m, dm))
print("b = %2.3f +/- %2.3f" % (b, db))

```

# Non-Linear Analysis

```python
#
# What if you need to do a fit with a different function? No problem!
#
# curve_fit doesn't care, it works exactly the same way.
#

def fitExp(t, A, tau):
    return A*np.exp(-t/tau)

sigma = np.ones(len(data))*(5.0/1023.0)  # why am I doing this differently? If you're not sure, ask! You'll learn something.
popt, pcov = curve_fit(fitExp, data.time.values, data.voltage.values, sigma=sigma)  # do the fit

A=popt[0]          # get the slope
tau=popt[1]          # get the intercept

dA = np.sqrt(pcov[0,0]) # uncertainty in the slope
dTau = np.sqrt(pcov[1,1]) # uncertainty in the intercept

ystar=fitExp(data.time.values, A, tau)  # use m & b

pl.title("Decay of charge on a capacitor")
pl.ylabel("V (V)")
pl.xlabel("time (ms)")
pl.errorbar(data.time.values, data.voltage.values, fmt='b.', yerr=sigma)
pl.plot(data.time.values, ystar,'r-')
pl.grid()
print("A = %2.3f +/- %2.3f" % (A, dA))
print("tau = %2.3f +/- %2.3f" % (tau, dTau))
print("How does tau relate to the slope of the linear fit?")
```

# Don't forget the statistics assignment

You can find it [here](Normal%20Distribution%20and%20Estimation%20of%20Parameters.ipynb).

```python

```

proj1/Arduino as a Laboratory Interface.ipynb


Dinámica

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

Movimiento parabólico

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  Movimiento parabólico

1.1  Introducción

1.2  Análisis cinemático

1.3  Movimiento horizontal

1.4  Movimiento vertical

1.5  Comentarios al movimiento curvilíneo

1.6  Ejemplos movimiento parabólico

2  Movimiento curvilíneo: Componentes normal y tangencial

2.1  Introducción

2.2  Movimiento plano

2.3  Velocidad

2.4  Aceleración

2.5  Ejemplos componentes normal y tangencial

3  Movimiento curvilíneo: Componentes cilíndricos

3.1  Introducción

3.2  Coordenadas polares

3.2.1  Posición

3.2.2  Velocidad

3.2.3  Aceleración

3.3  Coordenadas cilíndricas

3.4  Derivadas respecto al tiempo

3.5  Ejemplos componentes cilíndricos

 Fuente: Wikipedia

## Movimiento parabólico

### Introducción

El [movimiento parabólico](https://en.wikipedia.org/wiki/Projectile_motion) es el realizado por cualquier objeto cuya trayectoria describe una [parábola](https://en.wikipedia.org/wiki/Parabola), y que corresponde con la trayectoria ideal de un proyectil que se mueve en un medio que no ofrece resistencia al avance y que esté sujeto a un campo gravitatorio uniforme. El movimiento parabólico es un ejemplo de un movimiento realizado por un objeto en dos dimensiones o sobre un plano. Puede considerarse como la combinación de dos movimientos que son un [movimiento rectilíneo uniforme](https://es.wikipedia.org/wiki/Movimiento_rectil%C3%ADneo_uniforme), en la dirección horizontal ($\longleftrightarrow$), y un [movimiento rectilíneo uniformemente acelerado](https://es.wikipedia.org/wiki/Movimiento_rectil%C3%ADneo_uniformemente_acelerado) en la dirección vertical ($\updownarrow$).

### Análisis cinemático

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

Considere un proyectil lanzado en el punto $(x_0, y_0)$, con una velocidad inicial de $v_0$, cuyas componentes son $v_{0x}$ y $v_{0y}$. Cuando se hace caso omiso de la resistencia del aire, la única fuerza que actúa en el proyectil es su peso, el cual hace que el proyectil tenga una aceleración dirigida hacia abajo constante de aproximadamente $a_c=g=9.81 m/s^2=32.2 pies/s^2$.

### Movimiento horizontal

Como $a_x=0$, se pueden aplicar las ecuaciones de aceleración constante vistas en el [Capítulo 1: Movimiento Rectilíneo, numeral 2.6 Aceleración constante](./C01_CinematicaCineticaParticulas_MovRectilineo.ipynb#ac), resultando en:

\begin{equation*}
\begin{array}{crl}
\left(\underrightarrow{+}\right) &v=&v_0+a_ct&                   \quad &v_x=v_{0x} \\
\left(\underrightarrow{+}\right) &x=&x_0+v_0t+\frac{1}{2}a_ct^2& \quad &x=x_0+v_{0x}t \\
\left(\underrightarrow{+}\right) &v^2=&v_0^2+2a_c(x-x_0)&        \quad &v_x=v_{0x} \\
\end{array}
\label{eq:Ec3_1} \tag{3.1}
\end{equation*}

### Movimiento vertical

Estableciendo el sistema de coordenadas con el eje $y$ positivo hacia arriba, se tiene entonces que $a_y=-g$ y aplicando las ecuaciones de aceleración constante como visto en el ítem anterior, se llega a:

\begin{equation*}
\begin{array}{crl}
\left(+\uparrow \right) &v=&v_0+a_ct&                   \quad &v_y=v_{0y}-gt \\
\left(+\uparrow \right) &y=&y_0+v_0t+\frac{1}{2}a_ct^2& \quad &y=y_0+v_{0y}t-\frac{1}{2}gt^2 \\
\left(+\uparrow \right) &v^2=&v_0^2+2a_c(y-y_0)&        \quad &v_y^2=v_{0y}^2-2g \left(y-y_0  \right) \\
\end{array}
\label{eq:Ec3_2} \tag{3.2}
\end{equation*}

### Comentarios al movimiento curvilíneo

- En el movimiento horizontal la primera y la tercera ecuación implican que la componente horizontal de la velocidad siempre permanece constante durante la realización del movimiento.

- En el movimiento vertical, la última ecuación puede formularse eliminando el término del tiempo de las dos primeras ecuaciones, por lo que, solo dos de las tres ecuaciones son independientes entre ellas.

- De lo anterior se concluye que los problemas que involucran movimiento parabólico pueden tener como máximo tres incógnitas, ya que solo se podrán escribir tres ecuaciones independientes: una ecuación en la dirección horizontal y dos en la dirección vertical.

- La velocidad resultante $v$, que siempre será tangente a la trayectoria, se determinará por medio de la suma vectorial de sus componentes $v_x$ y $v_y$.

### Ejemplos movimiento parabólico

 Ejemplo 12.11: Hibbeler R. Engineering Mechanics: Dynamics

Un saco se desliza por la rampa, como se ve en la figura, con una velocidad horizontal de $12 m/s$. Si la altura de la rampa es de $6 m$, determine el tiempo necesario para que el saco choque con el suelo y la distancia $R$ donde los sacos comienzan a apilarse

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

- ***Sistema de coordenadas*** Se establece el origen en el punto $A$, donde comienza la trayectoria de la partícula (saco). Se observa que la velocidad inicial del saco presenta dos componentes, donde $v_{Ax}=12m/s$ y $v_{Ay}=0$. La acelaración en todo el recorrido, entre $A$ y $B$, es de $a_y=-9.81 m/s^2$. También se observa que se cumple que $v_{Bx}=v_{Ax}=12m/s$ (por qué?). Con lo anterior, las tres incógnitas restantes son $v_{By}$, $R$, y el tiempo de vuelo $t_{AB}$.

- ***Movimiento vertical $\left(+\uparrow \right)$:*** Del enunciado, se conoce la distancia vertical $A-B$, que será $y_B=6m$

$$y_B=y_A+v_{Ay}t_{AB}+\frac{1}{2}a_ct_{AB}^2$$

reemplazando valores se tiene

$$0=6m+0 \times t_{AB}+\frac{1}{2}(-9.81m/s^2)t_{AB}^2$$

$$t_{AB}=1.11 s$$

Una vez calculado el tiempo, la distancia horizontal, $R$ se determina así:

- ***Movimiento horizontal $\left(\underrightarrow{+}\right)$:***

$$x_B=x_A+v_{Ax}t_{AB}$$
$$R=0+12m/s(1.11s)$$
$$R=13.3m$$

***Solución computacional:***

```python
import numpy as np
import matplotlib.pyplot as plt
from sympy import *
import seaborn as sns

t,R = symbols('t R')
init_printing(use_latex='mathjax')
```

```python
# condiciones iniciales
x0 = 0     # coordenada xA
y0 = 6     # coordenada yA
v0x = 12   # Veloc en A en la dirección x
v0y = 0    # Veloc en A en la dirección y
y = 0      # Altura final
ac = -9.81 # aceleración debida a la gravedad
```

```python
# Ecuación del movimiento vertical
yd2 = Eq(y, y0 + v0y * t + ac * t**2 / 2)
yd2
```

```python
# Resolviendo para t
tiempo = solve(yd2,t)
print("El tiempo de caída de cada saco es de {0:6.4f} s".format(tiempo[1]))
```

```python
tiempo
```

```python
xd2 = Eq(R, x0 + v0x * tiempo[0])
xd2
```

```python
# Ecuación del movimiento horizontal
R = float(x0 + v0x * tiempo[0])
print("La distancia a la que caerá cada saco es de {0:6.4f} m".format(R))
```

```python
# Graficando
t = np.linspace(0,np.around(float(tiempo[1]), decimals = 4),100)

x = x0 + v0x * t
y = y0 + v0y * t + ac * t**2 / 2

plt.plot(x,y);
plt.xlabel("x(m)")
plt.ylabel("y(m)")
plt.grid(True)
```

## Movimiento curvilíneo: Componentes normal y tangencial

### Introducción

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

A veces es más conveniente emplear como sistema de referencia las coordenadas $n-t$, que expresan las componentes *normal* y *tangencial* a la trayectoria.

### Movimiento plano

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

Sea una partícula que se desplaza en el plano a lo largo de una curva fija, tal que en un instante dado está en la posición $s$ medida respecto a $O'$. Considere un sistema de ejes coordenados con origen en un punto fijo de la curva y, en un instante determinado, éste coincide con la ubicación de la partícula. El eje $t$ es tangente a la curva en el punto y positivo en la dirección de $s$, denominada con el vector unitario $\vec{\boldsymbol{u}}_t$. La determinación del eje normal, $\vec{\boldsymbol{u}}_n$ es inmediata, ya que solo existe una única posibilidad, siendo positivo en la dirección hacia el centro de la curva. La curva se forma por una serie de segmentos de arco de tamaño $ds$ y cada uno de estos segmentos es formado por el arco de un círculo con radio de curvatura $\rho$ y centro $O'$. El plano que se genera por los ejes $n-t$ se denomina *[plano osculador](https://es.wikipedia.org/wiki/Geometr%C3%ADa_diferencial_de_curvas#Plano_osculador)*, y está fijo en el plano del movimiento.

### Velocidad

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

Como se ha indicado en las secciones anteriores, la partícula se encuentra en movimiento, por lo que el desplazamiento es una función del tiempo, $s(t)$. La dirección de la velocidad de la partícula siempre es tangente a la trayectoria y su magnitud se determina por la derivada respecto al tiempo de la función de la trayectoria. Entonces:

\begin{equation*}
\boldsymbol{v}=v\boldsymbol{u}_t
\label{eq:Ec3_3} \tag{3.3}
\end{equation*}

donde

\begin{equation*}
v=\dot{s}
\label{eq:Ec3_4} \tag{3.4}
\end{equation*}

### Aceleración

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

El cambio de la velocidad de la partícula respecto al tiempo es la aceleración. Entonces

\begin{equation*}
\boldsymbol{a}=\dot{\boldsymbol{v}}=\dot{v}\boldsymbol{u}_t + v\dot{\boldsymbol{u}}_t
\label{eq:Ec3_5} \tag{3.5}
\end{equation*}

Falta determinar la derivada de $\dot{\boldsymbol{u}}_t$ respecto al tiempo. A medida que la partícula se desplaza a lo largo de un arco $ds$ en un diferencial de tiempo $dt$, $\boldsymbol{u}_t$ su dirección varía y pasa a ser $\boldsymbol{u}'_t$, donde $\boldsymbol{u}'_t=\boldsymbol{u}_t+d\boldsymbol{u}_t$. Observe que $d\boldsymbol{u}_t$ va de las puntas de $\boldsymbol{u}_t$ a $\boldsymbol{u}'_t$, que se extienden en un arco infinitesimal de magnitud $u_t=1$ (unitaria). Por lo tanto, $d\boldsymbol{u}_t=d\theta \boldsymbol{u}_n$, por lo que la derivada con respecto al tiempo es $\dot{\boldsymbol{u}}_t=\dot{\theta}\boldsymbol{u}_n$.

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

Observe también que $ds=\rho d\theta$, entonces $\dot{\theta}=\dot{s}/\rho$, resultando

$$\dot{\boldsymbol{u}}_t=\dot{\theta}\boldsymbol{u}_n=\frac{\dot{s}}{\rho}\boldsymbol{u}_n=\frac{v}{\rho}\boldsymbol{u}_n$$

Sustituyendo en la [Ec. 3.4](#Ec3_4) se puede reescribir $\boldsymbol{a}$ como la suma de las componentes tangencial y normal:

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

\begin{equation*}
\boldsymbol{a} = a_t \boldsymbol{u}_t + a_n \boldsymbol{u}_n
\label{eq:Ec3_6} \tag{3.6}
\end{equation*}

donde la componente tangencial es dada por

\begin{equation*}
a_t = \dot{v} \qquad \text{o} \qquad a_t ds = vdv
\label{eq:Ec3_7} \tag{3.7}
\end{equation*}

la componente normal, por

\begin{equation*}
a_n = \frac{v^2}{\rho}
\label{eq:Ec3_8} \tag{3.8}
\end{equation*}

y la magnitud de la aceleración está dada por

\begin{equation*}
a = \sqrt{a^2_t + a^2_n}
\label{eq:Ec3_9} \tag{3.9}
\end{equation*}

***Comentarios***

- Si la partícula se mueve a lo largo de una línea recta entonces $\rho \rightarrow \infty$ y por la [Ec. 3.8](#Ec3_8), $a_=0$. Con esto $a=a_t = \dot{v}$, y se puede concluir que *la componente tangencial de la aceleración representa el cambio en la magnitud de la velocidad*.

- Si la partícula se mueve a lo largo de una curva con velocidad constante, entonces $a_t=\dot{v}=0$ y $a=a_n=v^2/\rho$. Por lo tanto, *la componente normal de la aceleración representa el cambio en la dirección de la velocidad*. Como $a_n$ siempre actúa hacia el centro de la curvatura, esta componente en ocasiones se conoce como la [aceleración centrípeta](https://en.wikipedia.org/wiki/Centripetal_force) ("*que busca el centro*").

- Expresando la trayectoria de la partícula como $y=f(x)$, el radio de curvatura en cualquier punto de la trayectoria se determina por la ecuación:

\begin{equation*}
\rho=\frac{\left[1 + (dy/dx)^2\right]^{3/2}}{|d^2y/dx^2|}
\label{eq:Ec3_10} \tag{3.10}
\end{equation*}

Como consecuencia de lo anterior, una partícula que se mueve a lo largo de una trayectoria curva tendrá una aceleración como la mostrada en la figura:

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

### Ejemplos componentes normal y tangencial

 Ejemplo 12.14: Hibbeler R. Engineering Mechanics: Dynamics

Cuando el esquiador llega al punto $A$ a lo largo de la trayectoria parabólica en la figura, su rapidez es de $6 m/s$, la cual se incrementa a $2 m/s^2$. Determine la dirección de su velocidad y la dirección y magnitud de su aceleración en este instante. Al hacer el cálculo, pase por alto la estatura del esquiador..

- ***Sistema de coordenadas:***

Se establece el origen de los ejes $n-t$ en el punto fijo $A$ de la trayectoria.

- ***Velocidad:***

Como se definió, la velocidad será siempre tangente a la trayectoria. Como $y = \frac{1}{20}x^2$, su derivada es $\frac{dy}{dx}=\frac{1}{10}x$, reemplazando cuando $x=10m$, $\frac{dy}{dx}=1$. Por lo tanto, en $A$, $\boldsymbol{v}$ forma un ángulo $\theta=\tan^{-1}(1)=45^{\circ}$ con el eje $x$. Con esto, la velocidad en $A$ es

$$v_A=6m/s \quad 45^{\circ}\measuredangle$$

- ***Aceleración:***

Reemplazando las [Ecs. 3.7 y 3.8](#Ec3_7) en la [Ec. 3.6](#Ec3_6) para determinar la aceleración, se llega a:

$$\boldsymbol{a}=\dot{v}\boldsymbol{u}_t+\frac{v^2}{\rho}\boldsymbol{u}_n$$

De esta ecuación se desconoce el radio de curvatura $\rho$ de la trayectoria en el punto $A(10,5)$. Empleando la [Ec. 3.10](#Ec3.10) y reemplazando el valor de la coordenada:

$$\rho=\frac{\left[1 + (dy/dx)^2\right]^{3/2}}{|d^2y/dx^2|}=\left. \frac{\left[1 + (x/10)^2\right]^{3/2}}{|1/10|} \right|_{x=10m}=28.28m$$

Con lo anterior, la dirección de la aceleración está dada por

$$
\begin{align*}
\boldsymbol{a} & = \dot{v} \boldsymbol{u}_t + \frac{v^2}{\rho} \boldsymbol{u}_n \\
 & = 2 \boldsymbol{u}_t + \frac{(6m/s)^2}{28.28m} \boldsymbol{u}_n \\
 & = (2 \boldsymbol{u}_t + 1.273 \boldsymbol{u}_n) m/s^2
\end{align*}
$$

y cada una de las componentes se representan en la siguiente figura.

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

por último, la magnitud de la aceleración está dada por

$$a=\sqrt{(2m/s^2)^2+(1.273 m/s^2)^2}=2.37 m/s^2$$

el ángulo sería

$$\phi = \tan^{-1}\left(\frac{2}{1.273} \right)=57.5^{\circ}$$

De la figura:

$$45^{\circ}+90^{\circ}+57.5^{\circ}-180^{\circ}=12.5^{\circ}$$

entonces,

$$\boldsymbol{a}=2.37 m/s^2 \quad 12.5^{\circ} \measuredangle$$

Ahora vamos a realizar la solución empleando programación con el ecosistema `python`

```python
x = symbols('x')
ut, un = symbols('ut un')
```

La ecuación que determina la trayectoria de la partícula está dada por

```python
y = x**2 / 20
```

Y la velocidad de la partícula, cuya magnitud es la misma rapidez, segun el enunciado es

```python
v = 6
```

Ahora se deriva la ecuación de la trayectoria respecto a la variable $x$

```python
dydx = diff(y,x)
dydx
```

reemplazando en $x=10m$

```python
dydx = N(dydx.subs(x,10),4)
print("{0:6.1f}".format(dydx))
```

con esto, se calcula el ángulo que determina la direccion de la velocidad

```python
theta = N(atan(dydx)*180/np.pi,4)
print("{0:6.1f}".format(theta))
```

El cálculo de la aceleración se realiza mediante la siguiente ecuación:

$$\boldsymbol{a} = \dot{v} \boldsymbol{u}_t + \frac{v^2}{\rho} \boldsymbol{u}_n$$

se debe calcular el radio de curvatura $\rho$ con la [Ec. 3.10](#Ec3_10), que a su vez requiere del cálculo de la segunda derivada de la función de la trayectoria, $y$, respecto a $x$. Del enunciado se determina que $\dot{v}=2 m/s$.

```python
d2ydx2 = diff(y,x,2)
d2ydx2
```

```python
rho = N((1 + dydx**2)**(3/2) / d2ydx2,4)
print("{0:6.4f}".format(rho))
```

```python
v_dot = 2
```

Con lo anterior, se construye la expresión para la aceleración

```python
v2rho = v**2 / rho
```

```python
a_A = v_dot * ut + v2rho * un
a_A
```

Ahora se calculará la magnitud de la aceleración, dada por la [Ec. 3.9](#Ec3_9)

```python
a_mag = sqrt(v_dot**2 + v2rho**2)
print("{0:6.1f}".format(a_mag))
```

por último, calculamos el ángulo para la dirección de la aceleración

```python
phi = atan(v_dot / v2rho) * 180 / np.pi
print("{0:6.1f}".format(phi))
```

De la [figura](#Fig_angulos) donde se expresan los ángulos, se determina cuál sería la dirección

```python
a = 45 + 90 + phi - 180
print("{0:6.1f}".format(a))
```

$\color{red}{\textbf{Actividad para ser realizada por el estudiante:}}$

Realizar computacionalmente los otros ejemplos del capítulo que aparecen en el libro de Hibbeler, sección 12.7, ejemplos 12-15 y 12-16 (pags. 58 y 59).

También se invita a que desarrollen al menos un ejercicio de los problemas fundamentales (pag. 60), y ejercicios de los problemas (pags. 61 - 67), dividiendolos en tres partes: dos ejercicios del tercio inferior, dos del tercio medio y dos del tercio superior, tanto analíticamente ("a mano") como computacionalmente.

## Movimiento curvilíneo: Componentes cilíndricos

### Introducción

En ciertos problemas cuyo movimiento de la partícula describe una trayectoria curva, la descripción de dicho movimiento se describe de mejor forma (más simple) empleando un [sistema de coordenadas cilíndricas](https://en.wikipedia.org/wiki/Cylindrical_coordinate_system). Si el movimiento se limita a un plano se emplea un [sistema de coordenadas polares](https://en.wikipedia.org/wiki/Polar_coordinate_system).

### Coordenadas polares

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

La posición de la partícula en la figura se determina mediante una coordenada radial $r$, que se extiende desde el origen $O$ hasta la partícula, y el ángulo $\theta$ entre un eje horizontal que sirve como referencia y $r$, medido en sentido antihorario. Las componentes $\boldsymbol{u}_r$ y $\boldsymbol{u}_{\theta}$ se defienen en la dirección positiva de $r$ y $\theta$ respectivamente.

#### Posición

La posición de la partícula se define por el vector posición

\begin{equation*}
\boldsymbol{r}=r\boldsymbol{u}_r
\label{eq:Ec3_11} \tag{3.11}
\end{equation*}

#### Velocidad

La velocidad es la derivada de $\boldsymbol{r}$ respecto al tiempo

\begin{equation*}
\boldsymbol{v}=\boldsymbol{\dot{r}}=\dot{r}\boldsymbol{u}_r+r\boldsymbol{\dot{u}}_r
\label{eq:Ec3_12} \tag{3.12}
\end{equation*}

En la evaluación de $\boldsymbol{\dot{u}}_r$, obsérvese que $\boldsymbol{u}_r$ únicamente cambia de dirección respecto al tiempo, ya que por definición la magnitud del vector es unitaria. En un tiempo $\Delta t$, el cambio $\Delta r$ no cambiará la dirección de $\boldsymbol{u}_r$, sin embargo, un cambio $\Delta \theta$ proporcionará que $\boldsymbol{u}_r$ cambie a $\boldsymbol{u}'_r$, con $\boldsymbol{u}'_r=\boldsymbol{u}_r+\Delta \boldsymbol{u}_r$. Entonces, el cambio de $\boldsymbol{u}_r$ es por lo tanto $\Delta \boldsymbol{u}_r$. Si $\Delta \theta$ es pequeño, la magnitud del vector es $\Delta u_r \approx 1 (\Delta \theta)$, en la dirección $\boldsymbol{u}_{\theta}$. Entonces $\Delta \boldsymbol{u}_r=\Delta \theta \boldsymbol{u}_{\theta}$, y

$$\boldsymbol{\dot{u}}_r=\lim \limits_{\Delta t \to 0} \frac{\Delta \boldsymbol{u}_r}{\Delta t} = \left( \lim \limits_{\Delta t \to 0} \frac{\Delta \theta}{\Delta t}\right) \boldsymbol{u}_{\theta}
$$

\begin{equation*}
\boldsymbol{\dot{u}}_r=\dot{\theta}\boldsymbol{u}_{\theta}
\label{eq:Ec3_13} \tag{3.13}
\end{equation*}

Sustituyendo en la ecuación anterior, la velocidad se escribe a través de sus componentes como

\begin{equation*}
\boldsymbol{v}=v_r \boldsymbol{u}_r+v_{\theta}\boldsymbol{u}_{\theta}
\label{eq:Ec3_14} \tag{3.14}
\end{equation*}

donde

\begin{equation*}
v_r=\dot{r} \\
v_{\theta} = r\dot{\theta}
\label{eq:Ec3_15} \tag{3.15}
\end{equation*}

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

En la gráfica se observa la descomposición del vector velocidad en las componentes radial, $\boldsymbol{v}_r$, que mide la tasa de incremento (decremento) de la longitud en la coordenada radial, o sea, $\dot{r}$, y la componente transversal, $\boldsymbol{v}_{\theta}$, que es la tasa de movimiento a lo largo de una circunferencia de radio $r$. El término $\dot{\theta}=d\theta / dt$ también se conoce como *velocidad angular*, ya que es la razón de cambio del ángulo $\theta$ respecto al tiempo. Las unidades de la velocidad angular se dan en $rad/s$.

Considerando que $\boldsymbol{v}_r$ y $\boldsymbol{v}_{\theta}$ son perpendiculares, la magnitud de la velocidad estará dada por el valor positivo de:

\begin{equation*}
v = \sqrt{(\dot{r})^2+(r\dot{\theta})^2}
\label{eq:Ec3_16} \tag{3.16}
\end{equation*}

donde la dirección de $\boldsymbol{v}$ es tangente a la trayectoria.

#### Aceleración

La aceleración es la derivada de la velocidad respecto al tiempo. De las ecs. [(3.14)](#Ec3_14) y [(3.15)](#Ec3_15), se llega a la aceleración instantánea de la partícula.

\begin{equation*}
\boldsymbol{a}=\boldsymbol{\dot{v}}=\ddot{r}\boldsymbol{u}_r+\dot{r}\dot{\boldsymbol{u}}_r+\dot{r}\dot{\theta}\boldsymbol{u}_{\theta}+r\ddot{\theta}\boldsymbol{u}_{\theta}+r\dot{\theta}\boldsymbol{\dot{u}}_{\theta}
\label{eq:Ec3_17} \tag{3.17}
\end{equation*}

De la anterior ecuación se requiere determinar el valor de $\dot{\boldsymbol{u}}_{\theta}$, que es el cambio de la dirección $\boldsymbol{u}_{\theta}$ respecto al tiempo, con magnitud unitaria.

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

De la gráfica se tiene que en un tiempo $\Delta t$, un cambio $\Delta r$ no cambiará la dirección $\boldsymbol{u}_{\theta}$, sin embargo, un cambio $\Delta \theta$ hará que $\boldsymbol{u}_{\theta}$ pase a $\boldsymbol{u}'_{\theta}$, con $\boldsymbol{u}'_{\theta}=\boldsymbol{u}_{\theta}+\Delta\boldsymbol{u}_{\theta}$. Para pequeñas variaciones del ángulo, la magnitud del vector es $\Delta u_{\theta}\approx 1(\Delta \theta)$, actuando en la dirección $-\boldsymbol{u}_r$, o sea, $\Delta u_{\theta}=-\Delta \theta\boldsymbol{u}_r$, entonces

$$\boldsymbol{\dot{u}}_{\theta}=\lim \limits_{\Delta t \to 0} \frac{\Delta \boldsymbol{u}_{\theta}}{\Delta t} = -\left( \lim \limits_{\Delta t \to 0} \frac{\Delta \theta}{\Delta t}\right) \boldsymbol{u}_{r}
$$

\begin{equation*}
\boldsymbol{\dot{u}}_{\theta}=-\dot{\theta}\boldsymbol{u}_{r}
\label{eq:Ec3_18} \tag{3.18}
\end{equation*}

Sustituyendo el anterior resultado y la Ec. [(3.13)](#Ec3_13) en la ecuación para la aceleración, se escribe la aceleración en forma de componentes como

\begin{equation*}
\boldsymbol{a}=a_r\boldsymbol{u}_{r}+a_{\theta}\boldsymbol{u}_{\theta}
\label{eq:Ec3_19} \tag{3.19}
\end{equation*}

con

\begin{equation*}
a_r=\ddot{r}-r\dot{\theta}^2 \\
a_{\theta}=r\ddot{\theta}+2\dot{r}\dot{\theta}
\label{eq:Ec3_20} \tag{3.20}
\end{equation*}

donde $\ddot{\theta}=d^2\theta/dt^2=d/dt(d\theta /dt)$ se conoce como *aceleración angular y sus unidades son $rad/s^2$*. $\boldsymbol{a}_r$ y $\boldsymbol{a}_{\theta}$ son perpendiculares, entonces la magnitud d ela aceleración está dada por el valor positivo de

\begin{equation*}
a=\sqrt{(\ddot{r}-r\dot{\theta}^2)^2+(r\ddot{\theta}+2\dot{r}\dot{\theta})^2}
\label{eq:Ec3_21} \tag{3.21}
\end{equation*}

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

### Coordenadas cilíndricas

 Fuente: Hibbeler R. Engineering Mechanics: Dynamics

Si la partícula se mueve a lo largo de una curva espacial, entonces su ubicación se especifica por medio de las tres coordenadas cilíndricas, $r$, $\theta$, $z$. La coordenada $z$ es idéntica a la que se utilizó para coordenadas rectangulares. Como el vector unitario que define su dirección $\boldsymbol{u}_z$, es constante, las derivadas con respecto al tiempo de este vector son cero, y por consiguiente la posición, velocidad y aceleración de la partícula se escriben en función de sus coordenadas cilíndricas como sigue:

\begin{equation*}
\begin{split}
\boldsymbol{r}_p &= r\boldsymbol{u}_r+z\boldsymbol{u}_z \\
\boldsymbol{v} &= \dot{r}\boldsymbol{u}_r+r\dot{\theta}\boldsymbol{u}_{\theta}+\dot{z}\boldsymbol{u}_{z} \\
\boldsymbol{a} &= (\ddot{r}-r\dot{\theta}^2)\boldsymbol{u}_r+(r\ddot{\theta}+2\dot{r}\dot{\theta})\boldsymbol{u}_{\theta}+\ddot{z}\boldsymbol{u}_z
\end{split}
\label{eq:Ec3_22} \tag{3.22}
\end{equation*}

### Derivadas respecto al tiempo

Las ecuaciones anteriores requieren que obtengamos las derivadas con respecto al tiempo $\dot{r}$, $\ddot{r}$, $\dot{\theta}$ y $\ddot{\theta}$, para evaluar las componentes $r$ y $\theta$ de $\boldsymbol{v}$ y $\boldsymbol{a}. En general se presentan dos tipos de problema:

1. Si las coordenadas polares se especifican como ecuaciones paramétricas en función del tiempo, $r = r(t)$ y $\theta=\theta(t)$, entonces las derivadas con respecto al tiempo pueden calcularse directamente.

2. Si no se dan las ecuaciones paramétricas en función del tiempo, entonces debe conocerse la trayectoria $r=f(\theta)$. Si utilizamos la regla de la cadena del cálculo podemos encontrar entonces la relación entre $\dot{r}$ y $\dot{\theta}$ y entre $\ddot{r}$ y $\ddot{\theta}$

### Ejemplos componentes cilíndricos

 Ejemplo 12.20: Hibbeler R. Engineering Mechanics: Dynamics

Debido a la rotación de la barra ahorquillada, la bola en la figura se mueve alrededor de una trayectoria ranurada, una parte de la cual tiene la forma de un cardioide, $r=0.5(1 - cos(\theta)) pies$, donde $\theta$ está en radianes. Si la velocidad de la bola es $v=4 pies/s$ y su aceleración es $a=30 pies/s^2$ en el instante $\theta=180^{\circ}$, determine la velocidad angular $\dot{theta}$ y la aceleración angular $\ddot{\theta}$ de la horquilla.

- ***Sistema de coordenadas:***
Esta trayectoria es muy rara, y matemáticamente se expresa mejor por medio de coordenadas polares, como se hace aquí, en lugar de coordenadas rectangulares. También, como $\dot{theta}$ y $\ddot{\theta}$ deben determinarse, entonces las coordenadas $r$, $\theta$ no son una opción obvia.

- ***Velocidad y aceleración:***

Empleando la regla de la cadena para determinar las derivadas de $r$ y $\theta$:

\begin{equation*}
\begin{split}
r&=0.5(1-\cos\theta) \\
\dot{r}&=0.5(\sin\theta)\dot{\theta}\\
\ddot{r}&=0.5(\cos\theta)\dot{\theta}(\dot{\theta})+0.5(\sin\theta)\ddot{\theta}
\end{split}
\end{equation*}

evaluando cuando $\theta=180^{\circ}$, se tiene

$$r=1 pie \quad\quad \dot{r}=0\quad\quad\ddot{r}=-0.5\dot{\theta}^2$$

como $v=4 pie/s$, utilizando la ecuación [(3.16)](#Ec3_16) para determinar $\dot{\theta}$ se tiene

\begin{equation*}
\begin{split}
v&=\sqrt{(\dot{r})^2+(r\dot{\theta})^2} \\
4&=\sqrt{(0)^2+(1\dot{\theta})^2}\\
\dot{\theta}&=4rad/s
\end{split}
\end{equation*}

Ahora calculando $\ddot{\theta}$, empleando la ecuacion [3.21](#Ec3_21)

\begin{equation*}
\begin{split}
a&=\sqrt{(\ddot{r}-r\dot{\theta}^2)^2+(r\ddot{\theta}+2\dot{r}\dot{\theta})^2} \\
30&=\sqrt{[-0.5(4)^2-1(4)^2]^2+[1\ddot{\theta}+2(0)(4)]^2}\\
(30)^2&=(-24)^2+\ddot{\theta}^2 \\
\ddot{\theta}&=18rad/s^2
\end{split}
\end{equation*}

- ***Solución computacional:***

```python
import numpy as np
import matplotlib.pyplot as plt
from sympy import *
from sympy.physics.mechanics import dynamicsymbols, init_vprinting

theta = dynamicsymbols(r'\theta')
t = Symbol('t')

init_vprinting()
```

Graficando primero la funcion cardioide

```python
phi = np.linspace(0, 2*np.pi, 1000)

r = 0.5 * (1 - np.cos(phi))
plt.polar(phi, r, 'r')
plt.show()

```

Ahora obtenemos los valores de $\dot{r}$ y $\ddot{r}$

```python
r = 0.5 * (1 - cos(theta))
rdot = diff(r, t)
rdot
```

```python
rddot = diff(rdot, t)
rddot
```

Evaluando los anteriores resultados cuando $\theta=180^{\circ}$

```python
rN = r.subs(theta, 180 * pi / 180)
rN
```

```python
rdotN = rdot.subs(theta, 180 * pi / 180)
rdotN
```

```python
rddotN = rddot.subs(theta, 180 * pi / 180)
rddotN
```

Ahora vamos a determinar el valor numérico para $\dot{\theta}$, cuando $v=4pie/s$

```python
thetadot = N(Eq(4, sqrt(rdotN**2 + (rN * theta)**2)))
thetadot
```

```python
thetadot = solve(thetadot,theta)
thetadot
```