"realpart.(d) # récupère la partie réelle de d : (x, y)\n",
"dualpart.(d) # récupère la partie duale de d : (u, v) \n",
"```\n",
"\n",
"- En `Julia`, nous pouvons typer les fonctions pour utiliser le \"polymorphisme\" appelé aussi \"multiple dispatch\", ce qui permet de choisir le comportement d'une fonction en fonction du type des arguments. Par exemple :\n",
Le but est de résoudre par du tir simple indirect, deux problèmes simples de contrôle optimal dont le contrôle maximisant est lisse.
Le premier problème est en dimension 1 et possède des conditions aux limites simples tandis que le second est en dimension 2 et aura des conditions de transversalités sur le vecteur adjoint.
On propose un dernier exercice sur la dérivation de fonctions par les nombres duaux.
1. Afficher le flot du système hamiltonien associé et afficher 5 fronts aux temps $0$, $0.25$, $0.5$, $0.75$ et $1$ ainsi que quelques extrémales. On utilisera le TP précédent.
2. Coder la fonction de tir
$$
S(p_0) = \pi(z(t_f, x_0, p_0)) - x_f,
$$
où $t_f = 1$, $x_0=-1$, $x_f = 0$ et où $z=(x,p)$ et $\pi(z) = x$. Vous pouvez utiliser votre cours.
3. Afficher la fonction de tir pour $p_0 \in [0, 1]$.
4. Résoudre l'équation $S(p_0) = 0$ et tracer l'extrémale dans le plan de phase, cf. question 1. Vous donnerez une bonne initialisation au solveur de Newton sous-jacent.
Vous venez d'utiliser le package `ForwardDiff` pour calculer la Jacobienne de la fonction de tir. Ce package utilise les nombres duaux afin de pouvoir diférencier automatiquement vos fonctions.
Les nombres duaux s'écrivent sous la forme $a + b\,\varepsilon$ avec $(a,b)\in \mathbb{R}^2$ et $\varepsilon^2 = 0$. Nous allons voir comment nous pouvons les utiliser pour calculer des dérivées.
Soit deux fonctions $f, g \colon \mathbb{R} \to \mathbb{R}$ dérivables, de dérivées respectives $f'$ et $g'$. On pose
realpart.(d)# récupère la partie réelle de d : (x, y)
dualpart.(d)# récupère la partie duale de d : (u, v)
```
- En `Julia`, nous pouvons typer les fonctions pour utiliser le "polymorphisme" appelé aussi "multiple dispatch", ce qui permet de choisir le comportement d'une fonction en fonction du type des arguments. Par exemple :
```julia
julia>fun(y::Integer)=2y
julia>fun(y::Real)=y/2
julia>fun(2)
4
julia>fun(2.0)
1.0
```
**Attention !**
La fonction $f$ étant déjà définie plus haut, définissez-la en utilisant une majuscule :