# Canonical Model

While related to the normal form model, this one fully exapands the higher order terms, thus showing interesting behaviors not present in the Hopf normal form model (see [E.W. Large, F.V. Almonte and M.J. Velasco *A canonical model for gradient frequency neural networks*, Physica D 239 (2010) 905-911](http://www.sciencedirect.com/science/article/pii/S0167278910000187)):

$$
\dot{z} = z\left(\alpha+j\omega+(\beta_1 +j \delta_1)|z|^2 + \frac{(\beta_2 +j \delta_2)\varepsilon |z|^4}{1-\varepsilon|z|^2}\right) + \frac{x}{1-\sqrt{\varepsilon}x}\cdot\frac{1}{1-\sqrt{\varepsilon}\bar{z}}
$$

with $x$ being a complex-valued input (could be external or connections to other oscilators in a network of oscilators).

$\mathcal{P}(\varepsilon, x) = \frac{x}{1-\sqrt{\varepsilon}x}$ is a **passive non-linearity**, and $\mathcal{A(\varepsilon, \bar{z})} = \frac{1}{1-\sqrt{\varepsilon}\bar{z}}$ is an **active non-linearity**. We can express it as follows:

$$
\dot{z} = z\left(\alpha+j\omega+(\beta_1 +j \delta_1)|z|^2 + \frac{(\beta_2 +j \delta_2)\varepsilon |z|^4}{1-\varepsilon|z|^2}\right) + \mathcal{cP}(\varepsilon,x)\mathcal{A}(\varepsilon,\bar{z})
$$

## Polar form

Lets express the external input $x$ and the oscillator state $z$ in polar form:

$$
x=Fe^{j\theta}\\
\bar{z} = re^{-j\phi}
$$

Then,

$$
\begin{align}
\dot{r} &= r\left(\alpha + \beta_1 r^2 + \frac{\beta_2\varepsilon r^4}{1+\varepsilon r^2}\right) + \frac{F(rF\varepsilon+\cos(\theta-\phi)-F\sqrt{\varepsilon}\cos\phi-r\sqrt{\varepsilon}\cos\theta)}{(1-2F\sqrt{\varepsilon}\cos\theta+F^2\varepsilon)(1-2r\sqrt{\varepsilon}\sin\phi+r^2\varepsilon)}\\
\dot{\phi} &= \omega + \delta_1 r^2 + \frac{\delta_2\varepsilon r^4}{1+\varepsilon r^2} + \frac{F(\sin(\theta-\phi)+F\sqrt{\varepsilon}\sin\phi-r\sqrt{\varepsilon}\sin\theta)}{r(1-2F\sqrt{\varepsilon}\cos\theta+F^2\varepsilon)(1-2r\sqrt{\varepsilon}\sin\phi+r^2\varepsilon)}\\
\end{align}
$$

Is important to note that $x$ and $z$ must satisfy the following conditions:

$$
\begin{align}
|x| &< \sqrt{1/\varepsilon} \\
|z| &< \sqrt{1/\varepsilon} \\
\end{align}
$$

<!--The folowing code assumes a real input signal $s(t)$ we get $F = s(t)$ and $\theta = 0$, with $s \in \mathbb{R}$.-->

### No external input

Assuming $\mathcal{P}(\varepsilon, x)\mathcal{A}(\varepsilon, \bar{z} = 0$), we can rewrite the system as:

$$
\begin{align}
\dot{r} &= r\left(\alpha + \beta_1 r^2 + \frac{\beta_2\varepsilon r^4}{1+\varepsilon r^2}\right)\\
\dot{\phi} &= \omega + \delta_1 r^2 + \frac{\delta_2\varepsilon r^4}{1+\varepsilon r^2} \\
\end{align}
$$

```
%matplotlib inline

import numpy as np
import matplotlib.pyplot as plt

from pygrfnn import Zparam
from pygrfnn.oscillator import zdot

def rdot(r, z, force):
    """
    Compute the derivate of an oscillator's amplitude w.r.t. time, as a function
    of the oscillator's amplitude

    Args:
        r (`array_like`): oscillator's amplitude's to analyze
        z (:class:`Zparam`): oscillator parameters
        force (`float`): external force
    """
    return z.alpha*r + z.beta1*r**3 + z.beta2*z.epsilon*r**5./(1-z.epsilon*r**2) + \
        force

z_params = Zparam(0.3, 1.0, -1.0, 0, 0, 1.0)  # oscillator params
x = 0  # external force
r = np.arange(0, 1.0, 0.001)

drdt = rdot(r, z_params, x)
plt.figure(figsize=(8,8))
plt.plot(drdt, r)
plt.xlim([-1, 1])
plt.grid(True)
plt.show()
```

```

```


# Mackey and Glass

We study algorithms for solving constant delay differential equations with a test problem from W.H. Enright and H. Hayashi, "The evaluation of numerical software for delay differential equations", 1997. It is a model of blood production that was published by M. C. Mackey and L. Glass in "Oscillation and chaos in physiological control systems", 1977, and is given by
```math
\begin{equation}
 y'(t) = \frac{0.2y(t-14)}{1 + y(t-14)^{10}} - 0.1y(t)
\end{equation}
```

```julia
using DelayDiffEq, DiffEqDevTools, DiffEqProblemLibrary, Plots
using DiffEqProblemLibrary.DDEProblemLibrary: importddeproblems; importddeproblems()
import DiffEqProblemLibrary.DDEProblemLibrary: prob_dde_mackey
gr()

sol = solve(prob_dde_mackey, MethodOfSteps(Vern9(); fpsolve = NLFunctional(; max_iter = 1000)); reltol=1e-14, abstol=1e-14)
test_sol = TestSolution(sol)
plot(sol)
```

## Low order RK methods

### High tolerances

First we test final error estimates of continuous RK methods of low order at high tolerances. `OwrenZen4`, `OwrenZen5`, and `RK4` yield the best error estimates.

```julia
abstols = 1.0 ./ 10.0 .^ (4:7)
reltols = 1.0 ./ 10.0 .^ (1:4)

setups = [Dict(:alg=>MethodOfSteps(BS3())),
          Dict(:alg=>MethodOfSteps(Tsit5())),
          Dict(:alg=>MethodOfSteps(RK4())),
          Dict(:alg=>MethodOfSteps(DP5())),
          Dict(:alg=>MethodOfSteps(OwrenZen3())),
          Dict(:alg=>MethodOfSteps(OwrenZen4())),
          Dict(:alg=>MethodOfSteps(OwrenZen5()))]
names = ["BS3", "Tsit5", "RK4", "DP5", "OwrenZen3", "OwrenZen4", "OwrenZen5"]
wp = WorkPrecisionSet(prob_dde_mackey,abstols,reltols,setups;names=names,
                      appxsol=test_sol,maxiters=Int(1e5),error_estimate=:final)
plot(wp)
```

Next we test average interpolation errors:

```julia
abstols = 1.0 ./ 10.0 .^ (4:7)
reltols = 1.0 ./ 10.0 .^ (1:4)

setups = [Dict(:alg=>MethodOfSteps(BS3())),
          Dict(:alg=>MethodOfSteps(Tsit5())),
          Dict(:alg=>MethodOfSteps(RK4())),
          Dict(:alg=>MethodOfSteps(DP5())),
          Dict(:alg=>MethodOfSteps(OwrenZen3())),
          Dict(:alg=>MethodOfSteps(OwrenZen4())),
          Dict(:alg=>MethodOfSteps(OwrenZen5()))]
names = ["BS3", "Tsit5", "RK4", "DP5", "OwrenZen3", "OwrenZen4", "OwrenZen5"]
wp = WorkPrecisionSet(prob_dde_mackey,abstols,reltols,setups;names=names,
                      appxsol=test_sol,maxiters=Int(1e5),error_estimate=:L2)
plot(wp)
```

As before, `OwrenZen4` and `OwrenZen5` perform well over the whole range of investigated tolerances.

### Low tolerances

We repeat our tests with low tolerances.

```julia
abstols = 1.0 ./ 10.0 .^ (8:11)
reltols = 1.0 ./ 10.0 .^ (5:8)

setups = [Dict(:alg=>MethodOfSteps(BS3())),
          Dict(:alg=>MethodOfSteps(Tsit5())),
          Dict(:alg=>MethodOfSteps(RK4())),
          Dict(:alg=>MethodOfSteps(DP5())),
          Dict(:alg=>MethodOfSteps(OwrenZen3())),
          Dict(:alg=>MethodOfSteps(OwrenZen4())),
          Dict(:alg=>MethodOfSteps(OwrenZen5()))]
names = ["BS3", "Tsit5", "RK4", "DP5", "OwrenZen3", "OwrenZen4", "OwrenZen5"]
wp = WorkPrecisionSet(prob_dde_mackey,abstols,reltols,setups;names=names,
                      appxsol=test_sol,maxiters=Int(1e5),error_estimate=:final)
plot(wp)
```

And once again we also test the interpolation errors:

```julia
abstols = 1.0 ./ 10.0 .^ (8:11)
reltols = 1.0 ./ 10.0 .^ (5:8)

setups = [Dict(:alg=>MethodOfSteps(BS3())),
          Dict(:alg=>MethodOfSteps(Tsit5())),
          Dict(:alg=>MethodOfSteps(RK4())),
          Dict(:alg=>MethodOfSteps(DP5())),
          Dict(:alg=>MethodOfSteps(OwrenZen3())),
          Dict(:alg=>MethodOfSteps(OwrenZen4())),
          Dict(:alg=>MethodOfSteps(OwrenZen5()))]
names = ["BS3", "Tsit5", "RK4", "DP5", "OwrenZen3", "OwrenZen4", "OwrenZen5"]
wp = WorkPrecisionSet(prob_dde_mackey,abstols,reltols,setups;names=names,
                      appxsol=test_sol,maxiters=Int(1e5),error_estimate=:L2)
plot(wp)
```

Apparently `Tsit5` and `DP5` perform quite well at low tolerances, but only `OwrenZen5`, `OwrenZen4` and `RK4` achieve interpolation errors of around 1e-9.

## Lazy interpolants

### High tolerances

We repeat our tests with the Verner methods which, in contrast to the methods above, use lazy interpolants. As reference we include `OwrenZen4`.

```julia
abstols = 1.0 ./ 10.0 .^ (4:7)
reltols = 1.0 ./ 10.0 .^ (1:4)

setups = [Dict(:alg=>MethodOfSteps(Vern6())),
          Dict(:alg=>MethodOfSteps(Vern7())),
          Dict(:alg=>MethodOfSteps(Vern8())),
          Dict(:alg=>MethodOfSteps(Vern9())),
          Dict(:alg=>MethodOfSteps(OwrenZen4()))]
names = ["Vern6", "Vern7", "Vern8", "Vern9", "OwrenZen4"]
wp = WorkPrecisionSet(prob_dde_mackey,abstols,reltols,setups;names=names,
                      appxsol=test_sol,maxiters=Int(1e5),error_estimate=:final)
plot(wp)
```

And we obtain the following interpolation errors:

```julia
abstols = 1.0 ./ 10.0 .^ (4:7)
reltols = 1.0 ./ 10.0 .^ (1:4)

setups = [Dict(:alg=>MethodOfSteps(Vern6())),
          Dict(:alg=>MethodOfSteps(Vern7())),
          Dict(:alg=>MethodOfSteps(Vern8())),
          Dict(:alg=>MethodOfSteps(Vern9())),
          Dict(:alg=>MethodOfSteps(OwrenZen4()))]
names = ["Vern6", "Vern7", "Vern8", "Vern9", "OwrenZen4"]
wp = WorkPrecisionSet(prob_dde_mackey,abstols,reltols,setups;names=names,
                      appxsol=test_sol,maxiters=Int(1e5),error_estimate=:L2)
plot(wp)
```

`Vern6`, `Vern7`, and `Vern9` are outperformed by `OwrenZen4`.

### Low tolerances

Again, we repeat our tests at low tolerances.

```julia
abstols = 1.0 ./ 10.0 .^ (8:11)
reltols = 1.0 ./ 10.0 .^ (5:8)

setups = [Dict(:alg=>MethodOfSteps(Vern6())),
          Dict(:alg=>MethodOfSteps(Vern7())),
          Dict(:alg=>MethodOfSteps(Vern8())),
          Dict(:alg=>MethodOfSteps(Vern9())),
          Dict(:alg=>MethodOfSteps(OwrenZen4()))]
names = ["Vern6", "Vern7", "Vern8", "Vern9", "OwrenZen4"]
wp = WorkPrecisionSet(prob_dde_mackey,abstols,reltols,setups;names=names,
                      appxsol=test_sol,maxiters=Int(1e5),error_estimate=:final)
plot(wp)
```

```julia
abstols = 1.0 ./ 10.0 .^ (8:11)
reltols = 1.0 ./ 10.0 .^ (5:8)

setups = [Dict(:alg=>MethodOfSteps(Vern6())),
          Dict(:alg=>MethodOfSteps(Vern7())),
          Dict(:alg=>MethodOfSteps(Vern8())),
          Dict(:alg=>MethodOfSteps(Vern9())),
          Dict(:alg=>MethodOfSteps(OwrenZen4()))]
names = ["Vern6", "Vern7", "Vern8", "Vern9", "OwrenZen4"]
wp = WorkPrecisionSet(prob_dde_mackey,abstols,reltols,setups;names=names,
                      appxsol=test_sol,maxiters=Int(1e5),error_estimate=:L2)
plot(wp)
```

`Vern6`, `Vern7`, and `Vern9` show similar results at low tolerances, and perform even better than `OwrenZen4`.

```julia
using DiffEqBenchmarks
DiffEqBenchmarks.bench_footer(WEAVE_ARGS[:folder],WEAVE_ARGS[:file])
```


# Transport equation with source term

$$
\renewcommand{\DdQq}[2]{{\mathrm D}_{#1}{\mathrm Q}_{#2}}
\renewcommand{\drondt}{\partial_t}
\renewcommand{\drondx}{\partial_x}
\renewcommand{\dx}{\Delta x}
\renewcommand{\dt}{\Delta t}
\renewcommand{\grandO}{{\mathcal O}}
\renewcommand{\density}[2]{\,f_{#1}^{#2}}
\renewcommand{\fk}[1]{\density{#1}{\vphantom{\star}}}
\renewcommand{\fks}[1]{\density{#1}{\star}}
\renewcommand{\moment}[2]{\,m_{#1}^{#2}}
\renewcommand{\mk}[1]{\moment{#1}{\vphantom{\star}}}
\renewcommand{\mke}[1]{\moment{#1}{e}}
\renewcommand{\mks}[1]{\moment{#1}{\star}}
$$

In this tutorial, we propose to add a source term in the advection equation. The problem reads
$$\drondt u + c \drondx u = S(t, x, u), \quad t>0, , \quad x\in(0, 1),$$

where $c$ is a constant scalar (typically $c=1$).
Additional boundary and initial conditions will be given in the following.
$S$ is the source term that can depend on the time $t$, the space $x$ and the solution $u$.

In order to simulate this problem, we use the $\DdQq{1}{2}$ scheme and we add an additional `key:value` in the dictionary for the source term. We deal with two examples.

## A friction term

In this example, we takes $S(t, x, u) = -\alpha u$ where $\alpha$ is a positive constant.
The dictionary of the simulation then reads:

```python
%matplotlib inline
import sympy as sp
import numpy as np
import pylbm
import math
```

```python
C, ALPHA, X, u, LA = sp.symbols('C, ALPHA, X, u, LA')
c = 0.3
alpha = 0.5

def init(x):
    middle, width, height = 0.4, 0.1, 0.5
    out = np.zeros_like(x)
    mask = (np.abs(x%1-middle)<=width)
    out[mask] = height/width**10 * (x[mask]%1-middle-width)**5 * \
                                   (middle-x[mask]%1-width)**5
    return out

def solution(t, x):
    return init(x - c*t)*math.exp(-alpha*t)

dico = {
    'box': {'x': [0., 1.], 'label': -1},
    'space_step': 1./128,
    'scheme_velocity': LA,
    'schemes': [
        {
            'velocities': [1,2],
            'conserved_moments': u,
            'polynomials': [1, LA*X],
            'relaxation_parameters': [0., 2.],
            'equilibrium': [u, C*u],
            'source_terms': {u: -ALPHA*u},
        },
    ],
    'init': {u: init},
    'parameters': {
        LA: 1.,
        C: c,
        ALPHA: alpha
    },
    'generator': 'numpy',
}

sol = pylbm.Simulation(dico) # build the simulation
viewer = pylbm.viewer.matplotlib_viewer
fig = viewer.Fig()
ax = fig[0]
ax.axis(0., 1., -.1, .6)
x = sol.domain.x
ax.plot(x, sol.m[u], width=2, color='k', label='initial')
while sol.t < 1:
    sol.one_time_step()
ax.plot(x, sol.m[u], width=2, color='b', label=r'$D_1Q_2$')
ax.plot(x, solution(sol.t, x), width=2, color='r', label='exact')
ax.legend()
```

## A source term depending on time and space

If the source term $S$ depends explicitely on the time or on the space, we have to specify the corresponding variables in the dictionary through the key *parameters*. The time variable is prescribed by the key *'time'*. Moreover, sympy functions can be used to define the source term like in the following example. This example is just for testing the feature... no physical meaning in mind !

```python
t, C, X, u, LA = sp.symbols('t, C, X, u, LA')
c = 0.3

def init(x):
    middle, width, height = 0.4, 0.1, 0.5
    out = np.zeros_like(x)
    mask = (np.abs(x%1-middle)<=width)
    out[mask] = height/width**10 * (x[mask]%1-middle-width)**5 * \
                                   (middle-x[mask]%1-width)**5
    return out

dico = {
    'box': {'x': [0., 1.], 'label': -1},
    'space_step': 1./128,
    'scheme_velocity': LA,
    'schemes': [
        {
            'velocities': [1, 2],
            'conserved_moments': u,
            'polynomials': [1, LA*X],
            'relaxation_parameters': [0., 2.],
            'equilibrium': [u, C*u],
            'source_terms': {u: -sp.Abs(X-t)**2*u},
        },
    ],
    'init': {u: init},
    'generator': 'cython',
    'parameters': {LA: 1., C: c},
}

sol = pylbm.Simulation(dico) # build the simulation
viewer = pylbm.viewer.matplotlib_viewer
fig = viewer.Fig()
ax = fig[0]
ax.axis(0., 1., -.1, .6)
x = sol.domain.x
ax.plot(x, sol.m[u], width=2, color='k', label='initial')
while sol.t < 1:
    sol.one_time_step()
ax.plot(x, sol.m[u], width=2, color='b', label=r'$D_1Q_2$')
ax.legend()
```

```python

```


# Resumo, Teoria e Prática - Equações Diferenciais
> Autores: Rafael, Gil, Matheus, Karina, Felipe

> Fontes bibliográficas:
* Rosa, R. (2017). Equações Diferenciais
* Trefethen, L. & Bau, D. (1997) Numerical Linear Algebra
* Keith R. Symon (1988) Mecânica

---
## O que é uma EDO

> > > > > Equações Diferenciais estão presentes em diversos modelos em física, química, biologia, economia, engenharia, etc. Vários fenômenos envolvem a variação de uma quantidade em relaçao a outra, levando naturalmente a modelos baseados em equações diferenciais. Podemos ter variações temporais de, por exemplo, a posição de um objeto, a temperatura de um material, a concentração de um agente químico, a concentração de um poluente ou nutriente em um meio, a umidade do ar, o número de habitantes de uma cidade, a densidade de bactérias de uma cultura, a densidade de massa de um gás, o valor de uma mercadoria, o câmbio entre moedas, o produto interno bruto de um país, etc. Além de variações temporais dessas quantidades, podemos ter variações em relação a outras quantidades, como variação de temperatura em relação à posição e variação de densidade de massa de um fluido em relação à temperatura, por exemplo.

> > > > > As equações diferenciais são expressões matemáticas de certas leis envolvidas em uma modelagem, que podem, por exemplo, ser leis fundamentais, como a segunda lei de Newton, empíricas, como em reações químicas, ou heurísticas, como em dinâmica populacional.

Uma equacão diferencial  é uma equação cuja incógnita é uma função e cuja equação envolve derivadas dessa função procurada. Mais especificamente, consideramos uma equação da forma
$$
F\left(t,x,\frac{\mathrm{d}x}{\mathrm{d}t}, \dots, \frac{\mathrm{d}^nx}{\mathrm{d}t^n} \right) = 0
$$
onde $t$ é uma variável independente, $F = F (t, x, x_1,\dots, x_n) $ é uma função $F: \mathbb{R}^{n+2} \to \mathbb{R}$ e $x = x(t)$ é uma variável dependente, que é a função procurada (incógnita). Esta é uma equação de ordem $n$, indicando a derivada de ordem mais alta presente na equação.

REFERÊNCIA: Ricardo Rosa  . **Equações Diferenciais **, 2017.

http://www.labma.ufrj.br/~rrosa/dvifiles/apostila-ed-maio2017.pdf

Cédric Villani, Medalha Fields, falando sobre motivação e utilidade das equações diferenciais (em inglês com legendas)
https://www.youtube.com/watch?v=o9zQpQjfQ80

### Uma descrição mais 'ingênua'
Equações diferenciais são equações que modelam vários fenomenos do mundo em que vivemos, essas equações estão ligadas a maneira que esses fenomenos mudam. Quando dizemos que queremos resolver uma equação diferencial, é por que queremos descobrir como esse fenomeno ocorre, ou como estará no futuro mas sabemos apenas como ele muda, seja como ele muda a cada minuto como por exemplo a chuva que vai ficando mais forte ou mais fraca, ou se muda a cada lugar diferente que está sendo observado, por exemplo medir a temperatura próximo do ar condicionado numa sala ou longe do ar na mesma sala.

```python
# Bibliotecas do Python para auxiliar nos metódos númericos
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
import sympy
from sympy import Function, dsolve, Eq, Derivative, symbols, init_printing, plot, Matrix, exp, solve, linsolve

def custom_latex_printer(exp,**options):
    from google.colab.output._publish import javascript
    url = "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=default"
    javascript(url=url)
    return sympy.printing.latex(exp,**options)
init_printing(use_latex="mathjax",latex_printer=custom_latex_printer)
```

---
## Alguns modelos de EDOs:

### Taxa de Decaimento:
Vamos primeiro olhar para um EDO bem simples, que modela decaimento radioativo com uma massa inicial $y_0$ e coeficiente de decaimento $\lambda$ que depende do elemento observado.
$$\frac{\mathrm{d}x}{\mathrm{d}t}=-\lambda x$$

Solução númerica com $y_0 = 50, \lambda = 0.3$

```python
def model1(y, t, k):
  # modelo para decaimento radioativo
  return -k*y

ts = np.linspace(0,20)
ys = odeint(model1,50,ts,args=(0.3,))
plt.plot(ts,ys,label=0.3)
plt.legend(title='$\lambda$')
plt.ylabel=('massa')
plt.xlabel=('tempo')
plt.show()
```

Aqui podemos ver o 'poder' de modelagem de uma EDO, o gráfico nos diz que: Um elemento com massa 50 levará 20 unidades de tempo para chegar a uma massa 0.

Agora vamos observar que alterando o coeficiente $\lambda$, obtemos uma nova solução, para isso segue um plot com $\lambda$ variando de 0.1 a 0.5

para $\lambda \in R$ uma constante definida pelo elemento observado

Então utilizando este modelo para uma massa inicial de 50kg, variando os valores de $\lambda$

```python
lambdas = np.linspace(0.1,0.5,num=5)
ts = np.linspace(0,20)
for l in lambdas:
  ys = odeint(model1,50,ts,(l,))
  plt.plot(ts,ys,label=str(l))
plt.legend(title='$\lambda$')
plt.ylabel=('massa')
plt.xlabel=('tempo')
plt.show()
```

## EDOs de Ordem Superior - Soluções Analíticas

### Massa-Mola sem amortecimendo, ou oscilador harmônico simples

Vamos olhar para a modelagem do sistema massa-mola, novamente temos uma EDO a ser resolvida.

$$
m\frac{\mathrm{d}^2 x}{\mathrm{d}t^2} = -kx\\
\frac{\mathrm{d}^2 x}{\mathrm{d}t^2} = -\frac{k}{m}x
$$
Para ter um pouco de intuição física e algébrica sobre com o que estamos lidando, vamos fazer a seguinte mudança de varíaveis: $\omega_0 = \sqrt{\frac{k}{m}}$

O motivo ficará claro quando chegarmos a solução.

Portanto agora nossa EDO tem a seguinte cara
$$
\frac{\mathrm{d}^2 x}{\mathrm{d}t^2} = -\omega_0^2x \tag{1}
$$

### Resolvendo eq. (1)
$$
\frac{\mathrm{d}^2 x}{\mathrm{d}t^2} = -\omega_0^2x\\
\frac{\mathrm{d}^2 x}{\mathrm{d}t^2} + \omega_0^2x = 0\\
$$
Tomando o operador linear $D^2$ da derivada
$$
(D^2+\omega_0^2I)x = 0\\
$$
Podemos olhar para $(D^2+\omega_0^2I)$ como um polinômio do segundo grau em D, e portanto fatorar
$$
(D-r_1I)(D-r_2I)x = 0\\
$$
Onde $r_n$ são as raízes do polinômio. Se chamarmos o termo $(D-r_2I)x = z$
$$
(D-r_2I)x = z\\
\therefore (D-r_1I)z = 0
$$
Mas esta é uma EDO de primeira ordem, a qual conhecemos a solução geral:
$$
(D-r_1I)z = 0\\
\frac{\mathrm{d}}{\mathrm{d}t}z - r_1z = 0\\
\therefore z = c_1 e^{r_1 t}
$$
Voltando na equação $(D-r_2I)x = z$
$$
(D-r_2I)x = z\\
\frac{\mathrm{d}}{\mathrm{d}t} x - r_2 x = c_1 e^{r_1 t}\\
e^{-r_2 t}(\frac{\mathrm{d}}{\mathrm{d}t} x - r_2 x) = (c_1 e^{r_1 t})e^{-r_2 t}\\
\frac{\mathrm{d}}{\mathrm{d}t}(e^{-r_2 t} x) =  c_1 e^{(r_1⁻r_2) t}\\
e^{-r_2 t} x = \frac{c_1}{r_1 - r_2} e^{(r_1⁻r_2) t}\\
\therefore x(t) = c_2 e^{r_1t} + c_3 e^{r_2 t}
$$
Com $r_1 \neq r_2$

A solução de $(D^2+\omega_0^2I) = 0$, claramente, é $r_1 = i\omega_0, r_2 = -i\omega_0$

Temos então duas raízes complexas, vamos olhar para algumas propriedades dos complexos, seja $C \in \mathbb{C}$, chamamos de $C^*$ o conjugado complexo de $C$
$$
C = a + bi \\
C^* = a - bi\\
C + C^* = a\\
C - C^* = 2bi
$$
Tomando $c_2 = C, c_3 = C^*$, nossa solução se torna:
$$x(t) = C e^{i\omega_0t} + C^* e^{-i\omega_0t}$$
Passando $C$ para coordenadas polares
$$
C = r e^{i\theta} \\
C^* = r e^{-i\theta}\\
r = \sqrt{a^2 + b^2}\\
tg(\theta) = \frac{b}{a}\\
a = r cos(\theta)\\
b = r sen(\theta)\\
\theta \in \left[-\frac{\pi}{2},\dfrac{\pi}{2}\right]\\
$$
Para carregar menos a notação, chamaremos $r = \frac{1}{2}A$, podemos reescrever agora, usando a identidade de Euler:

$$
\begin{align}
x(t) &= \frac{1}{2}A e^{i\theta} e^{i\omega_0t} + \frac{1}{2}A e^{-i\theta}e^{-i\omega_0 t}\tag{sol 1} \\
& = \frac{1}{2}A e^{i(\omega_0t + \theta)} + \frac{1}{2}A e^{-i(\omega_0t + \theta)}\\
& = \frac{1}{2}A \big[cos(\omega_0t + \theta) + i sen(\omega_0t + \theta)\big] + \frac{1}{2} A \big[cos(\omega_0t + \theta) - isen(\omega_0t + \theta)\big] \\
& = \frac{1}{2}A \big[cos(\omega_0t + \theta) + i sen(\omega_0t + \theta) + cos(\omega_0t + \theta) - i sen(\omega_0t + \theta)  \big]\\
x(t) &= A cos(\omega_0t + \theta)
\end{align}
$$
Onde temos um significado para cada valor:
$$
\begin{align}
A &\to \text{Amplitudade da curva senoidal} \\
\omega_0 &\to \text{Frequência Angular} \\
\theta &\to \text{Fase, ou defasagem da curva senoidal}
\end{align}
$$

### Massa Mola Amortecido

$$m\frac{d^2x}{dt^2}=-kx-\mu\frac{dx}{dt}$$

Seja $D$ um operador linear, podemos escrever:
$$(mD^2+\mu D+ kI)x=0$$

Então queremos $D$ tal que:
$$(mD^2+\mu D+ kI)=0$$

Achando as raízes temos:
$$D=-\frac{\mu}{2m}\pm \sqrt{\big(\frac{\mu}{2m}\big)^2-\frac{k}{m}}$$

#### Os três casos diferentes

Para as duas raízes acima temos três situações que resultam em diferentes tipos de amortecimento:

$$
1) \frac{k}{m}>(\frac{\mu}{2m})^2\\
2) \frac{k}{m}<(\frac{\mu}{2m})^2\\
3) \frac{k}{m}=(\frac{\mu}{2m})^2\\
$$
#### 1)Subamortecido

Temos que:
$$\frac{k}{m}>(\frac{\mu}{2m})^2$$
Aplicando uma mudança de variáveis:

$$\frac{\mu}{2m}=\gamma \\
\frac{k}{m}=\omega_0^2 \\
\sqrt{\omega_0^2-\gamma^2}=\omega_1$$

Então temos que $D=-\gamma \pm i\omega_1$

Voltando ao sistema para $r_1=-\gamma +i\omega_1$ e $r_2=-\gamma -i\omega_1$

$$(mD^2+\mu D+ kI)x=(D-r_1I)(D-r_2I)x=0$$

Fazendo o mesmo processo para o massa mola sem atrito temos:
$$x=c_1e^{r_1}+c_2e^{r_2} \\
x(t)=Ce^{(-\gamma + i\omega_1)t} + C^*e^{(-\gamma - i\omega_1)t} \\
e^{-\gamma t}(Ce^{i\omega_1t}+C^*e^{-i\omega_1t})$$

Então fora o fator  $e^{-\gamma t}$ voltamos ao caso anterior de massa mola, adotando a `sol 1` feita anteriormente chegamos em:

$$x(t)=Ae^{-\gamma t}\cos(\omega_1t+\theta)$$

Onde $A$ e $\theta$ dependem das condições inicias.

---

#### 2)Superamortecido
Temos que:
$$\frac{k}{m}<(\frac{\mu}{2m})^2$$

Aplicando uma mudança de variáveis:

$$\frac{\mu}{2m}=\gamma \\
\frac{k}{m}=\omega_0^2 $$

Temos que $D=-\gamma \pm \sqrt{\gamma^2-\omega_0^2}$

Tomando $r_1=-\gamma + \sqrt{\gamma^2-\omega_0^2}$ e $r_2=-\gamma - \sqrt{\gamma^2-\omega_0^2}$:
$$(D-r_1)(D-r_2)x = 0$$

Refazendo os mesmo passos anteriores:
$$x=c_1e^{r_1}+c_2e^{r_2} \\
x(t)=c_1e^{(-\gamma + \sqrt{\gamma^2-\omega_0^2})t}+c_2e^{(-\gamma - \sqrt{\gamma^2-\omega_0^2})t}$$

Sendo $\sqrt{\gamma^2-\omega_0^2}=a$ temos:

$$x(t)=e^{-\gamma t}(c_1e^{at}+c_2e^{-at})$$

Com $c_1$ e $c_2$ constantes que dependem das condições iniciais.

---

### 3)Criticamente Amortecido

Temos que:
$$\frac{k}{m}=(\frac{\mu}{2m})^2$$

Com a mesma mudança de variável feita anteriormente temos que $D=-\gamma$, então para $r=-\gamma$ temos:
$$(D-r)(D-r)x = 0$$
Tomando $(D-r)x = z$
$$(D-r)z = 0 \\
\frac{d}{dt}z - rz = 0\\
\frac{d}{dt}z =rz \\
z = c e^{r t}$$

Voltando a equação anterior:
$$(D-r)x = z\\
(D-r)x = c e^{r t}\\
e^{-r t}\big(\frac{d}{dt}x - rx\big)=c e^{r t}e^{-r t}\\
\frac{d}{dt}(e^{-r t}x)=c e^{(r-r)t}=c \\
e^{-r t}x=c_1 t+c_2 \\
x(t)=(c_1 t+c_2)e^{r t}$$

Então substituindo $r=-\gamma$ temos para $c_1$ e $c_2$ constantes que dependem das condições iniciais:
$$x(t)=(c_1 t+c_2)e^{-\gamma t}$$

### Redução de ordem de EDOs e suas soluções - um pouco de Álgebra Linear

Ao reduzir ordem de EDOs, representaremos as com matrizes, como observado nas soluções analiticas elas sempre carregam uma função, em geral a exponencial $e^x$ ou uma senoidal como $cosseno$, precisamos então discutir o que significa aplicar essa função a uma matriz.

#### Exponencial de uma Matriz

Relembrando a série de Taylor para a função exponencial $e^x$

$$\mathrm{e}^x = \sum_{n=0}^\infty \frac{x^n}{n!}$$
Então, seja A uma matriz, vamos ver se podemos escrever
$$\mathrm{e}^A = \sum_{n=0}^\infty \frac{A^n}{n!}$$

Como uma série é uma soma, a soma de matrizes é bem definida. multiplicar uma matriz por $\frac{1}{n!}, \forall n \in \mathbb{N}$ também está bem definido.

A operação $A^n$ nada mais é do que multiplicar a matriz A pela matriz A, n vezes. Logo como é uma multiplicação de matrizes iterada precisamos que A seja uma matriz quadrada, assim esta operação estará sempre definida. Logo para matrizes quadradas é perfeitamente possível fazer a operação $\mathrm{e}^A$

#### Um pouco mais de propriedades
Imaginemos uma matriz $A_{mxm}$, tal que A é diagonal
$$
\begin{pmatrix}
a_0 &0 &\dots &  0 \\
0 &a_1 &\dots & 0 \\
\vdots & 0 & a_j &0 \\
0 & 0 & \dots & a_m
\end{pmatrix}
$$
Então $A^n$ é dado por
$$
\begin{pmatrix}
a_0 &0 &\dots &  0 \\
0 &a_1 &\dots & 0 \\
\vdots & 0 & a_j &0 \\
0 & 0 & \dots & a_m
\end{pmatrix} \cdot \dots \cdot \begin{pmatrix}
a_0 &0 &\dots &  0 \\
0 &a_1 &\dots & 0 \\
\vdots & 0 & a_j &0 \\
0 & 0 & \dots & a_m
\end{pmatrix} = \begin{pmatrix}
a_0^n &0 &\dots &  0 \\
0 &a_1^n &\dots & 0 \\
\vdots & 0 & a_j^n &0 \\
0 & 0 & \dots & a_m^n
\end{pmatrix}
$$

Portanto a operação de exponencial de uma matriz se torna simplesmente, pelas propriedades de multiplicação por escalar e soma de matrizes
$$
\mathrm{e}^A = \sum_{n=0}^\infty \frac{A^n}{n!} = \begin{pmatrix}
e^{a_0} &0 &\dots &  0 \\
0 & e^{a_1} &\dots & 0 \\
\vdots & 0 & e^{a_j} &0 \\
0 & 0 & \dots & e^{a_m}
\end{pmatrix}
$$

Reduzindo assim o custo computacional da operação.
O mesmo processo se dá para qualquer função $f(x)$ que precisemos aplicar a uma matriz, em especial estamos interessados também no $cosseno$

Esses últimos fatos podem ser aplicados na resolução de sistemas de equações diferenciais. Vamos tomar como exemplo a Lei de Hooke, que modela o comportamento de um sistema massa-mola em certas condições. A lei afirma que a força elástica de uma mola é diretamente proporcional a quanto ela está distendida ou comprimida. Isso é:

$$\textrm{Força elástica} = -kx$$

Ignorando forças externas, pela segunda lei de Newton temos que:

$$m\frac{\mathrm{d}^2x}{\mathrm{d}t^2} = -kx$$

$$\frac{\mathrm{d}^2x}{\mathrm{d}t^2} = -\frac{k}{m}x$$

Podemos reescrever essa equação como um sistema de equações de 1ª. ordem:

$$\begin{cases}
\frac{\mathrm{d}x}{\mathrm{d}t} = v\\
\frac{\mathrm{d}v}{\mathrm{d}t} = -\frac{k}{m}x\end{cases}$$

Esse sistema, por sua vez, pode ser escrito em uma notação matricial:

$$\frac{\mathrm{d}y}{\mathrm{d}t} = Ay$$

onde

$$y = \
\begin{bmatrix}
x\\
v\\
\end{bmatrix},\\
A = \
\begin{bmatrix}
0&1\\
-\frac{k}{m}&0\\
\end{bmatrix}$$

Nessa altura, uma pergunta deve ser feita: Qual o propósito disso tudo? A que fim serve reescrever o problema original como um sistema de equações ou denotá-lo matricialmente? Para responder essa pergunta, vamos reproduzir a equação em questão após todas essas transformações:

$$\frac{\mathrm{d}y}{\mathrm{d}t} = Ay$$

Uma coisa salta aos olhos: Nosso modelo de sistema massa-mola, reescrito matricialmente, parece idêntico ao modelo malthusiano de crescimento populacional. Não é preciso um grande salto da imaginação para concluir, agora, que podemos usar a mesma solução familiar de um problema no outro:

$$y = \mathrm{e}^{At}y_0$$

Encontrar uma solução se resume essencialmente, então, em computar essa exponencial. Em um primeiro momento, pode parecer que nossa única opção é aproximá-la com os primeiros termos da série de Taylor, mas há uma opção melhor, realizando uma transformação chamada *diagonalização*.

#### Diagonalização

Digamos que $A_{2 \mathrm{x} 2}$ é uma matriz com dois autovetores, $x_1$ e $x_2$. Seja $V$ uma matriz cujas colunas são formadas pelos autovetores de $A$:

$$V = \
\begin{bmatrix}
x_1&x_2\\
\end{bmatrix}$$

A partir dessas definições podemos calcular:

$$AV = \
\begin{bmatrix}
Ax_1&Ax_2\\
\end{bmatrix} = \
\begin{bmatrix}
\lambda_1x_1&\lambda_2x_2\\
\end{bmatrix}$$

Onde $\lambda_1$ e $\lambda_2$ são os autovalores associados. Essa relação ainda pode ser destrichada em:

$$\begin{bmatrix}
\lambda_1x_1&\lambda_2x_2\\
\end{bmatrix} = \
\begin{bmatrix}
x_1&x_2\\
\end{bmatrix} \
\begin{bmatrix}
\lambda_1&0\\
0&\lambda_2
\end{bmatrix}
$$

Assim:

$$AV = V\Lambda$$

Onde $\Lambda = \begin{bmatrix}
\lambda_1&0\\
0&\lambda_2
\end{bmatrix}$ é a matriz de autovalores.

O resultado verdadeiramente interessante aqui é o fato de a matrix $\Lambda$ ser *diagonal*.

Vamos voltar alguns passos e pensar em nosso problema original: Como podemos aplicar isso ao problema de exponenciação?  Vamos ver o que acontece quando substituimos uma matriz por sua forma diagonalizada em uma exponenciação:

$$\mathrm{e}^{At} = \mathrm{e}^{V\Lambda V^{-1}t}$$

Expandindo pela série de Taylor:

$$\mathrm{e}^{At} = I + V\Lambda V^{-1}t + \frac{1}{2}V\Lambda^2V^{-1}t^2 + ...$$

$$\mathrm{e}^{At} = V(I + \Lambda t + \frac{1}{2}\Lambda^2t^2 + ...)V^{-1}$$

$$\mathrm{e}^{At} = V\mathrm{e}^{\Lambda t}V^{-1}$$

Aqui, podemos aplicar o resultado da exponenciação de matrizes diagonais:

$$\mathrm{e}^{At} = V\begin{bmatrix}
e^{\lambda_1} &0 &\dots &  0 \\
0 & e^{\lambda_2} &\dots & 0 \\
\vdots & 0 & e^{\lambda_j} &0 \\
0 & 0 & \dots & e^{\lambda_m}
\end{bmatrix} V^{-1}$$

---

Com essas conclusões, podemos *finalmente* computar uma solução para o problema de Hooke:

Definindo problema de forma matricial:

```python
k, m, t = symbols('k, m, t')
A = Matrix([
    [0, 1],
    [-k/m, 0]
])
A
```

$$\left[\begin{matrix}0 & 1\\- \frac{k}{m} & 0\end{matrix}\right]$$

Computando matrizes de autovetores e autovalores

```python
P, D = A.diagonalize()
P, D
```

$$\left ( \left[\begin{matrix}- \frac{1}{\sqrt{- \frac{k}{m}}} & \frac{1}{\sqrt{- \frac{k}{m}}}\\1 & 1\end{matrix}\right], \quad \left[\begin{matrix}- \sqrt{- \frac{k}{m}} & 0\\0 & \sqrt{- \frac{k}{m}}\end{matrix}\right]\right )$$

Solução para condição inicial [1,0]

```python
(P*exp(D*t)*P**-1)*Matrix([1,0])
```

$$\left[\begin{matrix}\frac{1}{2} e^{t \sqrt{- \frac{k}{m}}} + \frac{1}{2} e^{- t \sqrt{- \frac{k}{m}}}\\\frac{\sqrt{- \frac{k}{m}}}{2} e^{t \sqrt{- \frac{k}{m}}} - \frac{\sqrt{- \frac{k}{m}}}{2} e^{- t \sqrt{- \frac{k}{m}}}\end{matrix}\right]$$

A solução do problema inicial se encontra na primeira linha do vetor. Podemos aplicar o *solver* do sympy ao problema em sua forma original para confirmar que a solução encontrada está correta:

```python
x = Function('x')
hooke = Eq(x(t).diff(t, 2), -(k/m)*x(t))
hooke
```

$$\frac{d^{2}}{d t^{2}}  x{\left (t \right )} = - \frac{k}{m} x{\left (t \right )}$$

```python
# Solução geral
sol = dsolve(hooke)

# Constantes da solução particular
eq1 = Eq(sol.subs(t, 0).rhs, 1)            # x (0) = 1
eq2 = Eq(sol.rhs.diff(t, 1).subs(t, 0), 0) # x'(0) = 0

C1, C2 = symbols('C1, C2')
v1, v2 = linsolve([eq1, eq2], [C1, C2]).args[0]

sol.subs({C1: v1, C2: v2})

```

$$x{\left (t \right )} = \frac{1}{2} e^{t \sqrt{- \frac{k}{m}}} + \frac{1}{2} e^{- t \sqrt{- \frac{k}{m}}}$$

---

### Soluções Númericas

#### Corpo em Queda livre com resistencia do ar
$$\frac{\mathrm{d}^2x}{\mathrm{d}t^2}=-g-\frac{\mu}{m}\frac{\mathrm{d}x}{\mathrm{d}t}$$
Para $g$,$\mu$ e $m$ constantes\\
Teremos na forma vetorial
$$
u = \begin{pmatrix} \frac{\mathrm{d}x}{dt} \\ x \end{pmatrix}
$$

Portanto podemos escrever como

$$
\frac{\mathrm{d}u}{\mathrm{d}t} = \begin{pmatrix} -g \\ \frac{\mathrm{d}x}{\mathrm{d}{t}} \end{pmatrix} + \begin{pmatrix} -\omega^2_1\frac{\mathrm{d}x}{\mathrm{d}{t}} \\ 0 \end{pmatrix}
$$
Sendo $g=9.8m/s^2$, $\mu=0.1$ e massa variando

```python
def model3(u, t):
  xdot, x = u
  return np.array([x, -10-(0.1*xdot)/m])

```

```python
ts=np.linspace(0,20,num=100)
for m in [10,100,1000]:
  ys = odeint(model3,[500,0],ts)
  vs = [k[0] for k in ys]
  plt.plot(ts, vs, label='m = '+ str(m))

plt.legend(title='Massa do Corpo')
plt.ylabel=('Posição')
plt.xlabel=('Tempo')
plt.show()
```

#### Massa e Mola com resistencia do ar:
$$\frac{\mathrm{d}^2x}{\mathrm{d}t^2}=\frac{-kx}{m}-\frac{\mu}{m}\frac{\mathrm{d}x}{\mathrm{d}t}$$
Para $k$ e $m$ constantes.

A função `odeint` da biblioteca `scipy` resolve edos de primeira ordem, precisamos então reduzir nosso problema para uma edo de primeira ordem, para tal iremos escrever nossa equação de forma vetorial, mas antes vamos deixar a notação mais compacta, chamando $\frac{k}{m} = \omega_0^2$ e $\frac{\mu}{m} = \omega_1^2$
$$
u = \begin{pmatrix} \frac{\mathrm{d}x}{dt} \\ x \end{pmatrix}
$$

Portanto podemos escrever como

$$
\frac{\mathrm{d}u}{\mathrm{d}t} = \begin{pmatrix} -\omega^2_0 \\ \frac{\mathrm{d}x}{\mathrm{d}{t}} \end{pmatrix} + \begin{pmatrix} -\omega^2_1\frac{\mathrm{d}x}{\mathrm{d}{t}} \\ 0 \end{pmatrix}
$$

Agora escrevemos um modelo de forma vetorial
Sendo $m=1kg$ e $\mu=0.1$ e k = $2$

```python
def model2(u, t, omegas):
  xdot, x = u
  return [-omegas[0]*x-omegas[1]*xdot, xdot]
```

```python
ts = np.linspace(0,30, num=1000)
ys = odeint(model2,[3,0],ts,([2,0.1],))
vs = [k[0] for k in ys]
plt.plot(ts, vs)
plt.ylabel=('$y(t)$')
plt.xlabel=('t')
plt.show()
```

Vamos fazer  a comparação da solução analitica e númerica para a EDO acima.
Temos que
$$x(t)=Ae^{-\gamma t}\cos(\omega_1t+\theta)$$

Onde
$$
\gamma = \frac{\mu}{2m} = \frac{1}{20}\\
\omega_0 = \sqrt(\frac{k}{m}) = \sqrt(2)\\
\omega_1 = \sqrt(\omega_0^2 - \gamma^2) = \sqrt(2 - \left(\frac{1}{20}\right)^2)
$$

Como para $t=0, x(0) = 3$, teremos:
$$
A = 3\\
\theta = 0
$$

```python
def sol(t):
  gamma = 1/20
  omg1 = np.sqrt(2-(1/20)**2)
  return 3*np.e**(-gamma*t)*np.cos(omg1*t + 0)

ts = np.linspace(0,30, num=1000)
ys = odeint(model2,[3,0],ts,([2,0.1],))
vs = [k[0] for k in ys]
plt.figure(figsize=(20,10))
plt.plot(ts, vs, label='numerica')
plt.plot(ts, sol(ts), label='analitica')
plt.legend(title='curvas')
plt.ylabel=('$y(t)$')
plt.xlabel=('t')
plt.show()
```

#### Gráfico de erro

```python
ts = np.linspace(0,30, num=1000)
ys = odeint(model2,[3,0],ts,([2,0.1],))
vs = [k[0] for k in ys]
plt.figure(figsize=(20,10))
plt.plot(ts, abs(vs-sol(ts)))
plt.ylabel=('err')
plt.xlabel=('t')
plt.title('Erro')
plt.show()
```

### Massa e Mola sem solução analítica:

Podemos utilizar do modelo anterior e adicionar uma nova força de modo que não seja possível calcular a solução de forma analítica do nosso problema, obrigando-nos a usar um método numérioco. Vamos supor o seguinte modelo:

$$\frac{\mathrm{d}^2x}{\mathrm{d}t^2}=\frac{-kx}{m}-\frac{\mu}{m}\frac{\mathrm{d}x}{\mathrm{d}t} - \frac{ce^{-\frac{1}{c+1}x^2}}{m}$$

```python
def ddf(x,dx,t):
  global k,u,c,m
  return -k*x/m -u*dx/m -c*np.exp(-(1/(c+1)*x**2))/m

x0=8
dx0=0

ts=np.linspace(0,20,10000)

def euler_segunda_ordem(f,ts,x0,dx0):
  xs=[x0]
  dxs=[dx0]
  tant=ts[0]
  for t in ts[1:]:
    h=t-tant
    dxs.append(dxs[-1] + f(xs[-1],dxs[-1],tant)*h)
    xs.append(xs[-1] + dxs[-2]*h + (f(xs[-1],dxs[-2],tant)*h**2)/2)
    tant=t
  return xs

```

Começando variando somente com o atrito cinético, sem nossa força exponencial:

```python
k=5
u=0
c=0
m=10

for uv in [0,1,2,4]:
  u=uv
  plt.plot(ts,euler_segunda_ordem(ddf,ts,x0,dx0),label="u = "+ str(uv))
plt.title("Coeficiente de atrito cinético variando")
plt.legend()
plt.show()

```

Agora, somente variando nossa força exponencial, sem o atrito cinético:

```python
k=5
u=0
c=0
m=10

for cv in [0,5,20,50]:
  c=cv
  plt.plot(ts,euler_segunda_ordem(ddf,ts,x0,dx0),label="c = "+ str(c))
plt.title("Coeficiente de atrito especial variando")
plt.legend()
plt.show()
```

Juntando os dois, e variando o nosso atrito especial, temos:

```python
k=5
u=2
c=0
m=10

for cv in [0,5,20,50]:
  c=cv
  plt.plot(ts,euler_segunda_ordem(ddf,ts,x0,dx0),label="c = "+ str(c))
plt.title("Coeficiente de atrito especial variando com amortecimento fixo")
plt.legend()
plt.show()
```

E finalmente, variando ambos os coeficientes, o cinético e o exponencial:

```python
_, [ax1, ax2, ax3] = plt.subplots(ncols=3, figsize=(20,6))

for uv,a in enumerate([ax1, ax2, ax3]):
  u=(uv+1)*2
  for cv in [0,5,20,50]:
    c=cv
    a.plot(ts,euler_segunda_ordem(ddf,ts,x0,dx0),label="u , c = "+ str(u)+" , "+str(c))
    a.legend()
plt.show()

```

```python

```


# DAE with absolute value function in constraints

The system simulated in this example is:

$$  \left\{
        \begin{align}
            \dot{x}_1(t) =&~ 1 + B_0z(t)   \\
            \dot{x}_2(t) =&~ B_1z(t) \\
            0 =&~ |x_1(t)| - x_2(t)
        \end{align}
    \right. $$

In code $B_0 = 0$ and $B_1 = 1$
In this particular Jupyter File we consider the LCP representation of the absolute value function with an LCP.
Let first note that either $|x| = -x$ when $x\leq 0$, or $|x| = x$ when $x\geq0$, with equality iff $x = 0$. This is equivalent to write the complentary problem:

$$ 0\leq |x|-x \perp |x|+x\geq0 $$

noting $\lambda = |x_1|- x_1 $ we finally obtain the system:

$$  \left\{
        \begin{align}
            \dot{x}_1(t) =&~ 1 + B_0z(t)   \\
            \dot{x}_2(t) =&~ B_1z(t) \\
            0 =&~ \lambda  +x_1 - x_2(t) \\
            0\leq&~\lambda+2x_1 \perp \lambda \geq 0
        \end{align}
    \right. $$

Note that different values of $(B_0,B_1)$ and of the initial conditions yield simulated results with jumps even if continuous solutions exists !

```python
import siconos.numerics as sn
import scipy.linalg as linalg
import numpy as np
import siconos.kernel as sk
from numpy import eye, empty, float64, zeros, transpose, array
from siconos.kernel import FirstOrderLinearTIDS, FirstOrderType2R, FirstOrderLinearTIR, EqualityConditionNSL, RelayNSL,\
                           ComplementarityConditionNSL, NonSmoothDynamicalSystem, Interaction, \
                           EulerMoreauOSI, MoreauJeanOSI, LCP, TimeDiscretisation, TimeStepping
import siconos.numerics as sn

z0    = 0

x10   = -5
x20   = 6

t0    = 0.      # start time
T     = 10.0      # end time with : 1.6 for start of the pb

time_step = 0.01 #0.001 # 0.012

# _B = [0,1]     # sliding
_B = [-1,0.5]  #jumping (could stay on the constraint also ...)

_A = zeros((3,3))
_A[0,2] = _B[0]
_A[1,2] = _B[1]
_A[2,0] = 1
_A[2,1] = -1

_b = [1,0,1]

print("A = ")
print(_A)

print("b = ")
print(_b)

_E = np.eye(3)
_E[2,2] = 0
print("E = ")
print(_E)

# Linear ODE system with time invariant coefficients
dyn = FirstOrderLinearTIDS([x10,x20,z0],_A)
dyn.setbPtr(_b)
dyn.setMPtr(_E)

switch = NonSmoothDynamicalSystem(t0, T)
switch.insertDynamicalSystem(dyn)

####################################################

#
R= zeros((3,1));
R[2,0] = 1
print("R = ")
print(R)

C = zeros((1,3));
C[0,0] = 2;
print("C = ")
print(C)

D = zeros((1,1));
D[0,0] = 1;
print("D = ")
print(D)

e = [0]# constant parts in LCP left hand sides

# Declaration of the left hand side of the LCP in the form
# C1*x + D1*λ + e1
# Using the matrices previously defined
# R1 is built the such that dx/dt = A*x + R1*λ + b
rel_python_1 = sk.FirstOrderLinearTIR(C, R)
rel_python_1.setDPtr(D)
rel_python_1.setePtr(e)

# Declaration that right side is an LCP
nslaw1 = ComplementarityConditionNSL(1)

# Link between left hand side et right hand side of the LCP
# 0=< C1*x + D1*λ + e1 _|_ λ>= 0
interaction_1 = Interaction(nslaw1, rel_python_1)

switch.link(interaction_1, dyn)

# Discretization and non-smooth problem formulation (LCP)
θ = 1.
γ = 1.
#osi = EulerMoreauOSI(θ)  # One Step time Integrator for First Order Dynamical Systems.
# Simple theta method (~backward euler)
osi = EulerMoreauOSI(θ,γ)  # One Step time Integrator for First Order Dynamical Systems.

osnspb = sk.LCP()

# Simulation and time discretisation
td = TimeDiscretisation(t0, time_step)
simu = TimeStepping(switch, td, osi, osnspb)

##########################################################################
## !!! ALWAYS DECLARE COMPUTE RESIDUY and R for NonLinear Relations !!!!
##         OTHERWISE NEWTOWN ALG DO NOT USE JACOBIANS
#########################################################################
# simu.setComputeResiduY(True)
# simu.setComputeResiduR(True)
# simu.setNewtonMaxIteration(100) #100 more funcky
# simu.setNewtonTolerance(1e-10)
##########################################################################

##### Simulation run
x = dyn.x() # tracking state variables form ODE
λ = interaction_1.lambda_(0) # tracking λ variables form LCP
k = 0

##### Numpy array used to save data at each time step, for post-processing
N = int((T - t0) / simu.timeStep()) + 1
data_plot = zeros((N, 6))

###### Initial state
data_plot[k, 0] = t0
data_plot[k, 1] = x[0] # x1
data_plot[k, 2] = x[1] # x2
data_plot[k, 3] = x[2] # z
data_plot[k, 4] = λ[0] # |x1|-x
k += 1

while simu.hasNextEvent():

    simu.computeOneStep() # Build and solve the LCP
#     osnspb.display()
    data_plot[k, 0] = simu.nextTime()
    data_plot[k, 1] = x[0] # x1
    data_plot[k, 2] = x[1] # x2
    data_plot[k, 3] = x[2] # z
    data_plot[k, 4] = λ[0] # |x1|-x
    k += 1
    #rel_python.display()
    simu.nextStep() # Save current state and prepare next step

print("Number of iterations = ",k)

import ipympl
import matplotlib.pyplot as plt
%matplotlib notebook

plt.figure(figsize=(10,15))
plt.subplot(311)
plt.title('phase-space plot x1,x2')
plt.plot(data_plot[0:k - 1, 1], data_plot[0:k - 1, 2],label='x2(x1)')
plt.legend()
plt.grid()
plt.subplot(312)
plt.title('times plots')
plt.plot(data_plot[0:k - 1, 0], data_plot[0:k - 1, 1],label='x1(t)')
plt.plot(data_plot[0:k - 1, 0], data_plot[0:k - 1, 2],label='x2(t)')
plt.legend()
plt.grid()
plt.subplot(313)
plt.title('absolute value function f(x1) = |x1| phase-space plots')
plt.plot(data_plot[0:k - 1, 1], data_plot[0:k - 1, 1] + data_plot[0:k - 1, 4],label='|x1| = λ(t) + x1(t)')
plt.legend()
plt.grid()

constraint = -data_plot[0:k - 1, 2] + data_plot[0:k - 1, 1] + data_plot[0:k - 1, 4]
plt.figure(figsize=(10,5))
plt.title('Constraint evolution (time plot) -x2(t) + |x1(t)|')
plt.plot(data_plot[0:k - 1, 0], constraint,label='constraint(t)')
plt.legend()
plt.grid()
plt.show()

plt.figure(figsize=(10,5))
plt.title('z(t)')
plt.plot(data_plot[0:k - 1, 0], data_plot[0:k - 1, 3],label='z(t)')
plt.legend()
plt.grid()
plt.show()

plt.figure(figsize=(10,5))
plt.title('λ(t)')
plt.plot(data_plot[0:k - 1, 0], data_plot[0:k - 1, 4],label='λ(t)')
plt.legend()
plt.grid()
plt.show()

print(data_plot[0:k - 1, 4])
```

    A =
    [[ 0.   0.  -1. ]
     [ 0.   0.   0.5]
     [ 1.  -1.   0. ]]
    b =
    [1, 0, 1]
    E =
    [[ 1.  0.  0.]
     [ 0.  1.  0.]
     [ 0.  0.  0.]]
    R =
    [[ 0.]
     [ 0.]
     [ 1.]]
    C =
    [[ 2.  0.  0.]]
    D =
    [[ 1.]]
    Number of iterations =  1001

    <IPython.core.display.Javascript object>

    <IPython.core.display.Javascript object>

    <IPython.core.display.Javascript object>

    <IPython.core.display.Javascript object>

    [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
      0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]

```python

```