# **3.2 Pullout curve versus bond length**

 part 1

        Starting point

In the previous notebook [3.1 Hardening and softening](3_1_nonlinear_bond.ipynb#top) we have seen that the effect of the softening
in the bond-slip law affects the pullout response in a qualitatively different way than a constant or increasing shear stress for a growing slip.

        Where are we heading

To deepen our understanding of the correspondence between the bond length and maximum achievable pullout force we will
study the response in three case studies. With the pullout model introduced in notebook [3.1](3_1_nonlinear_bond.ipynb#model)
we will simulate the pullout curve for a changing bond length and extract characteristic points of the structural response.
In particular, we are interested in the trend of the maximum pullout force versus the bond length.

**Quality of a model = our level of understanding:** We can establish a direct relation between the level of our understanding of the observed phenomena, e.g. pull-out behavior, and the quality of the models we are able to construct. The better the model, the more general the design rules can be formulated. Thus, the validity of the model is a central issue.

**Before starting to experiment:** Therefore, when designing experimental setups, it is necessary
 - to **formulate a hypothesis** how the phenomenology works
 - to provide **several perspective of observation** by changing some parameters

Indeed, the change of the bond length is an easy way how to extract much more information from the test then if only single geometrical configuration is used.

**Parametric studies:** The notebook demonstrates an important discipline of engineering research, namely the aim to capture the dependency between the material behavior, geometrical configuration by simple **design formulas** and rules
**applicable in engineering practice**. Many design formulas are derived **empirically**, based solely on
thorough experimental studies. With an increasing quality, or more precisely, **validity of the models**, some design configurations can be also covered based on the simulation results. In the subsequent studies, we will use a model and as a virtual experiment to demonstrate the derivation of a formula for **anchorage length**, i.e. the minimum necessary bond length that guarantees the full utilization of the reinforcement.

# **Case study 1: textile reinforced concrete**

To characterize the bond behavior between carbon fabrics penetrated with rubber-like material the test setup with a variable bond length has been studied in [Li et al. (2018)](../papers/Li_Bielak_Hegger_Chudoba_2017.pdf). This symmetric, double-sided pullout-test was chosen to appropriately reflect the condition of a typical crack bridge as it occurs in structural TRC members under tensile or bending loads.

## Test setup with symmetric debonding

In the test setup, a TRC specimen with a notch on both faces at the middle section is clamped using hydraulic cylinders.The proposed test setup induces high transversal stress into the anchorage zone of the specimen. For non-impregnated yarns and yarns with a flexible impregnation, e.g. styrene-butadiene, the bond characteristics are not influenced by transversal pressure if the concrete remains uncracked in longitudinal direction. Due to the low stiffness of the yarns in comparison to the concrete in transversal direction, the transversal pressure is transferred by small concrete vaults, forming around the yarn channels.

## Test specimens and measured results

| Material parameter | Value | Unit |
|:- | -:| -:|
| matrix area | 1543 | [mm$^2$] |
| matrix stiffness | 28.5 | [GPa] |
| reinforcement area | 16.7 | [mm$^2$] |
| reinforcement stiffness | 170 | [GPa] |
| bond perimeter | 10 | [mm] |
| specimen length | 200-700 | [mm] |
| fabric strength | 1300 | [MPa] |

The paper [Li et al. (2018)](../papers/Li_Bielak_Hegger_Chudoba_2017.pdf) describes an automatic calibration of the bond slip law. The resulting bond-slip law is used here to reproduce the length-dependency of the pullout response of the cross section described above. We will now use the ```PullOutModel1D``` to
reproduce the test results with the bond slip law identified in the paper.

**Comment on the shape of the material law:** The diagram above shows the result of the automated bond-slip calibration that has been performed for several tested lengths to validate if the algorithm will derive the same bond-slip law from all the performed tests.
Let us remark the unusual shape of the pullout curve exhibiting a first peak followed by a small drop down and subsequent increase of the bond level. This kind of behavior explained by a so called jamming effect due to increasing the lateral pressure in the interface zone between the fiber and matrix.

Let us apply the derived average bond-slip law in a study to investigate and illuminate the correspondence between this type of hardening bond-slip law and pullout response. Recall that only a half of the specimen is simulated so that the pullout displacement in the model is equivalent to the half of the crack bridge displacement measured in the test. See a remark to the validity of the applied [symmetry assumption](#symmetry_assumption) below.

```python
%matplotlib widget
import matplotlib.pylab as plt
import numpy as np
from bmcs_cross_section.pullout import PullOutModel1D
```

```python
po_trc = PullOutModel1D(n_e_x=100, w_max=6) # mm
po_trc.material_model='trilinear'
po_trc.geometry.L = 100
po_trc.material_model_.trait_set(E_m=28000, E_f=180000, tau_1=5.5, tau_2=8, s_1=0.07, s_2=6)
po_trc.interact()
```

    VBox(children=(HBox(children=(VBox(children=(Tree(layout=Layout(align_items='stretch', border='solid 1px black…

        Run in a loop along the changing bond length

The model `po_trc` chould be again used to interactively, however, we will directly apply the automated evaluation to find the dependence between the maximum pullout force and the bond length. Let us extend the loop that we previously introduced in the notebook [3.1](3_1_nonlinear_bond.ipynb#crfp_study). Instead of plotting the results directly after each simulation `run`, let us now store the pullout curves in a list called `Pw_list`. The `history` attribute of the model provides the method `get_Pw_t` delivering three data arrays, namely the force and the corresponding two displacements at unloaded and loaded ends. Thus, the calculated arrays are obtained by writing
```python
P, w_unloaded, w_loaded = po_trc.history.get_Pw_t()
```
In the code below, we let all the three arrays in a single variable called ``Pw_t`` and append this tuple of three values into the list ``Pw_list`` collecting the results for each studied length from the list ``L_list``

```python
L_list = [100, 150, 200, 250, 300, 350]
Pw_list = []
po_trc.w_max = 6
for L in L_list:
    print('evaluating pullout curve for L', L)
    po_trc.geometry.L_x=L
    po_trc.reset()
    po_trc.run()
    Pw_t = po_trc.history.get_Pw_t()
    Pw_list.append(Pw_t)
```

    evaluating pullout curve for L 100
    evaluating pullout curve for L 150
    evaluating pullout curve for L 200
    evaluating pullout curve for L 250
    evaluating pullout curve for L 300
    evaluating pullout curve for L 350

**Fiber rupture:** In addition to the parameters needed to simulate the debonding, let us also define the fabric strength so that we can plot the breaking force of the reinforcement $f_{\mathrm{trc,t}} = 1300$ MPa. Then the rupture force force is evaluated as
\begin{align}
P_\mathrm{fu} = A_\mathrm{f} f_{\mathrm{trc,t}}
\end{align}

```python
f_trc_t = 1300 # [MPa]
P_fu = po_trc.cross_section.A_f * f_trc_t # [N]
P_fu / 1000 # [kN]
```

    200.07

        ... plot and decorate the results

The data of all studies is stored in the list `Pw_list`. Let us now loop over this list, associate every study with a color and
show the pull-out curves in a single diagram refered to as `ax`. In parallel, we extract the maximum pullout force from each study and associate it with the respective bond length. This information is plotted in the diagram `ax_P_L`.

```python
fig, (ax, ax_P_L) = plt.subplots(1,2, figsize=(10,4), tight_layout=True)
fig.canvas.header_visible = False
P_max_list = []
for Pw_t, L, color in zip(Pw_list, L_list, ['red','green','blue','black','orange','gray']):
    P_range, w_unloaded, w_loaded = Pw_t
    ax.plot(w_loaded, P_range/1000, color=color, linestyle='solid', label=r'$L_\mathrm{b}$ = %d' % L)
    ax.plot(w_unloaded, P_range/1000, color=color, linestyle='dashed')
    P_max = np.max(P_range)/1000 # kN
    P_max_list.append(P_max)
# Plotting
ax.set_xlabel(r'half of crack opening $w/2$ [mm]'); ax.set_ylabel(r'$P$ [kN]')
ax.legend()
ax_P_L.plot(L_list, P_max_list, 'o-', color='blue', label=r'$P_\mathrm{max}$')
ax_P_L.set_xlabel(r'bond length $L_\mathrm{b}$ [mm]')
ax_P_L.set_ylabel(r'pullout force $P_\mathrm{max}$ [kN]')
ax_P_L.set_xlim(xmin=0); ax_P_L.set_ylim(ymin=0)
ax.plot([0, 6], [P_fu/1000, P_fu/1000], linestyle='dashed', linewidth=1, color='red', label='breaking force' );
ax_P_L.plot([0, 350], [P_fu/1000, P_fu/1000], linestyle='dashed', linewidth=1, color='red', label='breaking force' );
ax_P_L.legend();
```

    Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …

## **Comments** to the study
 - **Anchorage length**: The relation between the maximum pullout force and the bond length is linear and reaches the breaking force of the reinforcement at the length 250 mm. Comparing this value with the experimental observation, we see that the breaking load exhibits a huge scatter. It is therefore impossible to specify the deterministic value of the fabric strength.
 - **Scatter of breaking force**: What is the reason for the experimentally observed scatter of the force at which the fabric breaks? We cannot expect that the pullout force is distributed evenly across the cross section. The statistical aspects of a parallel fiber bundle significantly affect the response of the material that needs to be accounted for in the design rules of textile fabric composites. In case of brittle fabrics this issue **must** included in the reliable design concept.

 - **Symmetric debonding in both directions**: The fact that the test is designed as symmetric raises the question if the debonding runs symmetrically in both directions, particularly in the context of an existing scatter in the material properties across the fabrics and bond structure. The answer is, that as far as the pullout (crack-bridge) force increases, the differences on both sides will balance each other. A weaker spot on a one side will lead to a faster increment of debonding upon increasing the bridging force transferred over the debonded zone. Due to hardening bond, the larger debonded length will be able to increase the amount of transfered force. To compensate this, the other side will have to balance this by a further debonding. This **balancing of debonding**, however, can only be assumed for an ascending branch of the pullout curve. If one side of the fabric starts to pullout with a decreasing force, the debonding process becomes one-sided.

# **Case study 2: Anchorage and constant bond-slip law**

 part 2

The first study using a hardening law has shown that the maximum pullout force increases nearly linearly
up to the failure of the reinforcement. Derivation of such a trend was our goal to have an idea how
to derive a formula for the assessment of anchorage length.
To provide a more straightforward derivation of this trend let us again consider a constant bond-slip law
and provide a simple analytical expression for the relation between the bond length and the maximum pullout load.
We will again make use of the `sympy` and `numpy` packages

```python
import sympy as sp
import numpy as np
sp.init_printing()
```

Recall that the pull-out model with constant bond strength presented in
the notebook [2.1](../tour2_constant_bond/2_1_1_PO_observation.ipynb#top)
predicts a square root function
\begin{align}
P_w = \sqrt{A_\mathrm{f} E_\mathrm{f} p_\mathrm{b} \bar{\tau} w}
\end{align}
so that we can express it in `sympy` as

```python
p_b, tau, E_f, A_f, L_b, w = sp.symbols(r'p_b, tau, E_f, A_f, L_b, w')
P_w = sp.sqrt(p_b*tau*E_f*A_f*w)
P_w
```

Once the debonding reached the end of the bond length $L_\mathrm{b}$, the pull out force can grow up to the maximum load of
\begin{align}
P_\max = L_\mathrm{b} p_\mathrm{b} \bar{\tau}
\end{align}

```python
P_max = L_b * p_b * tau
P_max
```

**This is actually the equation wee seek!** The right diagram of the parametric study [performed above](#hardening_parametric_study)

To cover both phases of the pullout process, let us construct a piecewise function which the plateau after reaching the value $P_\max$

```python
P_w_pull = sp.Piecewise(
    (P_w, P_w < P_max),
    (P_max, True)
)
P_w_pull
```

With these equation we can quickly reinterpret the results obtained numerically in [study 1](#case_study_1)

| Material parameter | Value | Unit |
|:- | -:| -:|
| matrix area | 1543 | [mm$^2$] |
| matrix stiffness | 28.5 | [GPa] |
| reinforcement area | 16.7 | [mm$^2$] |
| reinforcement stiffness | 170 | [GPa] |
| bond perimeter | 10 | [mm] |
| specimen length | 200-700 | [mm] |
| fabric strength | 1300 | [MPa] |

With these parameters we can require the anchorage length at which the fiber breaks by setting
\begin{align}
\tau_\mathrm{fu} = \dfrac{P_\mathrm{fu}}{p_\mathrm{b} L_\mathrm{b}}
\end{align}
and set $L_\mathrm{b}=250$ to obtain the same anchorage curve as in [study 1](#case_study_1)

```python
tau_fu = P_fu / 10 / 250
tau_fu # [MPa]
```

        ... and plot it

```python
get_P_w_pull = sp.lambdify((w, p_b, tau, E_f, A_f, L_b), P_w_pull, 'numpy')
get_P_max = sp.lambdify((L_b, p_b, tau), P_max, 'numpy' )
# breaking force
w_range = np.linspace(0, 6, 100)
fig, (ax, ax_P_L) = plt.subplots(1,2, figsize=(10,4), tight_layout=True)
fig.canvas.header_visible=False
L_list = np.array([100, 150, 200, 250, 300, 350])
for L in L_list:
    ax.plot(w_range, get_P_w_pull(w_range, p_b=10, tau=tau_fu, E_f=170000, A_f=16.7, L_b = L) / 1000, label=r'$L_\mathrm{b}$ = %d' % L)
ax.set_title(r'Pullout curves for variable bond length with constant bond slip');
ax.set_xlabel(r'$w$ [mm]'); ax.set_ylabel(r'$P$ [kN]')
ax.legend()
ax_P_L.plot(L_list, get_P_max(L_list, p_b=10, tau=tau_fu)/1000, 'o-', color='blue', label=r'$P_\mathrm{max}$')
ax_P_L.set_xlabel(r'bond length $L_\mathrm{b}$ [mm]')
ax_P_L.set_ylabel(r'pullout force $P_\mathrm{max}$ [kN]')
ax_P_L.set_xlim(xmin=0); ax_P_L.set_ylim(ymin=0)
ax_P_L.plot([0, 350], [P_fu/1000, P_fu/1000], linestyle='dashed', linewidth=2, color='red', label='breaking force' );
ax_P_L.legend();
```

    Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …

## **Comment:**
 - Note that the anchorage length diagrams in [study 1](#case_study_1) with a nonlinear hardening law and the constant bond-slip law used in study 2 shown above are equal, even if the pull-out curves on the left are different. To explain this, compare the bond state at failure for a selected bond length. The shear profile at failure will be very similar because the a relatively large value of slip has been achieved  over the whole bond length so that the shear stress is nearly uniform already. Verify this statement by using the interactive interface of `po_trc` and render it.

# **Case study 3: CFRP sheet revisited**

 part 3

To complete the picture with the case of softening bond-slip law, let us extend the study previously presented [for CFRP sheets in notebook 3.1](3_1_nonlinear_bond.ipynb#cfrp_sheet_test) with the goal and construct the relation between the bond length $L_\mathrm{b}$ and the maximum pullout force $P_\max$.

## Model construction

```python
po_cfrp = PullOutModel1D(n_e_x=200, w_max=1) # mm
po_cfrp.geometry.L_x=100
po_cfrp.time_line.step = 0.02
po_cfrp.cross_section.trait_set(A_m=400*200, A_f=100*0.11, P_b=100)
po_cfrp.material_model='trilinear'
po_cfrp.material_model_.trait_set(E_m=28000, E_f=230000, tau_1=5.5, tau_2=0, s_1=0.07, s_2=0.4)
po_cfrp.interact()
```

    VBox(children=(HBox(children=(VBox(children=(Tree(layout=Layout(align_items='stretch', border='solid 1px black…

        Run in a loop along the changing bond length

To study the dependence between the maximum pullout force and the bond length, let us extend the loop that we previously introduced in the notebook [3.1](3_1_nonlinear_bond.ipynb#crfp_study). Instead of plotting the results directly after each simulation `run`, let us now store the pullout curves in a list called `Pw_list`. The `history` attribute of the model provides the method `get_Pw_t` delivering three data arrays, namely the force and the corresponding two displacements at unloaded and loaded ends.

```python
L_list = [5, 10, 50, 100, 200]
Pw_list = []
for L in L_list:
    print('evaluating pullout curve for L', L)
    po_cfrp.geometry.L_x=L
    po_cfrp.reset()
    po_cfrp.run()
    Pw_t = po_cfrp.history.get_Pw_t()
    Pw_list.append(Pw_t)
```

    evaluating pullout curve for L 5
    evaluating pullout curve for L 10
    evaluating pullout curve for L 50
    evaluating pullout curve for L 100
    evaluating pullout curve for L 200

        ... let us put the results into the same diagrams as above

In addition to the maximum pullout load, we also include the evolution of the pullout displacement at when the maximum load has been reached, denoted as $w_\mathrm{argmax}$

```python
fig, (ax, ax_P_L) = plt.subplots(1,2, figsize=(10,4), tight_layout=True)
ax_w_L = ax_P_L.twinx()
fig.canvas.header_visible = False
P_max_list = []
w_argmax_list = []
for Pw_t, L, color in zip(Pw_list, L_list, ['red','green','blue','black','orange']):
    P_range, w_unloaded, w_loaded = Pw_t
    ax.plot(w_loaded, P_range/1000, color=color, linestyle='solid', label=r'$L_\mathrm{b}$ = %d' % L)
    ax.plot(w_unloaded, P_range/1000, color=color, linestyle='dashed')
    P_max = np.max(P_range)/1000 # kN
    w_argmax = w_loaded[np.argmax(P_range)]
    P_max_list.append(P_max)
    w_argmax_list.append(w_argmax)
    ax.plot([w_argmax], [P_max], 'o', color=color)
# Plotting
ax.set_xlabel(r'$w$ [mm]'); ax.set_ylabel(r'$P$ [kN]')
ax.legend()
ax_P_L.plot(L_list, P_max_list, 'o-', color='blue', label=r'$P_\mathrm{max}$')
ax_P_L.set_xlabel(r'bond length $L_\mathrm{b}$ [mm]')
ax_P_L.set_ylabel(r'pullout force $P_\mathrm{max}$ [kN]')
ax_P_L.set_xlim(xmin=0); ax_P_L.set_ylim(ymin=0)
ax_P_L.legend(loc=4)
ax_w_L.plot(L_list, w_argmax_list, 'o-', color='orange', label=r'$w_\mathrm{argmax}$')
ax_w_L.set_ylabel(r'pullout displacement at $P_\mathrm{max}$ [mm]')
ax_w_L.set_ylim(ymin=0);
ax_w_L.legend(loc=5);
```

    Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …

## **Discussion:**
 - Comparing the result with the non-softening laws shown in the studies 1 and 2 above, the evolution of the maximum pullout force with the increasing debonded length displayed in the right diagram is nonlinear and reaches the plateau at $L_b \approx 0.75$ mm.

        Exercise X0303: Anchorage length

      3.1 Nonlinear bond - softening and hardening

    4.1 Loading unloading and reloading

```python

```


# <center> MACROECONOMIA INTERTEMPORAL I - 2019
# <center> Capítulo 9 - Horizonte Infinito
# <center> ANTONIO FIORENCIO
# <center> Preliminar. Não citar.  Comentários bem-vindos.

## Introdução

Nos capítulos anteriores vimos como resolver modelos macroeconômicos com um número reduzido de períodos, dois ou, às vezes, três. Apesar de simples, esses modelos permitiram a análise de vários aspectos importantes das escolhas intertemporais dos agentes econômicos. Entretanto, para diversos problemas práticos, essa estrutura com poucos períodos é excessivamente rígida e precisamos de modelos em que um maior número de períodos permita maior flexibilidade na análise. Por exemplo, se quisermos analisar o desempenho da economia ao longo de cada um dos próximos seis meses, precisaremos de um modelo com vários períodos.

Uma pergunta natural é: quantos? Até agora enfatizamos que os modelos devem ser mantidos tão simples quanto possível. Portanto, pareceria natural que para analisar a economia ao longo de um ano utilizássemos um modelo com doze períodos; para cinco anos, sessenta períodos. Essa abordagem, entretanto, não é prática. As contas ficam rapidamente intratáveis e precisariam ser refeitas a cada vez que o horizonte mudasse. A maneira prática é passar diretamente para um modelo com horizonte infinito.

Mas essa é uma hipótese razoável? É claro que as pessoas não acham que viverão para sempre. Um horizonte de planejamento
infinito é uma maneira simples de representar o fato de que as pessoas não sabem qual será o último período de suas vidas; e, portanto, não há um “último” período em que o indivíduo consome tudo que tem. (Essa modelagem acaba sendo mais simples que tratar a data da morte como uma variável aleatória – o que seria mais realista.)

Mas um horizonte infinito não irá representar mal o comportamento das pessoas reais que vivem menos que isso? Na verdade, não, pois os valores futuros são descontados a taxas compostas, seja pela taxa de juros, seja pela de impaciência. Para valores razoáveis, um horizonte de cem ou de infinitos anos produz comportamentos muito parecidos.

Modelos com horizonte infinito são mais complexos que os de dois períodos que vimos até agora. Esses modelos raramente permitem uma solução analítica e precisam ser resolvidos graficamente ou numericamente, como veremos nos próximos capítulos.

## O modelo de crescimento em tempo discreto

Como primeiro exemplo, vamos estender o modelo de dois períodos com capital, mas sem lazer, ativos financeiros ou incerteza. Recapitulando, nesse caso, o problema do indivíduo é:

$ \left\{ \begin{array}{l l}
\underset{X}{max} \, U(C_1,C_2)  = ln(C_1) + \cfrac{1}{1+\rho}ln(C_2)\\
    Y_1 = C_1 + I_1 \\
    Y_2 = C_2 + I_2   \\
    Y_1 = Z_1K_1^\alpha  \,\,\,\,\,\,  Y_2 = Z_2K_2^\alpha  \\
    K_2 = (1-\delta)K_1 + I_1 \,\,\,\,\,\,  K_3 = (1-\delta)K_2 + I_2  \\
    K_1,Z_1,Z_2: dados \,\,\,\,\,\, K_3 = K^F  \\
    \\
    X = (C_1,C_2,I_1,I_2,K_2,K_3,Y_1,Y_2 )   \\
    \end{array}\right. $

A primeira linha mostra o objetivo do indivíduo. A segunda mostra a restrição orçamentária do primeiro período e as restrições para cada estado da natureza possível no segundo período. A terceira faz o mesmo para as funções de produção. A quarta apresenta as equações de acumulação de capital, com uma taxa de depreciação δ. A quinta linha apresenta as probabilidades dos estados da natureza. A última apresenta a condição inicial e a final do problema.

Vamos, gradualmente, transformar esse problema para obter outro semelhante com horizonte infinito.

Primeiro passo. (i) Definimos $β=\frac{1}{1+ρ}$.(ii) Substituir os valores das produções pelas suas expressões.

$ \left\{ \begin{array}{l l}
    \underset{X}{max} \, U(C_1,C_2)  = ln(C_1) + \beta\ln(C_2)\\
    Z_1K_1^\alpha = C_1 + I_1 \\
    Y_2 = Z_2K_2^\alpha = C_2 + I_2   \\
    K_2 = (1-\delta)K_1 + I_1 \,\,\,\,\,\,  K_3 = (1-\delta)K_2 + I_2  \\
    K_1,Z_1,Z_2: dados \,\,\,\,\,\, K_3 = K^F  \\
    \\
    X = (C_1,C_2,I_1,I_2,K_2,K_3)   \\
    \end{array}\right. $

Segundo passo. Substituir os valores dos investimentos nas restrições orçamentárias nas equações de acumulação de capital.

$ \left\{ \begin{array}{l l}
    \underset{X}{max} \, U(C_1,C_2)  = ln(C_1) + \beta\ln(C_2)\\
    K_2 = Z_1K_1^\alpha + (1-\delta)K_1 - C_1 \\
    K_3 = Z_2K_2^\alpha + (1-\delta)K_2  - C_2  \\
    K_1,Z_1,Z_2: dados \,\,\,\,\,\, K_3 = K^F  \\
    \\
    X = (C_1,C_2,K_2,K_3)   \\
    \end{array}\right. $

Terceiro passo. Vamos começar a contar o tempo em $t=0$ e não em $t=1$. Isso não tem maior importância, serve apenas para seguir a maioria dos textos.

$ \left\{ \begin{array}{l l}
    \underset{ \{C_t,K_{t+1}\}}{max} \, U = \begin{equation}
              \sideset{}{_{t=0}^1}\sum\beta^tln(C_t)
            \end{equation} \\
    K_1 = Z_0K_0^\alpha + (1-\delta)K_0 - C_0 \\
    K_2 = Z_1K_1^\alpha + (1-\delta)K_1  - C_1  \\
    K_0,Z_0,Z_1: dados \,\,\,\,\,\, K_2 = K^F  \\
    \\
    X = (C_0,C_1,K_1,K_2)   \\
    \end{array}\right. $

Quarto passo. Note que as duas expressões para a acumulação de capital têm o mesmo formato. Isso nos permite escrever a equação de acumulação para um período *t* arbitrário.

$ \left\{ \begin{array}{l l}
    \underset{{\{C_t,K_{t+1}}\}}{max} \, U(C_t)  = \begin{equation}
              \sideset{}{_{t=0}^1}\sum\beta^tln(C_t)
            \end{equation} \\
    K_{t+}1 = Z_tK_t^\alpha + (1-\delta)K_t - C_t \\
    K_0,Z_0,Z_1: dados \,\,\,\,\,\, K_2 = K^F  \\
    \end{array}\right. $

Quinto passo. (i) O limite superior do somatório na função objetivo passa de um para infinito. (ii) Todos os valores da tecnologia serão dados exogenamente. (No próximo caopítulo, a trajetória da tecnologia será descrita por uma equação em diferenças.) (iii) No modelo de dois períodos, a condição final do problema é $K_2≥0$. Mas quando o horizonte é infinito não há um último período. Para simplificar a apresentação, vamos ignorar temporariamente essa condição – mas o que acontece no “final” dos tempos aparecerá nas condições de ótimo. A versão final do problema com horizonte infinito em tempo discreto é:

$ \left\{ \begin{array}{l l}
    \underset{{\{ C_t,K_{t+1} }\}}{max} \, U  = \begin{equation}
              \sideset{}{_{t=0}^\infty}\sum\beta^tln(C_t)
            \end{equation} \\
    K_{t+1} = Z_tK_t^\alpha + (1-\delta)K_t - C_t \\
    K_0, Z_t: dados \,\,\,\,\,\,   \\
    \end{array}\right. $

Se você comparar a versão final do modelo com horizonte infinito com a versão inicial com dois períodos, notará que, embora a estrutura matemática seja mais complexa, a intuição econômica é a mesma. O problema do indivíduo consiste em escolher uma sequência de consumo e uma de capital (variáveis de controle) para maximizar uma soma ponderada de suas utilidades instantâneas (função objetivo) sujeito às restrições orçamentárias de cada período e ao estoque inicial de capital. Note que o indivíduos escolhe os consumos a partir de $t=0$ e o capital a partir de $t=1$, já que $K_0$ foi escolhido "ontem".

O que ganhamos com a maior complexidade? A possibilidade de tratar problemas econômicos em que dividir a vida em apenas dois períodos é uma simplificação excessiva. Agora, podemos falar de hoje, amanhã, depois de amanhã, depois de depois...

## A solução via Lagrange

Há mais de uma maneira de resolver o problema do indivíduo com horizonte infinito, visto na última seção. Vamos resolver formando o Lagrangeano do problema.

$   \underset{\{ C_t,K_{t+1},\lambda_t \}}{max} L  =
              \sideset{}{_{t=0}^\infty}\sum { \left( \beta^tln(C_t) +
              \lambda_t [ Z_tK_t^\alpha + (1-\delta)K_t - C_t - K_{t+1}] \right) }$

Em palavras. No período inicial $(t=0)$, o indivíduo planeja uma sequência de consumos e estoques de capital (e multiplicadores) ao longo da vida para maximizar sua expectativa de utilidade descontada ao longo da vida, com base nas informações inicialmente disponíveis.

No modelo com dois períodos, nós resolvemos o problema derivando em relação a cada variável de controle e a cada multiplicador. Aqui, entretanto, há uma infinidade de cada um deles. Na “força bruta” não conseguiremos resolver. A maneira de resolver o problema requer, em primeiro lugar, achar as condições de ótimo para um período “representativo” e, em seguida, resolver essas condições. Vejamos a primeira parte.

Considere a escolha do indivíduo em um período arbitrário *t* no futuro. Nesse período, ele deverá escolher: (i) o consumo daquele período e (ii) o estoque de capital do período seguinte.

Para facilitar a visualização do problema, vamos escrever a parte relevante do Lagrangeano de maneira mais explícita.

$  \underset{ \{ C_t,K_{t+1},\lambda_t \}}{max} L  =
    \,\,\, ... +\, \beta^tln(C_t) + \beta^{t+1}ln(C_{t+1}) \, + ... +\\
   \;\;\;\;\;\;\;\;\;\;\;\;\;\;\; + \lambda_t[Z_tK_t^\alpha + (1-\delta)K_t - C_t - K_{t+1}] \, +
    \lambda_{t+1}[ Z_{t+1}K_{t+1}^\alpha + (1-\delta)K_{t+1} - C_{t+1} - K_{t+2}] \, + ...
$

As condições de primeira ordem incluem:

$ \left\{ \begin{array}{l l}
\cfrac{\partial L}{\partial C_t} = \beta^t\cfrac{1}{C_t} - \lambda_t = 0 \\
\cfrac{\partial L}{\partial K_{t+1}} = \lambda_t - \lambda_{t+1}(\alpha Z_{t+1}K_{t+1}^{\alpha-1}
    + 1-\delta) = 0  \\
\cfrac{\partial L}{\partial \lambda_t} = K_{t+1} - Z_tK_t^\alpha - (1-\delta)K_t + C_t = 0  \\
\end{array}\right.$

Ainda falta uma condição de ótimo, relacionada com o "período final". Mas, antes vamos manipular as duas primeiras condições acima e obter um resultado interessante.

Note que, como o período *t* é arbitrário:

$ β^t \cfrac{1}{C_t} = λ_t \,\,  \Rightarrow\,\,  β^{t+1} \cfrac{1}{C_{t+1}} = λ_{t+1} $

Substitua $λ_t$ e $λ_{t+1}$ na condição de ótimo para $K_{t+1}$:

$ β^t \cfrac{1}{C_t} - \left[ β^{t+1} \cfrac{1}{C_{t+1}} \left( \alpha Z_{t+1}K_{t+1}^{\alpha-1} + 1-\delta \right) \right] = 0  $

Simplificando:

$ \cfrac{1}{C_t} =  β \cfrac{1}{C_{t+1}} \left( \alpha Z_{t+1}K_{t+1}^{\alpha-1} + 1-\delta \right)    $

Mudando os índices de tempo, essa é a equação de Euler do modelo de dois períodos com capital. (Caso houvesse ativos financeiros, em equilíbrio a taxa de juros seria igual à produtividade marginal do capital menos a depreciação, a produtividade marginal líquida do capital.) A diferença importante é que, agora, temos uma equação em diferenças que precisa ser resolvida para acharmos toda a trajetória do consumo. Neste capítulo veremos uma solução gráfica e, no próximo, uma solução numérica.

Finalmente, precisamos de uma condição de ótimo para a escolha ótima no “final” do horizonte de planejamento. No modelo de dois períodos, a condição ótima era $K_3≥0$. Sem entrar em detalhes, a condição equivalente para o caso do horizonte infinito é:

$ \lim_{t\to \infty}{ \left[ \left(β^t \cfrac{1}{C_t} \right) K_{t+1} \right] } = 0 $

O termo dentro do parêntese interior é a utilidade marginal do consumo descontada pela impaciência. O termo dentro do colchete é o valor (em utilidade descontada) do estoque de capital. Finalmente, considerando o limite quando t→∞, temos o valor no “final” do horizonte de planejamento. Ou seja, não queremos deixar sobrar no final da vida nada que esperemos ser útil.

Resumindo, as condições de equilíbrio são:

$ \left\{ \begin{array}{l l}
\cfrac{1}{C_t} =  β \cfrac{1}{C_{t+1}} \left( \alpha Z_{t+1}K_{t+1}^{\alpha-1} + 1-\delta \right) \\
K_{t+1} = Z_tK_t^\alpha + (1-\delta)K_t - C_t   \\
K_0: dado \\
\lim_{t\to \infty}{ \left(β^t \cfrac{1}{C_t}K_{t+1} \right) } = 0  \\
\end{array}\right.$

Do ponto de vista econômico, a solução desse problema consiste em trajetórias para o estoque de capital e para o consumo que respeitem: (i) a escolha ótima dos indivíduos; (ii) a disponibilidade de recursos na economia; (iii) a evolução da tecnologia; (iv) o estoque inicial de capital; e (v) a condição final de ausência de desperdício.

Do ponto de vista matemático, temos um sistema de duas equações em diferenças de primeira ordem, não lineares, para determinar duas variáveis endógenas – consumo e capital – com uma variável exógena – a tecnologia. As trajetórias devem respeitar as chamadas condições de contorno – o estoque inicial de capital e o seu valor “no infinito”.

## O diagrama de fases

A solução gráfica do problema requer a construção do que é conhecido como o “diagrama de fases” do problema. No nosso caso, o diagrama de fases é apenas um gráfico de $(C\, x\, K)$ no qual vamos representar: (i) o estado estacionário da economia e (ii)  as possíveis trajetórias conjuntas do consumo e do estoque de capital fora do estado estacionário.

Para fazer o diagrama de fases é importante lembrar que, no estado estacionário:

$C_t=C_{t+1}=C$, \, $K_t=K_{t+1}=K, \, Z_t=Z_{t+1}=Z$

Nossa estratégia é a seguinte. Primeiro, vamos determinar as combinações de consumo e capital que mantém o consumo constante – e vamos representar essas combinações no gráfico $(C\, x\, K)$. Em seguida, faremos a mesma coisa com as combinações que mantém o capital constante. Finalmente, veremos o que acontece com duas as variáveis quando elas não são constantes.

A equação em diferenças que determina o movimento do consumo é:

$ \cfrac{1}{C_t} =  β \cfrac{1}{C_{t+1}} \left( \alpha Z_{t+1}K_{t+1}^{\alpha-1} + 1-\delta \right) $

Portanto:

$ C_t =  C_{t+1} ⇒ 1 = β \left(αZK_{t+1}^{α-1} +1-δ \right) $

Ou seja:

$ K_{t+1} = K^* = { \left[ \cfrac{1}{\alpha Z } \left( \cfrac{1}{\beta} - 1 + \delta \right) \right] } ^{\frac{1}{\alpha-1} } $

Essa expressão não depende do consumo e, portanto, é uma reta vertical $(\bar{C})$ no plano $(C\,x\,K)$; ver Figura 1.

Quando $K_(t+1)=K^*$, o retorno por acumular uma unidade a mais de capital $\left( αZK_{t+1}^{α-1}+1-δ \right)$ – equivalente à taxa de juros – é igual à perda por esperar para consumir, a impaciência; nesse ponto, o consumo é constante, como vimos em outras versões da equação de Euler. À direita da reta vertical $K_{t+1}>K^*$, o retorno do investimento será menor que a impaciência (pois a produtividade marginal do capital $\left( αZK_{t+1}^{α-1} \right)$ é decrescente) e o consumo será decrescente. Verifique isso na expressão. De forma equivalente, à esquerda de $K^*$ o consumo será crescente. Isso é representado no gráfico pelas setas verticais.

Vejamos, agora, a condição para o estoque de capital ficar constante. A equação em diferenças que determina o movimento do capital é:

$ K_{t+1} = Z_tK_t^\alpha + (1-\delta)K_t - C_t $

$ K_t = K_{t+1} \,\, ⇒ \,\, C=ZK^α-δK $

Essa equação indica que o estoque de capital ficará constante quando o consumo for igual à produção líquida. A equação é representada por uma curva que sai da origem, é inicialmente crescente, atinge um máximo e decresce; curva (k ̇ ). Em pontos acima da curva, o consumo é superior à produção líquida, o estoque de capital diminui e as setas horizontais apontam para a direita. De forma equivalente para pontos abaixo da curva.

Resumindo, o estado estacionário é dado por:

$ \left\{ \begin{array}{l l}
1 = β \left(αZK_{t+1}^{α-1} +1-δ \right) \\
C=ZK^α-δK \\
\end{array}\right.$

Antes de prosseguir com a análise do gráfico, é preciso considerar a segunda simplificação mencionada acima. Na discussão acima, nós implicitamente consideramos que cada período é bastante curto e que $K_t \approx K_{t+1}$. Sem essa aproximação a curva que determina $C_t = C_{t+1}$ não seria vertical, mas positivamente inclinada. Se considerarmos o limite quando os períodos se tornam cada vez mais curtos, teremos um modelo em tempo contínuo e a curva será vertical sem aproximações. Entretanto, para nossos objetivos, não é necessária uma discussão mais detalhada.

A Figura 2 mostra uma trajetória da economia a partir de uma posição inicial arbitrária. No ponto B: (i) a taxa de juros é superior à impaciência, o consumo aumenta e a economia se move para cima; (ii) o consumo é inferior à renda, o estoque de capital aumenta e a economia se move para a direita. O resultado é que a economia se desloca, ao longo tempo, na direção nordeste. Neste exemplo, a economia atinge a curva (k ̇ ) antes da (c ̇ ) e, a partir daí segure na direção noroeste rumo a D. Ao atingir o eixo vertical, o estoque capital acaba, não há mais renda nem consumo e a economia vai para a origem, que também é um estado estacionário. (Note que no ponto C, o movimento da economia é exclusivamente vertical para cima.)

A Figura 3 mostra várias trajetórias possíveis. Vemos que há apenas duas curvas que levam ao estado estacionário. Além disso, é possível mostrar que duas trajetórias jamais se cruzam e que por cada ponto do gráfico passa uma curva. A Figura 3 indica que para cada nível de capital existe apenas um nível de consumo que coloca a economia em uma trajetória que leva ao estado estacionário, a chamada trajetória convergente ou  saddle-path. Se, para um nível de capital inicial, consumo inicial for muito grande ou muito pequeno, a economia não irá para o estado estacionário.

A discussão até agora ignorou a condição inicial $(K_0:\,dado)$ e a condição final do sistema $\left(\lim_{t\to \infty}{ \left(β^t \frac{1}{C_t}K_{t+1} \right) } = 0  \right)$. Vejamos o que elas nos dizem.

Como o nome sugere, a condição inicial indica a posição de partida da economia. Essa condição especifica apenas o estoque de capital inicial; o consumo inicial não é um dado do problema, mas uma escolha do indivíduo. Qualquer que seja o consumo inicial escolhido pelo indivíduo, ele deverá estar sobre uma reta vertical que passe por $K_0$. Caso contrário, ou o indivíduo estaria destruindo capital inutilmente ou criando capital a partir do nada.

Uma vez que o indivíduo tenha escolhido o consumo inicial, a economia segue a trajetória descrita pela curva correspondente. Uma trajetória que comece acima do saddle-path não pode ser uma escolha ótima, pois, a longo prazo, o estoque de capital irá para zero, o indivíduo não terá mais recursos e morrerá de fome. A utilidade marginal do capital será tão grande que a condição final não será respeitada. Da mesma forma, uma trajetória que comece abaixo do saddle-path tampouco será ótima, pois o consumo também irá para zero. O gráfico indica que apenas as trajetórias que levem ao estado estacionário podem ser ótimas e isso determina o consumo inicial ótimo.

O comportamento ótimo pode ser resumido em dois passos: (i) escolher o consumo inicial ótimo e (ii) escolher os consumos subsequentes respeitando  equação de Euler. O consumo inicial ótimo é aquele que, seguindo a equação de Euler no futuro, exatamente esgota a restrição orçamentária intertemporal (incluindo a condição final).

## Exemplos

Exemplo 1: Suponha que a economia esteja inicialmente no estado estacionário e que uma catástrofe natural destrua parte do estoque de capital. O estoque de capital passa de $K_0$ para $K_1$ na Figura 4 – note que essa redução não foi escolhida pelos agentes. A escolha ótima coloca a economia no ponto *B*. Nesse ponto, os indivíduos consomem menos que a renda líquida, e o estoque de capital aumenta. Além disso, inicialmente o retorno do investimento está acima da impaciência e os indivíduos desejam consumo crescente.

O resultado é bastante intuitivo. A destruição do estoque de capital não alterou as condições estruturais da economia: a função de produção, as preferência e a tecnologia continuam as mesmas. Portanto, o estado estacionário continua o mesmo. Para poderem recuperar seu estoque de capital, os indivíduos reduzem seu consumo inicial abaixo da nova e menor renda líquida e, à medida que vão ficando mais ricos, passam a consumir mais até voltarem ao estado estacionário original.

Comentário

(i) O consumo pode dar saltos de um período para o seguinte. Mas o estoque de capital não pode: não vamos destruir capital e não podemos criá-lo do nada.

(ii) Nesse modelo, embora o consumo possa dar saltos em qualquer período a escolha ótima requer os eventuais saltos ocorram apenas no período inicial. Um salto planejado ao longo da trajetória futura violaria a equação de Euler e não seria ótimo. Um salto do consumo no período inicial responde a um choque inesperado, não foi planejado e não tem como ser evitado.

(iii) O problema é resolvido de trás para frente. Primeiro: determine o estado estacionário (posição final). Segundo: determine a (única) trajetória convergente que leva ao estado estacionário. Terceiro: Determine a (única) posição inicial da variável de controle que coloca a economia sobre a trajetória convergente.	♠

### Política fiscal simplificada

Vamos considerar algumas variações no gasto público. Para concentrar em um caso bastante simples, suponha que: (i) o governo mantenha o orçamento equilibrado a cada período $(G_t=T_t)$; (ii) o gasto público não afete nem a utilidade dos agentes nem a produção da economia; e (iii) que os impostos sejam *lump-sum*. Nesse caso, o problema do indivíduo passa a ser:

$ \left\{ \begin{array}{l l}
    \underset{{{ C_t,K_{t+1} }}}{max} U  = \begin{equation}
              \sideset{}{_{t=0}^\infty}\sum\beta^tln(C_t)
            \end{equation} \\
    K_{t+1} = Z_tK_t^\alpha + (1-\delta)K_t - C_t - T_t \\
    K_0: dado \,\,\,\,\,\,   \\
    \lim_{t\to \infty}{ \left(β^t \cfrac{1}{C_t}K_{t+1} \right) } = 0  \\
    \end{array}\right. $

É fácil ver que o equilíbrio da economia será dado por:

$ \left\{ \begin{array}{l l}
\cfrac{1}{C_t} =  β \cfrac{1}{C_{t+1}} \left( \alpha Z_{t+1}K_{t+1}^{\alpha-1} + 1-\delta \right) \\
K_{t+1} = Z_tK_t^\alpha + (1-\delta)K_t - C_t  -G_t \\
K_0: dado \\
\lim_{t\to \infty}{ \left(β^t \cfrac{1}{C_t}K_{t+1} \right) } = 0  \\
\end{array}\right.$

E as condições de estacionariedade das variáveis são:

$ \left\{ \begin{array}{l l}
C = ZK^α - δK -G \\
1 = β \left(αZK^{α-1} +1-δ \right) \\
\end{array}\right.$

A única modificação em relação ao caso sem governo é a presença do gasto público na equação de acumulação. Essa simplicidade depende das três hipóteses acima sobre a política fiscal.

Exemplo 2: Considere um aumento inesperado e permanente no gasto público.

As condições de estacionariedade mostram que a curva $(\bar{C})$ não se desloca e que a curva $(\bar{K})$ se desloca paralelamente para baixo: o consumo privado é integralmente deslocado pelo gasto do governo.  Se a economia está inicialmente em equilíbrio no ponto A, o consumo é reduzido para B e a economia passa instantaneamente para seu novo estado estacionário, sem nenhuma dinâmica de transição – ver Figura 5.

É claro que do ponto de vista do bem-estar o novo estado estacionário é inferior ao original, ou seja, o aumento no gasto público reduziu o bem-estar dos agentes. Embora isso seja verdade nesse modelo simplificado, é preciso tomar algum cuidado com essa conclusão. 	♣

Exemplo 3: Aumento antecipado e permanente no gasto público.

Quando ocorrer, o aumento no gasto do governo deslocará a curva (K ̇ ) paralelamente para baixo.  O estado estacionário passará de A para D – ver Figura 6.

Para descobrir a trajetória de transição ótima, observe que, enquanto o aumento anunciado do gasto do governo não tiver ocorrido, as curvas relevantes são (K ̇ ) e (C ̇ ).  Quando o gasto for efetivamente aumentado, as curvas relevantes passam a ser  (K ̇^' ) e (C ̇ ). No momento em que o gasto do governo for efetivamente alterado, a economia deve estar em algum ponto sobre o saddle path que leva a D. Se não estiver, terá que haver um salto no nível de consumo.  Mas isso implica uma descontinuidade planejada na utilidade marginal do consumo – o que viola as condições para a maximização de utilidade.  Portanto, no instante em que o aumento no gasto é anunciado, os agentes devem ajustar seu consumo de forma que a economia atinja o saddle path que leva a D no instante em que o gasto for efetivamente aumentado.

A Figura 6 mostra que, inicialmente, o consumo cai de A para B.  No ponto B, o campo de força da economia aponta na direção leste e, imediatamente à direita de B, na direção sudeste.  (O consumo do governo ainda não aumentou e as curvas relevantes continuam sendo (K ̇ ) e (C ̇ ).) A partir de B, a economia desloca se em direção ao ponto sobre o saddle path que leva a D. Durante esta etapa, o consumo cai e o estoque de capital aumenta.  O aumento no estoque de capital implica na queda da sua produtividade marginal e, portanto, no retorno do capital.  A trajetória de B para C é uma etapa de aumento de poupança para fazer face ao aumento esperado no gasto do governo: os agentes reduzem seu consumo/aumentam sua poupança.  Lembre que acumular capital é a única forma dessa economia fechada poupar agregadamente. A economia atinge o ponto C exatamente no instante em que o governo aumenta efetivamente os gastos.  Nesse instante, as novas curvas relevantes são (K ̇ ) e (C ̇ ), a economia está sobre o novo saddle path e se dirigirá, sem novos saltos, para D.

Supusemos que os agentes consigam calcular exatamente qual o valor do consumo inicial necessário para atingirem o estado estacionário final sem saltos antecipados no consumo. É claro que as pessoas não têm esse nível de precisão. O que acontece quando elas percebem que erraram seus cálculos e caminham para uma situação insustentável? Quando percebem isso, as pessoas refazem seus planos e ajustam seu consumo de forma a passar a uma trajetória que julguem sustentável. As trajetórias reais terão uma série de ajustes não planejados em torno da trajetória ideal.
Como sempre, um modelo é uma simplificação da realidade que visa capturar as características mais importantes do comportamento da economia. Nesse exemplo, o que é qualitativamente importante é que as pessoas começam a poupar antes do governo aumentar o gasto e, quando os impostos efetivamente aumentam, passam a despoupar. Sabendo que ficarão mais pobres no futuro, as pessoas transferem recursos do período de vacas gordas para o de vacas magras.	♣

## Conclusão

Este capítulo mostrou como estender nosso modelo básico para um número infinito de períodos e como fazer uma análise gráfica do equilíbrio da economia. Lembre que os gráficos estão baseados em uma aproximação supondo que o tamanho dos períodos seja pequeno; em tempo contínuo, os gráficos estariam exatos. É claro que os gráficos fornecem apenas soluções qualitativas. Veremos a seguir como resolver esse modelo numericamente para obter resultados mais precisos.

## Resumo

Problema do indivíduo

$ \left\{ \begin{array}{l l}
    \underset{{\{ C_t,K_{t+1} }\}}{max} \, U  = \begin{equation}
              \sideset{}{_{t=0}^\infty}\sum\beta^tln(C_t)
            \end{equation} \\
    K_{t+1} = Z_tK_t^\alpha + (1-\delta)K_t - C_t \\
    K_0, Z_t: dados \,\,\,\,\,\,   \\
    \end{array}\right. $

Equilíbrio

$ \left\{ \begin{array}{l l}
\cfrac{1}{C_t} =  β \cfrac{1}{C_{t+1}} \left( \alpha Z_{t+1}K_{t+1}^{\alpha-1} + 1-\delta \right) \\
K_{t+1} = Z_tK_t^\alpha + (1-\delta)K_t - C_t   \\
K_0: dado \\
\lim_{t\to \infty}{ \left(β^t \cfrac{1}{C_t}K_{t+1} \right) } = 0  \\
\end{array}\right.$

## Exercícios

**Exercício 1**

Considere um aumento permanente e inesperado na taxa de impaciência. Descreva o ajustamento da economia.

Resposta

♥

**Exercício 2**

Considere um aumento antecipado e permanente no gasto público financiado por impostos lump-sum. Descreva o ajustamento da economia.

Resposta

♦

**Exercício 3**

Considere um aumento antecipado e temporário no gasto público financiado por impostos lump-sum. Descreva o ajustamento da economia.

Resposta (Há dois conjuntos de setas que correspondem a períodos diferentes.)

♠

**Exercício 4**

No exercício 3, o governo anunciou que o aumento nos gastos era temporário e, efetivamente, os reduziu no momento combinado.  Suponha, agora, que, na hora de reduzir os gastos, o governo decida prorrogá los por mais alguns períodos e depois cumpra a promessa de reluzi-los.  Descreva o ajustamento da economia.

Resposta (Há dois conjuntos de setas que correspondem a períodos diferentes.)

♣

## Referências e leitura adicional

[Plosser](https://www.aeaweb.org/articles?id=10.1257/jep.3.3.51) e
[Mankiw](https://www.aeaweb.org/articles?id=10.1257/jep.3.3.79) avaliam os modelos *RBC*.

O capítulo 2 de [Obstfeld & Rogoff](https://www.amazon.com/Foundations-International-Macroeconomics-MIT-Press/dp/0262150476) e o capítulo 9 de [Garin, Lester & Sims](https://www3.nd.edu/~esims1/gls_textbook.html) são boas referência para o modelo de horizonte infinito em tempo discreto. [Hejdra](https://global.oup.com/academic/product/foundations-of-modern-macroeconomics-9780198784135?cc=br&lang=en&#) e [Romer](https://www.mheducation.com/highered/product/advanced-macroeconomics-romer/M9781260185218.html) para o modelo em tempo contínuo.

```julia

```


# **SimBot-1 Notebook: Differential Drive Robots**
***

Differential Drive Robots (DDR) are based upon the concept that a robot with two opposing wheels and a simple DC motor for each wheel is all you need to control the simple movement of a robot in a 2D plane.

Now that we have covered the basics of Python, we will advance to simple exercises involving a simulated DDR.

In this course you will gain experience in coding for DDRs yet will not have to struggle with the challenging world of hardware and SSH connections to the RaspberryPi. The AlphaBot2 robot utilizing the RaspberryPi system is the robot for which we will be writing simulation code.
#### **Figure 1:** Elevation view of the AlphaBot2 system

#### **Figure 2:** Plan view of AlphaBot2 base

#### **Table 1:** Base description

AlphaBot2 robot building kit for Raspberry Pi 3 Model B. (n.d.). Retrieved from https://www.waveshare.com/alphabot2-pi.htm

The input used in this course is the Ultrasonic Ranging Sensor (URS) and the outputs are the two differential drive motors. As seen in Figure 2, the elements labeled "10" on the left-hand image are the differential drive motors.

A URS is effectively a sonar sensor that sends an ultrasonic signal forward and picks up any waves that bounce backward off an object in front of the sensor. Based upon the duration of time from when the signal is sent to when a signal is received, the robot can determine the distance from the robot to an object due to the average speed of the sound waves.

Alphabot2 is a DDR: Two independent motors drive the left and right wheels and the differential speed between the two wheels control the speed and direction of the robot. As explained above, DDR is a system of two dual-directional DC motors mounted colinearly, mirrored about the forward-backward plane. Each motor can independently be turned either high or low (on or off). Does this provide every movement necessary to control the robot in a 2D plane?

Yes! So let's get to it!

# **SimBot-1 Notebook: Intro to Robot Classes and Methods**
The SimBot-1 defines classes and methods to control and move a simulated AlphaBot2 (described above).

For this course we will learn what this SimBot-1 Notebook enables us to do with the AlphaBot2.  As mentioned in Intro Notebook 4, you can define your own classes and inside those classes define your own methods. By the end of this notebook you too will be writing code to drive the AlphaBot2.

 Much of the code is originally sourced from http://enesbot.me/kinematic-model-of-a-differential-drive-robot.html

The code in this notebook is more complex by nature of its objective. Some of the code is not required to understand the focus of this intro course - but it certainly wont hurt. There will be deliniation of expected understanding. In many cells, reading the doc string will often enable you to ascertain if it is necessary to understand that class, method etc.

***
Not salient:

```python
"""Header cell, contains modules and functions to make the whole notebook experience better"""
%matplotlib inline
# plots graphs within the notebook

from IPython.display import display,Image, Latex
from sympy.interactive import printing
printing.init_printing(use_latex='mathjax')
from IPython.display import clear_output

import time

from IPython.display import display,Image, Latex

from IPython.display import clear_output

import matplotlib.pyplot as plt
import numpy as np
import math
import scipy.constants as sc

import sympy as sym

font = {'family' : 'serif',
        #'color'  : 'black',
        'weight' : 'normal',
        'size'   : 12,
        }
fontlabel = {'family' : 'serif',
        #'color'  : 'black',
        'weight' : 'normal',
        'size'   : 12,
        }

from matplotlib.ticker import FormatStrFormatter
plt.rc('font', **font)

class PDF(object):

    def __init__(self, pdf, size=(200,200)):
        self.pdf = pdf
        self.size = size

    def _repr_html_(self):
        return ''.format(self.pdf, self.size)

    def _repr_latex_(self):
        return r'\includegraphics[width=1.0\textwidth]{{{0}}}'.format(self.pdf)

class ListTable(list):
    """ Overridden list class which takes a 2-dimensional list of
        the form [[1,2,3],[4,5,6]], and renders an HTML Table in
        IPython Notebook. """

    def _repr_html_(self):
        html = ["<table>"]
        for row in self:
            html.append("<tr>")

            for col in row:
                html.append("<td>{0}</td>".format(col))

            html.append("</tr>")
        html.append("</table>")
        return ''.join(html)

```

## Objective
This notebook focuses on the control of a simulated differential drive robot for prescribed simple tasks.

## Theoretical Background

The robot parameters are:

 Wheel radius: $r$.

 Length between wheels: $L$

 Angular velocity of the left and right wheels: $\omega_L$, $\omega_R$, respectively.

 Angle from horizontal: $\alpha$.

 Position vector of the robot: $(x,y)$.

 Velocity vector of the robot: $V=(\dot{x},\dot{y})$.

Below is a diagram showing the nomenclature for the variables defined above:

#### **Figure 3: Differential Drive Nomenclature**

Hereafter $\dot{a}$ refers to the time derivative of variable $a$:

$$
\dot{a}=\frac{da}{dt}
$$

The velocities of the wheels are therefore defined as:

$$
V_L=\omega_Lr\text{ and }V_R=\omega_Rr
$$

The velocity of the robot, taken at the center of the wheels, is simply:

$$
\vec{V}=\frac{V_R+V_L}{2}(\cos(\alpha)\vec{e}_x+\sin(\alpha\vec{e}_y),
$$

yielding the following equations of motions:

$$
\dot{x}=r\frac{\omega_R+\omega_L}{2}\cos{\alpha}
$$

$$
\dot{y}=r\frac{\omega_R+\omega_L}{2}\sin{\alpha}
$$

and

$$
\dot{\alpha}=\frac{r}{L}(\omega_R-\omega_L)
$$

Numerically, these solutions of these equations requires their discretization. Remember that the derivative $\frac{da}{dt}$ of a variable $a=f(t)$ is the slope $s$ of the local tangent. Over a small enough time interval $\Delta t$, any continuous function $f$ can be approximated by a linear function based on the slope $a(t+\Delta t) =a(t)+s(t)\Delta t$. The derivative is then estimated as:

$$
\frac{da}{dt}\approx\frac{\Delta a}{\Delta t}
$$

where $\Delta a=a(t+\Delta t$)-a(t). The discretized equations of motion may be recast as an integration of the trajectory of the robot:

$$
x(t+\Delta t) = x(t) +\Delta t\left(r\frac{\omega_R+\omega_L}{2}\cos{\alpha}\right),
$$

$$
y(t+\Delta t) = y(t) +\Delta t\left(r\frac{\omega_R+\omega_L}{2}\sin{\alpha}\right),
$$

$$
\alpha(t+\Delta t) = \alpha(t) +\Delta t\left(r\frac{\omega_R-\omega_L}{L}\right).
$$

As long as the initial conditions are prescribed at $t=0$, the motion of the robot is predictable providing that $\Delta t $ is not too large, as we shall see later. The present discretization is the simplest one, and also the most rudimentary. Even though the above equations carry fairly large numerical errors, no robot is perfect and these numerical errors will not be discussed here.

## Code description

The cell below includes two classes, named Robot and DDRobot. Robot defines the robot dimensions, position variables ($x,y,\alpha$), the time step $ \Delta t $, the left/right angular velocities and various functions necessary to integrate the robot motion.
 DDRobot handles much of the movement of the robot through methods which call initialization objects defined in the Robot class. DDRobot is the main class while Robot is effectively created within class DDRobot as many of the methods from Robot class are called within DDRobot class.

Read carefully through the following extensively commented cell to learn the Robot and DDRobot classes:

```python
import matplotlib.pyplot as plt #enables plotting capabilities for the robot
                                #for this case this is the OUTPUT as the whole
                                #robot is simulated through this notebook
import numpy as np #Numerical Python library as described in the Intro Python Notebook
import math #math module
import scipy.constants as sc #shortcut for physical and mathematical constants
                             #and units
import sympy as sym #SymPy is a Python library for symbolic mathematics

from math import sin, cos

class Robot(object):
    """Defines basic mobile robot properties. Defines __init__, step, print_xya, and
    plot_robot methods. Is called in the main class of DDRobot."""
    def __init__(self):
        #initialization class.
        self.pos_x  = 0.0 #placing bot at origin: (x,y) = (0,0)
        self.pos_y  = 0.0
        self.angle  = 0.0 # IN RAD setting alpha = 0
        self.plot   = False #intializing no plot to show
        self._delta = 0.01 #
        self.step_plot = int(8) #plotting every 5 iterations
        self.mag_plot = 1.5 # arrow magnification

    # Movement
    def step(self):
        """ updates the x,y and alpha """
        self.deltax()
        self.deltay()
        self.deltaa()

    def move(self, seconds):
        """ Moves the robot for an 's' amount of seconds. Takes argument of seconds as type
        int"""
        for i in range(int(seconds/self._delta)):
            self.step()
            if i % self.step_plot == 0 and self.plot: # plot path every 5 steps
                self.plot_xya() #plots a dot in the position of the robot

    # Printing-and-plotting:
    def print_xya(self):
        """ prints the x,y position and angle """
        print ("x = " + str(self.pos_x) +" "+ "y = " + str(self.pos_y))
        print ("a = " + str(self.angle))

    def plot_robot(self):
        """ plots an arrow representation of the robot. """
        plt.arrow(self.pos_x, self.pos_y, 0.001
                  * cos(self.angle), 0.001 * sin(self.angle),
                  head_width=self.mag_plot*self.length, head_length=self.mag_plot*self.length,
                  fc='k', ec='k')

    def plot_xya(self):
        """ plots a dot in the position of the robot """
        plt.scatter(self.pos_x, self.pos_y, c='r', edgecolors='r')

class DDRobot(Robot):
    """Defines a differential drive robot. Is the main class. Moves the robot.
    Class Robot is effectively created within class DDRobot as many of the
    methods from Robot class are called within DDRobot class."""

    def __init__(self):
        """__init__ : Initialization class (for DDRobot class)"""
        Robot.__init__(self)
        self.radius = 0.1 #radius of bot wheel as defined in Fig 3
        self.length = 0.4 #length between bot wheels as defined in Fig 3
        self.rt_spd_left = 0.0 #initializing rotation speed, left wheel to 0
        self.rt_spd_right = 0.0 #initializing rotation speed, right wheel to 0

    def deltax(self):
        """ update x position depending on L and R angular speeds """
        self.pos_x += self._delta * (self.radius*0.5) \
        * (self.rt_spd_right + self.rt_spd_left)*cos(self.angle)

    def deltay(self):
        """ update y position depending on l and r angular speeds """
        self.pos_y += self._delta * (self.radius*0.5) \
        * (self.rt_spd_right + self.rt_spd_left)*sin(self.angle)

    def deltaa(self):
        """ update angle depending on l and r angular speeds """
        self.angle += self._delta * (self.radius/self.length) \
        * (self.rt_spd_right - self.rt_spd_left)

def D2R(a):
    """function to convert degrees to radians. Takes single argument of degrees."""
    return float(((math.pi)*float(a))/180.0)
def R2D(a):
    """Function to convert radians to degrees. Takes single argument of radians."""
    return float((180.0*float(a)/(math.pi)))

```

### Deriving time required to make a turn of a specified angle:
$\bar{\omega}$ (average angular velocity), is equal to: $\bar{\omega} = \frac{\Delta \Theta}{\Delta t}$ where $\Delta \Theta$ is change in angle, and $\Delta t$ is change in time. As we are specifying the $\Theta$ and and $\bar{\omega}$ of the turn, we can solve for the time required and then derive a relation for the exact time needed for the robot to achieve a rotation of a given angle around its center.

$V = \frac{\omega}{t}$

Solving for $t$:

$t = \frac{\omega}{V}$

$t = \frac{\theta}{\frac{\pi}{2}{0.63}}$

## DDR Movement Commands:

To efficiently repeatedly call a class, one should use object instantiation as explained in Notebook 4. The following cell screenshot shows the object instantiation of the DDRobot class under the object name mybot:

(If another class had been instantiated to the object mybot, it would have been overridden by this new class object instantiation)

```python
# object instantiation
mybot = DDRobot() # instantiating/creating an object instance of the DDRobot() class
                    # enables methods to be passed to the Robot and DDRobot classes as objects
```

For simplicity, assume that all units are based on the metric system. Your new robot, mybot, is by default located at $(x=0,y=0)$, its angle from the horizontal axis $x$ is $0$ and the wheel radius and length between wheel are $r=0.1$m and $L=0.4$m (see class DDRobot). The default time step is $\Delta t=0.01$s. All these variables and more can be easily customized to your problem:

```python
#object instantiation
mybot = DDRobot()
mybot.pos_x = 0 #x
mybot.pos_y = 0 #y
mybot.angle = D2R(45) #alpha
mybot.length =0.4 #L
mybot.radius = 0.1 #r
mybot.rt_spd_left = 10 # omega_L
mybot.rt_spd_right = 10 # omega_R
```

#### Ex: Drive DDR in a straight line:
In simplest terms to move a DDR, you initialize each motor at a specified power and then pass the mybot.move(seconds) command.

For a straight line you set each motor at equal power, and for a turn at unequal power.

We will step through the commands required to execute a straight line in the following extensively commented cell.

```python
# object instantiation
mybot = DDRobot()             # creating an instance of DDRobot() enables methods to be passed to the
                              #    Robot and DDRobot classes as objects
# initialization block as mentioned above
mybot.pos_x = 5               # calling pos_x method to set x initial position - in center of plot
mybot.pos_y = 5               # calling pos_y method to set y initial position - in center of plot
mybot.angle = 0               # initial starting direction: 0 radians from horizontal
mybot.plot = True             # turning on plot
mybot.mag_plot = 1.5          # coefficient of magnification of the arrow
mybot.step_plot = 20          # plotting robot's path as dots
mybot.plot_robot()            # plotting the robot!

# movement block
mybot.rt_spd_left = 10        # setting rotational speed of left motor to 10
mybot.rt_spd_right = 10       # setting rotational speed of right motor to 10
mybot.move(4)                 # move for 4 seconds at set specifications

#resizing plot block
mybot.plot_robot()            # plotting robot's movement
plt.xlim([0, 10])             # axis limits
plt.ylim([0, 10])
plt.rcParams["figure.figsize"] = (10,10) # forcing a square shape for plot
plt.show()                    # plotting full course of robots path
```

You may change the size of the arrow and the spacing of the dots tracing the trajectory using the mag_plot and step_plot attributes:

```python
# object instantiation
mybot = DDRobot()             # creating an instance of DDRobot() enables methods to be passed to the Robot and DDRobot classes as objects
# initialization block as mentioned above
mybot.pos_x = 5               # calling pos_x method to set x initial position - in center of plot
mybot.pos_y = 5               # calling pos_y method to set y initial position - in center of plot
mybot.angle = 0               # initial starting direction: 0 radians from horizontal
mybot.plot = True             # turning on plot

mybot.mag_plot = 3          # coefficient of magnification of the arrow
mybot.step_plot = 50          # plotting robot's path as dots

mybot.plot_robot()            # plotting robot's movement
# movement block
mybot.rt_spd_left = 10        # setting rotational speed of left motor to 10
mybot.rt_spd_right = 10       # setting rotational speed of right motor to 10
mybot.move(4)                 # move for 4 seconds at set specifications
#resizing plot block
mybot.plot_robot()            # plotting robot's movement
plt.xlim([0, 10])             # axis limits
plt.ylim([0, 10])
plt.rcParams["figure.figsize"] = (10,10) # forcing a square shape for plot
plt.show()                    # plotting full course of robots path
```

### **Q1: Executing a turn:** Make a turn for 3 seconds using the above code as a framework:

```python
#your code here:
```

### Now completing a full rotation:
We steped through the commands required to execute a straight line in the previous exercise and you just completed a turn for 3 seconds.

As you likely discovered, to execute a turn with a DDR, the left and right angular velocities, $\omega_{L}$ and $\omega_{R}$ must be different. Therefore the only difference from a straight line in the code is to change one motor's power initialization setting to create an imballance in power applied to the bot.

We will now derive the time, $t$ needed to turn the robot an angle $\alpha_o$ at given rotation speed $\omega_L$ and $\omega_R$ and robot dimensions $r$ and $L$. This equation starts by intergrating the robot angle equation above:

$$
\dot{\alpha}=\frac{d\alpha}{dt}=\frac{r}{L}(\omega_R-\omega_L)
$$

from $0$ to a time $t$ yields

$$
\int_0^t\frac{d\alpha}{dt}dt=\int_0^t\frac{r}{L}(\omega_R-\omega_L)dt
$$

Since the left hand side function is constant with respect to time, the result is simply:

$$
\alpha(t) - \alpha(0) =tr\frac{\omega_R-\omega_L}{L}
$$

Therefore the time to execute a rotation of angle $\alpha_o=\alpha(t) - \alpha(0)$ is

$$
t = \frac{\alpha_oL}{r(\omega_R-\omega_L)} \;\;\;\mathrm{Eq. Time\,of\,Turn}
$$

We will now implement the Time of Turn equation in the following cell:

```python
#object instantiation
mybot = DDRobot()               # enables methods to be passed to the Robot and DDRobot classes as objects
#initialization block
mybot.pos_x = 5              # calling pos_x method to set x initial position - in center of plot
mybot.pos_y = 5              # calling pos_y method to set y initial position - in center of plot
mybot.angle = float(D2R(0))  # initial starting direction: 0 radians
mybot.plot = True            # turning on plot
mybot.mag_plot = 1           # coefficient of magnification of the arrow
mybot.step_plot = 20
mybot.plot_robot()           # plotting the robot!

#movement block:
a_t = D2R(360)
mybot.rt_spd_left = 4*math.pi
mybot.rt_spd_right = 6*math.pi
# Time of Turn eq:
t = ((a_t - mybot.angle)*mybot.length)/(mybot.radius*(mybot.rt_spd_right - mybot.rt_spd_left))
mybot.move(t)                 # move for t seconds

#plotting block
mybot.plot_robot()            # plot robot's entire path
plt.xlim([0, 10])             # axis limits
plt.ylim([0, 10])
plt.rcParams["figure.figsize"] = (10,10) # forcing size as square
plt.show()
```

### **Q2: Square:** Now that you have completed a straight line and a turn, you have all the components to complete a square. Synthesize the two blocks of code to transcribe a square:

```python
#your code here:
```

#### Ex: Repeated Code Block: Hexagon:
Below is a demonstration on how to make a hexagon via two repeated code blocks:

```python
#object instantiation
mybot = DDRobot()             # enables methods to be passed to the Robot and DDRobot classes as objects

#initialization block
mybot.pos_x = 10               # calling pos_x method to set x initial position - in center of plot
mybot.pos_y = 10               # calling pos_y method to set y initial position - in center of plot
mybot.angle = D2R(0)         # initial starting direction: 0 rad
mybot.plot = True             # turning on plot
mybot.mag_plot = 1           # coefficient of magnification of the arrow
mybot.step_plot = 20
mybot.plot_robot()            # plotting the robot!

#movement block:
    #1 side
#forward
mybot.rt_spd_left = 10
mybot.rt_spd_right = 10
mybot.move(3)
#turn
a_t = D2R(60)
mybot.rt_spd_left = 4*math.pi
mybot.rt_spd_right = 6*math.pi
# Time of Turn eq:
t = ((a_t - 0)*mybot.length)/(mybot.radius*(mybot.rt_spd_right - mybot.rt_spd_left))
mybot.move(t)                 # move for t seconds

    #1 side
#forward
mybot.rt_spd_left = 10
mybot.rt_spd_right = 10
mybot.move(3)
#turn
mybot.rt_spd_left = 4*math.pi
mybot.rt_spd_right = 6*math.pi
# Time of Turn eq:
t = ((a_t - 0)*mybot.length)/(mybot.radius*(mybot.rt_spd_right - mybot.rt_spd_left))
mybot.move(t)                 # move for t seconds

    #1 side
#forward
mybot.rt_spd_left = 10
mybot.rt_spd_right = 10
mybot.move(3)
#turn
mybot.rt_spd_left = 4*math.pi
mybot.rt_spd_right = 6*math.pi
# Time of Turn eq:
t = ((a_t - 0)*mybot.length)/(mybot.radius*(mybot.rt_spd_right - mybot.rt_spd_left))
mybot.move(t)                 # move for t seconds

    #1 side
#forward
mybot.rt_spd_left = 10
mybot.rt_spd_right = 10
mybot.move(3)
#turn
mybot.rt_spd_left = 4*math.pi
mybot.rt_spd_right = 6*math.pi
# Time of Turn eq:
t = ((a_t - 0)*mybot.length)/(mybot.radius*(mybot.rt_spd_right - mybot.rt_spd_left))
mybot.move(t)                 # move for t seconds

    #1 side
#forward
mybot.rt_spd_left = 10
mybot.rt_spd_right = 10
mybot.move(3)
#turn
mybot.rt_spd_left = 4*math.pi
mybot.rt_spd_right = 6*math.pi
# Time of Turn eq:
t = ((a_t - 0)*mybot.length)/(mybot.radius*(mybot.rt_spd_right - mybot.rt_spd_left))
mybot.move(t)                 # move for t seconds

    #1 side
#forward
mybot.rt_spd_left = 10
mybot.rt_spd_right = 10
mybot.move(3)
#turn
mybot.rt_spd_left = 4*math.pi
mybot.rt_spd_right = 6*math.pi
# Time of Turn eq:
t = ((a_t - 0)*mybot.length)/(mybot.radius*(mybot.rt_spd_right - mybot.rt_spd_left))
mybot.move(t)                 # move for t seconds

#plotting block
mybot.plot_robot()            # plot robot's entire path
plt.xlim([0, 20])             # axis limits
plt.ylim([0, 20])
plt.rcParams["figure.figsize"] = (20,20) # forcing size as square
plt.show()
```

## Coding Optimization:
While we can see in the previous example how differential drive robots work on the most elementary level, we can also see the glaring inefficiency of this process.

For this example problem we will focus on two classic ways to increase the efficiency and decrease the number of lines of code required for the same operation:

1. for loop the action commands
2. define methods for specific actions

We will first focus on the for loop option:

### **Q3: For loop:** Instead of repeating the two blocks of code 6 times, write a for loop to transcribe a hexagon using the movement block:
If you need a refresher on for loops review Intro Notebook 3.

```python
#your code here:
```

### **object.method(argument)** Optimization:
Now that you have seen how a for loop can greatly reduce required lines of code for the same task, we will look at an even more powerful tool: **object.method(argument)**

As you saw in the definition of the Robot and DDRobot classes, and their use in nearly every cell since, use of **object.method(argument)** enables a user to set attributes and use methods attached to an object while not requiring their redefinition for each cell. While this is one great use of object instantiation, we are about to discover yet another powerful use for classes.

Look at the previous example: Repeated Code Block: Hexagon. The repetition in the movement block immediately jumps out:

These two blocks are perfect candidates for truncation into two separate methods:

"**turn_left()**", and "**forward()**". Of course a third method, "**turn_right()**" will also be defined as the opposite of "**turn_left()**".

Classes and more specifically methods are an excellent application for reusing specific commands with changing arguments and even objects. We will now walk you through defining our own class and methods.

**The objective of this class and it's methods are to** create callable **object.method(argument)** combinations that execute turns, and forward actions in one line of code. We will now create these methods as an addition to the DDRobot class:

This class will be called "Turn" and have three methods: **object.turn_right(a_R)** , **object.turn_left(a_L)** , and **object.forward(f_time)** .

This class and its corresponding methods can be seen in the screenshot below:

Take note how the input lines *a_R, a_L and f_time* for *turn_right, turn_left and forward* respectively have been commented out. This is done so input is not required each time the method is called i.e. in a for loop with n iterations. Therefore it is imperative to insert the following lines in the initialization block of your answer (before the method is called) to avoid causing errors (left turn angle variable shown):

As these variables in the previous screenshot are defined in a cell and attached to an object instance mybot of the class Turn, they are called local variables. This means they won't change during iterations in the cell but will change from cell to cell i.e. they are not global variables. This prevents overwriting if you were using the same commands with a different object i.e. otherbot.a_L . If you wished to have a variable saved from cell to cell it is easy enough to assign that variable to be global as shown in the following screenshot:

### In the cell below, the Turn class has been created for the three turning methods: **turn_right()**, **turn_left()** and **forward()**.
These have been defined in the Turn class at the bottom of the cell. Take note of these additions and run the cell:

```python
import matplotlib.pyplot as plt #enables plotting capabilities for the robot
                                #for this case this is the OUTPUT as the whole
                                #robot is simulated through this notebook
import numpy as np #Numerical Python library as described in the Intro Python Notebook
import math #math module
import scipy.constants as sc #shortcut for physical and mathematical constants
                             #and units
import sympy as sym #SymPy is a Python library for symbolic mathematics

from math import sin, cos

class Robot(object):
    """Defines basic mobile robot properties. Defines __init__, step, print_xya, and
    plot_robot methods. Is called in the main class of DDRobot."""
    def __init__(self):
        #initialization class.
        self.pos_x  = 0.0 #placing bot at origin: (x,y) = (0,0)
        self.pos_y  = 0.0
        self.angle  = 0.0 # IN RAD setting alpha = 0
        self.plot   = False #intializing no plot to show
        self._delta = 0.01 #
        self.step_plot = int(5) #plotting every 5 iterations
        self.mag_plot = 1.5 # arrow magnification

    # Movement
    def step(self):
        """ updates the x,y and alpha """
        self.deltax()
        self.deltay()
        self.deltaa()

    def move(self, seconds):
        """ Moves the robot for an 's' amount of seconds. Takes argument of seconds as type
        int"""
        for i in range(int(seconds/self._delta)):
            self.step()
            if i % self.step_plot == 0 and self.plot: # plot path every 5 steps
                self.plot_xya() #plots a dot in the position of the robot

    # Printing-and-plotting:
    def print_xya(self):
        """ prints the x,y position and angle """
        print ("x = " + str(self.pos_x) +" "+ "y = " + str(self.pos_y))
        print ("a = " + str(self.angle))

    def plot_robot(self):
        """ plots an arrow representation of the robot. """
        plt.arrow(self.pos_x, self.pos_y, 0.001
                  * cos(self.angle), 0.001 * sin(self.angle),
                  head_width=self.mag_plot*self.length, head_length=self.mag_plot*self.length,
                  fc='k', ec='k')

    def plot_xya(self):
        """ plots a dot in the position of the robot """
        plt.scatter(self.pos_x, self.pos_y, c='r', edgecolors='r')

class DDRobot(Robot):
    """Defines a differential drive robot. Helps move the robot.
    Class Robot is effectively created within class DDRobot as many of the
    methods from Robot class are called within DDRobot class."""

    def __init__(self):
        """__init__ : Initialization class (for DDRobot class)"""
        Robot.__init__(self)
        self.radius = 0.1 #radius of bot wheel as defined in Fig 3
        self.length = 0.4 #length between bot wheels as defined in Fig 3
        self.rt_spd_left = 0.0 #initializing rotation speed, left wheel to 0
        self.rt_spd_right = 0.0 #initializing rotation speed, right wheel to 0

    def deltax(self):
        """ update x position depending on L and R angular speeds """
        self.pos_x += self._delta * (self.radius*0.5) \
        * (self.rt_spd_right + self.rt_spd_left)*cos(self.angle)

    def deltay(self):
        """ update y position depending on l and r angular speeds """
        self.pos_y += self._delta * (self.radius*0.5) \
        * (self.rt_spd_right + self.rt_spd_left)*sin(self.angle)

    def deltaa(self):
        """ update angle depending on l and r angular speeds """
        self.angle += self._delta * (self.radius/self.length) \
        * (self.rt_spd_right - self.rt_spd_left)

        ### Turning Methods:

class Turn(DDRobot):
    """Defines methods that move robot with fewer lines of code by defining specific actions into methods.
    Calls DDRobot and its methods"""
    def __init__(self):
        """Initializes Turn class with DDRobot class object"""
        DDRobot.__init__(self)

    def turn_right(self,a_R):
        """Turns mybot a specified angle to the right. Args: R, desired angle of turn to Right """
            # takes input of degrees, converts to Radians
#         a_R = D2R(float(input("Enter the desired angle of rotation to the right (in degrees): ")))
        self.rt_spd_left = 6*math.pi # initializing left rotational speed at 4*pi
        self.rt_spd_right = 4*math.pi # initializing left rotational speed at 6*pi
        t = ((a_R - 0)*mybot.length)/(mybot.radius*(mybot.rt_spd_left - mybot.rt_spd_right))
        # Time of Turn eq:
        self.move(t) # move for t seconds

    def turn_left(self,a_L):
        """Turns mybot a specified angle to the left. Args: L, desired angle of turn Left """
            # takes input of degrees, converts to Radians
#         a_L = D2R(float(input("Enter the desired angle of rotation to the left (in degrees): ")))
        self.rt_spd_left = 4*math.pi # initializing left rotational speed at 4*pi
        self.rt_spd_right = 6*math.pi # initializing left rotational speed at 6*pi
        t = ((a_L - 0)*mybot.length)/(mybot.radius*(mybot.rt_spd_right - mybot.rt_spd_left))
        # Time of Turn eq:s
        self.move(t) # move for t seconds

    def forward(self,f_time):
        """Drives robot straight ahead for specified amount of time. Takes argument of f_time in seconds"""
#         f_time = int(input("Enter the desired time to move forward: "))
        self.rt_spd_left = 10
        self.rt_spd_right = 10
        self.move(f_time)

def D2R(a):
    """function to convert degrees to radians. Takes single argument of degrees."""
    return (math.pi*a)/180
def R2D(a):
    """Function to convert radians to degrees. Takes single argument of radians."""
    return 180*a/math.pi

```

### **Q4: Use turn and forward methods to complete a hexagon using a for loop:**
We have completed a for loop for a hexagon, and now defined methods for completing turns of user inputted angles and forward motion for user inputted time.

Synthesize the code required to **take user input for number of desired sides, side length, then complete a hexagon using a for loop and plot its course, using mybot as the object, and the forward(), turn_right() or turn_left() methods.** You are welcome to use the initialization and plotting code blocks from previous exercises.

```python
#your code here:
```

### **Q5: n Sided Polygon *for* loop:** Write a script using a *for* loop and the turning methods that transcribes a polygon with n number of sides:

```python
#your code here:
```

### **Q6: n Sided Polygon *while* loop:** Write a script using a *while* loop and the turning methods that transcribes a polygon with n number of sides, this time with **local variables**:
The body of the code can be reused from question 5 but **use local variales** if you haven't already. You must replace the for loop structure with a while loop and it's necessary commands.

```python
#your code here:
```

# Congratulations!
You have completed SimBot-1 Notebook! You now know how to write a class, methods and attributes for a Differential Drive Robot. You are now ready to move onto SimRobot-2 Notebook: Sensor Input and Output for the AlphaBot2!

```python

```


## Tsyganenko:

## This model 'reader' uses cloned sources of
## geopack (https://github.com/tsssss/geopack),
## geospacepy-lite (https://github.com/lkilcommons/geospacepy-lite),
## installed using pip install -e ./ in the geopack/ and geospacepy directories, respectively,
## on top of a python Kamodo environment before starting the jupyter notebook server.
## geospacepy-lite requires the CDF libraries from NASA and spacepy.pycdf to efficiently read OMNI data.

```python
%load_ext autoreload
%autoreload 2
```

```python
import numpy as np
```

```python
import os.path,datetime
```

```python
from geopack import geopack
```

    Load IGRF coefficients ...

```python
from kamodo import Kamodo,kamodofy,gridify
```

### Environmment variable to point to NASA SPDF CDF
(https://spdf.gsfc.nasa.gov/pub/software/cdf/dist/) installation on your machine

```python
os.environ["CDF_LIB"]='/Applications/cdf/cdf73_1-dist/lib/'
```

```python
from spacepy import pycdf
```

```python
import geospacepy
```

    Traceback (most recent call last):
      File "/Users/lrastaet/Desktop_Lutz/Projects/Kamodo/geospacepy-lite/geospacepy/__init__.py", line 8, in <module>
        from geospacepy.geospacepy_config import config
    ModuleNotFoundError: No module named 'geospacepy.geospacepy_config'

    Solar wind data files will be saved to /Users/lrastaet/Library/Application Support/geospacepy

```python
from tsyganenko import T96,T89,T01,T04
```

```python
t89_igrf=T89(2010,1,1,10,4,1)
```

    Created interval between 2010-01-01 and 2010-01-01, cadence hourly, start index 10, end index 11
    Applying transform Hourly Kp*10 -> Kp to omni hourly variable KP

```python
t89_igrf
```

\begin{equation}\operatorname{b_{x}}{\left(\vec{x} \right)} [nT] = \lambda{\left(\vec{x} \right)}\end{equation}\begin{equation}\operatorname{b_{x ijk}}{\left(x_{i},y_{j},z_{k} \right)} [nT] = \lambda{\left(x_{i},y_{j},z_{k} \right)}\end{equation}\begin{equation}\operatorname{b_{y}}{\left(\vec{x} \right)} [nT] = \lambda{\left(\vec{x} \right)}\end{equation}\begin{equation}\operatorname{b_{y ijk}}{\left(x_{i},y_{j},z_{k} \right)} [nT] = \lambda{\left(x_{i},y_{j},z_{k} \right)}\end{equation}\begin{equation}\operatorname{b_{z}}{\left(\vec{x} \right)} [nT] = \lambda{\left(\vec{x} \right)}\end{equation}\begin{equation}\operatorname{b_{z ijk}}{\left(x_{i},y_{j},z_{k} \right)} [nT] = \lambda{\left(x_{i},y_{j},z_{k} \right)}\end{equation}\begin{equation}\vec{b}{\left(\vec{x} \right)} [nT] = \lambda{\left(\vec{x} \right)}\end{equation}\begin{equation}\vec{b}_{ijk}{\left(x_{i},y_{j},z_{k} \right)} [nT] = \lambda{\left(x_{i},y_{j},z_{k} \right)}\end{equation}

```python
x=np.array([8.,9.,10.])
y=np.array([0.,1.,2.])
z=np.array([2.,3.,4.])
points=np.column_stack((x,y,z))
points
points[:,0]
```

    array([ 8.,  9., 10.])

```python
t89_igrf.b_x(points)
```

    array([[ 6.22189170e-01],
           [-1.18328788e+03],
           [-2.00080654e+02]])

```python
t89_igrf.detail()
```

      symbol
      units
      lhs
      rhs

      b_x(xvec)
      b_x(xvec)
      nT
      b_x
      None

      b_x_ijk(x_i, y_j, z_k)
      b_x_ijk(x_i, y_j, z_k)
      nT
      b_x_ijk
      None

      b_y(xvec)
      b_y(xvec)
      nT
      b_y
      None

      b_y_ijk(x_i, y_j, z_k)
      b_y_ijk(x_i, y_j, z_k)
      nT
      b_y_ijk
      None

      b_z(xvec)
      b_z(xvec)
      nT
      b_z
      None

      b_z_ijk(x_i, y_j, z_k)
      b_z_ijk(x_i, y_j, z_k)
      nT
      b_z_ijk
      None

      bvec(xvec)
      bvec(xvec)
      nT
      bvec
      None

      bvec_ijk(x_i, y_j, z_k)
      bvec_ijk(x_i, y_j, z_k)
      nT
      bvec_ijk
      None

```python
t89_igrf['B_x[T]']='b_x'
```

```python
t89_igrf.detail()
```

      symbol
      units
      lhs
      rhs

      b_x(xvec)
      b_x(xvec)
      nT
      b_x
      None

      b_x_ijk(x_i, y_j, z_k)
      b_x_ijk(x_i, y_j, z_k)
      nT
      b_x_ijk
      None

      b_y(xvec)
      b_y(xvec)
      nT
      b_y
      None

      b_y_ijk(x_i, y_j, z_k)
      b_y_ijk(x_i, y_j, z_k)
      nT
      b_y_ijk
      None

      b_z(xvec)
      b_z(xvec)
      nT
      b_z
      None

      b_z_ijk(x_i, y_j, z_k)
      b_z_ijk(x_i, y_j, z_k)
      nT
      b_z_ijk
      None

      bvec(xvec)
      bvec(xvec)
      nT
      bvec
      None

      bvec_ijk(x_i, y_j, z_k)
      bvec_ijk(x_i, y_j, z_k)
      nT
      bvec_ijk
      None

      B_x(xvec)
      B_x(xvec)
      T
      B_x
      1.0e-9*b_x(xvec)

```python
t89_igrf['B_x'](points)
```

    array([[ 6.22189170e-10],
           [-1.18328788e-06],
           [-2.00080654e-07]])

```python
t89_igrf['b_x'](points)
```

    array([[ 6.22189170e-01],
           [-1.18328788e+03],
           [-2.00080654e+02]])

```python
t89_igrf['bvec']((9.,0.,0.))
```

    array([[26.76851212, -0.11158617, 56.98372572]])

```python
t96_igrf=T96(2010,1,1,10,4,1)
```

    Created interval between 2010-01-01 and 2010-01-01, cadence 1min, start index 604, end index 605

```python
t96_igrf.b((xx,yy,zz))
```

```python
t01_igrf=T01(2010,1,1,10,4,1)
```

```python
t01_igrf.b((xx,yy,zz))
```

```python
t04_igrf=T04(2010,1,1,10,4,1)
```

```python
t04_igrf
```

```python

```


# Optimización media-varianza

La **teoría de portafolios** es una de los avances más importantes en las finanzas modernas e inversiones.
- Apareció por primera vez en un [artículo corto](https://www.math.ust.hk/~maykwok/courses/ma362/07F/markowitz_JF.pdf) llamado "Portfolio Selection" en la edición de Marzo de 1952 de "the Journal of Finance".
- Escrito por un desconocido estudiante de la Universidad de Chicago, llamado Harry Markowitz.
- Escrito corto (sólo 14 páginas), poco texto, fácil de entender, muchas gráficas y unas cuantas referencias.
- No se le prestó mucha atención hasta los 60s.

Finalmente, este trabajo se convirtió en una de las más grandes ideas en finanzas, y le dió a Markowitz el Premio Noble casi 40 años después.
- Markowitz estaba incidentalmente interesado en los mercados de acciones e inversiones.
- Estaba más bien interesado en entender cómo las personas tomaban sus mejores decisiones cuando se enfrentaban con "trade-offs".
- Principio de conservación de la miseria. O, dirían los instructores de gimnasio: "no pain, no gain".
- Si queremos más de algo, tenemos que perder en algún otro lado.
- El estudio de este fenómeno era el que le atraía a Markowitz.

De manera que nadie se hace rico poniendo todo su dinero en la cuenta de ahorros. La única manera de esperar altos rendimientos es si se toma bastante riesgo. Sin embargo, riesgo significa también la posibilidad de perder, tanto como ganar.

Pero, ¿qué tanto riesgo es necesario?, y ¿hay alguna manera de minimizar el riesgo mientras se maximizan las ganancias?
- Markowitz básicamente cambió la manera en que los inversionistas pensamos acerca de esas preguntas.
- Alteró completamente la práctica de la administración de inversiones.
- Incluso el título de su artículo era innovador. Portafolio: una colección de activos en lugar de tener activos individuales.
- En ese tiempo, un portafolio se refería a una carpeta de cuero.
- En el resto de este módulo, no ocuparemos de la parte analítica de la teoría de portafolios, la cual puede ser resumida en dos frases:
 - No pain, no gain.
 - No ponga todo el blanquillo en una sola bolsa.

**Objetivos:**
- ¿Qué es la línea de asignación de capital?
- ¿Qué es el radio de Sharpe?
- ¿Cómo deberíamos asignar nuestro capital entre un activo riesgoso y un activo libre de riesgo?

*Referencia:*
- Notas del curso "Portfolio Selection and Risk Management", Rice University, disponible en Coursera.
___

## 1. Línea de asignación de capital

### 1.1. Motivación

El proceso de construcción de un portafolio tiene entonces los siguientes dos pasos:
1. Escoger un portafolio de activos riesgosos.
2. Decidir qué tanto de tu riqueza invertirás en el portafolio y qué tanto invertirás en activos libres de riesgo.

Al paso 2 lo llamamos **decisión de asignación de activos**.

Preguntas importantes:
1. ¿Qué es el portafolio óptimo de activos riesgosos?
 - ¿Cuál es el mejor portafolio de activos riesgosos?
 - Es un portafolio eficiente en media-varianza.
2. ¿Qué es la distribución óptima de activos?
 - ¿Cómo deberíamos distribuir nuestra riqueza entre el portafolo riesgoso óptimo y el activo libre de riesgo?
 - Concepto de **línea de asignación de capital**.
 - Concepto de **radio de Sharpe**.

Dos suposiciones importantes:
- Funciones de utilidad media-varianza.
- Inversionista averso al riesgo.

La idea sorprendente que saldrá de este análisis, es que cualquiera que sea la actitud del inversionista de cara al riesgo, el mejor portafolio de activos riesgosos es idéntico para todos los inversionistas.

Lo que nos importará a cada uno de nosotros en particular, es simplemente la desición óptima de asignación de activos.
___

### 1.2. Línea de asignación de capital

Sean:
- $r_s$ el rendimiento del activo riesgoso,
- $r_f$ el rendimiento libre de riesgo, y
- $w$ la fracción invertida en el activo riesgoso.

 Realizar deducción de la línea de asignación de capital en el tablero.

**Tres doritos después...**

#### Línea de asignación de capital (LAC):
$E[r_p]$ se relaciona con $\sigma_p$ de manera afín. Es decir, mediante la ecuación de una recta:

$$E[r_p]=r_f+\frac{E[r_s-r_f]}{\sigma_s}\sigma_p.$$

- La pendiente de la LAC es el radio de Sharpe $\frac{E[r_s-r_f]}{\sigma_s}=\frac{E[r_s]-r_f}{\sigma_s}$,
- el cual nos dice qué tanto rendimiento obtenemos por unidad de riesgo asumido en la tenencia del activo (portafolio) riesgoso.

Ahora, la pregunta es, ¿dónde sobre esta línea queremos estar?
___

### 1.3. Resolviendo para la asignación óptima de capital

Recapitulando de la clase pasada, tenemos las curvas de indiferencia: **queremos estar en la curva de indiferencia más alta posible, que sea tangente a la LAC**.

 Ver en el tablero.

Analíticamente, el problema es

$$\max_{w} \quad E[U(r_p)]\equiv\max_{w} \quad E[r_p]-\frac{1}{2}\gamma\sigma_p^2,$$

donde los puntos $(\sigma_p,E[r_p])$ se restringen a estar en la LAC, esto es $E[r_p]=r_f+\frac{E[r_s-r_f]}{\sigma_s}\sigma_p$ y $\sigma_p=w\sigma_s$. Entonces el problema anterior se puede escribir de la siguiente manera:

$$\max_{w} \quad r_f+wE[r_s-r_f]-\frac{1}{2}\gamma w^2\sigma_s^2.$$

 Encontrar la $w$ que maximiza la anterior expresión en el tablero.

**Tres doritos después...**

La solución es entonces:

$$w^\ast=\frac{E[r_s-r_f]}{\gamma\sigma_s^2}.$$

De manera intuitiva:
- $w^\ast\propto E[r_s-r_f]$: a más exceso de rendimiento que se obtenga del activo riesgoso, más querremos invertir en él.
- $w^\ast\propto \frac{1}{\gamma}$: mientras más averso al riesgo seas, menos querrás invertir en el activo riesgoso.
- $w^\ast\propto \frac{1}{\sigma_s^2}$: mientras más riesgoso sea el activo, menos querrás invertir en él.
___

## 2. Ejemplo de asignación óptima de capital: acciones y billetes de EU

Pongamos algunos números con algunos datos, para ilustrar la derivación que acabamos de hacer.

En este caso, consideraremos:
- **Portafolio riesgoso**: mercado de acciones de EU (representados en algún índice de mercado como el S&P500).
- **Activo libre de riesgo**: billetes del departamento de tesorería de EU (T-bills).

Tenemos los siguientes datos:

$$E[r_{US}]=11.9\%,\quad \sigma_{US}=19.15\%, \quad r_f=1\%.$$

Recordamos que podemos escribir la expresión de la LAC como:

\begin{align}
E[r_p]&=r_f+\left[\frac{E[r_{US}-r_f]}{\sigma_{US}}\right]\sigma_p\\
      &=0.01+\text{S.R.}\sigma_p,
\end{align}

donde $\text{S.R}=\frac{0.119-0.01}{0.1915}\approx0.569$ es el radio de Sharpe (¿qué es lo que es esto?). la pendiente

Grafiquemos la LAC con estos datos reales:

```python
# Importamos librerías que vamos a utilizar
import numpy as np
import matplotlib.pyplot as plt
```

```python
# Datos
erus,sus,rf=.119,.1915,.01
# Radio de Sharpe para este activo
sr=(erus-rf)/sus
# Vector de volatilidades del portafolio
sp=np.linspace(0,.5,100)
# LAC
erp=rf+sr*sp
```

```python
# Gráfica
plt.figure(figsize=(7,4))
plt.plot(sp,erp,lw='3',label='LAC')
plt.plot(0,rf,'o',ms=10,label='libre de riesgo')
plt.plot(sus,erus,'o',ms=10,label='portafolios riesgoso')
plt.axhline(y=erus,color='gray')
plt.axvline(x=sus,color='gray')
plt.axhline(y=0,color='k')
plt.axvline(x=0,color='k')
plt.grid()
plt.xlabel('Volatility')
plt.ylabel('Expected return')
plt.legend(loc='best')
plt.show()
```

Bueno, y ¿en qué punto de esta línea querríamos estar?
- Pues ya vimos que depende de tus preferencias.
- En particular, de tu actitud de cara al riesgo, medido por tu coeficiente de aversión al riesgo.

Solución al problema de asignación óptima de capital:

$$\max_{w} \quad E[U(r_p)]$$

$$w^\ast=\frac{E[r_s-r_f]}{\gamma\sigma_s^2}$$

Dado que ya tenemos datos, podemos intentar para varios coeficientes de aversión al riesgo:

```python
# importar pandas
import pandas as pd
```

```python
# Crear un DataFrame con los pesos, rendimiento
# esperado y volatilidad del portafolio óptimo
# entre los activos riesgoso y libre de riesgo
# cuyo índice sean los coeficientes de aversión
# al riesgo del 1 al 10 (enteros)
g=np.arange(1,11)
wopt=(erus-rf)/(g*sus**2)
sp=wopt*sus
erp=rf+(erus-rf)/sus*sp
data=pd.DataFrame(index=g,columns=['$w_{opt}$','$E[r_p]$','$\sigma_p$'])
data['$w_{opt}$']=wopt
data['$E[r_p]$']=erp
data['$sigma_p$']=sp
data
```

      $w_{opt}$
      $E[r_p]$
      $\sigma_p$
      $sigma_p$

      1
      2.972275
      0.333978
      NaN
      0.569191

      2
      1.486137
      0.171989
      NaN
      0.284595

      3
      0.990758
      0.117993
      NaN
      0.189730

      4
      0.743069
      0.090994
      NaN
      0.142298

      5
      0.594455
      0.074796
      NaN
      0.113838

      6
      0.495379
      0.063996
      NaN
      0.094865

      7
      0.424611
      0.056283
      NaN
      0.081313

      8
      0.371534
      0.050497
      NaN
      0.071149

      9
      0.330253
      0.045998
      NaN
      0.063243

      10
      0.297227
      0.042398
      NaN
      0.056919

¿Cómo se interpreta $w^\ast>1$?
- Cuando $0<w^\ast<1$, entonces $0<1-w^\ast<1$. Lo cual implica posiciones largas en el mercado de activos y en el activo libre de riesgo.
- Por el contrario, cuando $w^\ast>1$, tenemos $1-w^\ast<0$. Lo anterior implica una posición corta en el activo libre de riesgo (suponiendo que se puede) y una posición larga (de más del 100%) en el mercado de activos: apalancamiento.

# Anuncios parroquiales.

## 1. Quiz la siguiente clase.
## 2. [Calificaciones](https://docs.google.com/spreadsheets/d/18-SDXpkuN6LULO16_1VPHPksrP-QCEpj7OLxiaSpQ3U/edit?usp=sharing)

Created with Jupyter by Esteban Jiménez Rodríguez.