{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Fonctions d'une variable complexe (II)\n",
    "\n",
    "# Exponentielle, logarithmes, puissances\n",
    "\n",
    "Marc Lorenzi\n",
    "\n",
    "7 avril 2019"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import cmath\n",
    "import math\n",
    "import colorsys\n",
    "import random"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.rcParams['figure.figsize'] = (10, 10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "__Avertissement__ : Avant de lire ce notebook, regardez celui intitulé Fonctions d'une variable complexe (I).\n",
    "\n",
    "Nous allons poursuivre ce que nous avons commencé dans le notebook précédent et nous intéresser aux fonctions usuelles bien connues sur $\\mathbb R$ : exponentielle, logarithme, puissances. Dans un troisième nobook, nous explorerons la trigonométrie. \n",
    "\n",
    "Voici tout d'abord la fonction de tracé introduite dans le premier notebook. Je ne la ré-expliquerai pas."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def arg01(z):\n",
    "    theta = cmath.phase(z) / (2 * math.pi)\n",
    "    if theta < 0: return theta + 1\n",
    "    else: return theta"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def psi(x, m, d):\n",
    "    if x == 0: return 0\n",
    "    else:\n",
    "        return abs(math.sin(math.pi * math.log(x, 2) / m)) ** d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_complex(f, extent=[-1.5, 1.5, -1.5, 1.5], m=1, d=0.2, nx=301, ny=301):\n",
    "    xmin, xmax, ymin, ymax = extent\n",
    "    ws = [[0 for i in range(nx)] for j in range(ny)]\n",
    "    plt.hsv()\n",
    "    for i in range(nx):\n",
    "        for j in range(ny):\n",
    "            x = xmin + j * (xmax - xmin) / nx\n",
    "            y = ymax - i * (ymax - ymin) / ny\n",
    "            z = x + 1j * y\n",
    "            try:\n",
    "                w = f(z)\n",
    "                r = psi(abs(w), m, d)\n",
    "                ph = arg01(w)\n",
    "                ws[i][j] = colorsys.hsv_to_rgb(ph, 1, r)\n",
    "            except:\n",
    "                ws[i][j] = (0., 0., 0.)\n",
    "    plt.imshow(ws, interpolation='bicubic', extent=extent, aspect='auto')\n",
    "    plt.grid()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. L'exponentielle"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.1 C'est quoi ?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La fonction exponentielle est la mère de toutes les fonctions usuelles. Voici sa définition.\n",
    "\n",
    "__Définition__ : Pour tout $z\\in\\mathbb C$,\n",
    "\n",
    "$$e^z=\\sum_{n=0}^\\infty \\frac{z^n}{n!}$$\n",
    "\n",
    "Lorsqu'on maîtrise la théorie des séries entières, il est alors assez facile de prouver les résultats suivants.\n",
    "\n",
    "__Proposition__ : Pour tous $z,z'\\in\\mathbb C$, $e^{z+z'}=e^ze^{z'}$.\n",
    "\n",
    "\n",
    "__Proposition__ : La fonction exponentielle est holomorphe sur $\\mathbb C$, et $\\exp'=\\exp$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Rappelons que pour $z=x+iy\\in\\mathbb C$, on a $e^z=e^x(\\cos y + i\\sin y)$, où pour l'instant, nous appelons $\\sin$ et $\\cos$ les fonctions de $\\mathbb R$ vers $\\mathbb R$ dont vous avez sans doute déjà entendu parler. Nous reviendrons sur ces fonctions dans le prochain notebook."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2 Un algorithme de calcul de l'exponentielle"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Nous allons examiner dans cette section comment calculer une valeur approchée de $e^z$ à partir de la série ci-dessus. Le terme général de la série qui définit l'exponentielle est $\\frac {z^n}{n!}$. La bonne nouvelle est le dénominateur $n!$ qui tend très vite vers l'infini. Le numérateur $z^n$, en revanche, est une fort mauvaise nouvelle si $|z|$ est grand."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 1.2.1 Majorons le reste d'une série convergente"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Commençons par établir une inégalité.\n",
    "\n",
    "__Proposition__ : Soit $n\\in\\mathbb N^*$. On a\n",
    "\n",
    "$$\\sum_{k=n+1}^\\infty\\frac 1 {k!}\\le \\frac 1 {n!n}$$\n",
    "\n",
    "__Démonstration__ : Soit $k\\ge n + 1$. On a \n",
    "\n",
    "$$\\frac 1 {k!}=\\frac 1 {(n+1)!}\\frac 1 {(n+2)(n+3)\\ldots k}\\le \\frac 1 {(n+1)!}\\frac 1{(n+1)^{k-n-1}}$$\n",
    "\n",
    "De là, $$\\sum_{k=n+1}^\\infty\\frac 1 {k!}\\le \\frac 1 {(n+1)!}\\sum_{k=n+1}^\\infty \\frac 1{(n+1)^{k-n-1}}=\\frac 1 {(n+1)!}\\sum_{k=0}^\\infty \\frac 1{(n+1)^{k}}$$\n",
    "\n",
    "La série ci-dessus est une série géométrique convergente, dont la somme est\n",
    "\n",
    "$$\\sum_{k=0}^\\infty \\frac 1{(n+1)^{k}}=\\frac 1 {1-\\frac 1 {n+1}}=\\frac {n+1}n$$\n",
    "\n",
    "D'où le résultat."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 1.2.2 Le cas $|z|\\le 1$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Soit maintenant $z\\in\\mathbb C$ tel que $|z|\\le 1$. Pour tout entier $k\\ge n+1$, on a $|z^k| \\le |z|^{n+1}$. Ainsi, \n",
    "\n",
    "$$\\left|\\sum_{k=n+1}^\\infty\\frac {z^k} {k!}\\right|\\le \\frac {|z|^{n+1}} {n!n}$$\n",
    "\n",
    "Pour calculer $e^z$ à la précision $10^{-p}$ il suffit donc de calculer $\\sum_{k=0}^n\\frac {z^k} {k!}$ où l'entier $n$ est tel que \n",
    "\n",
    "$$\\left|\\frac 1 z\\right|^{n+1}n!n \\ge 10 ^p$$\n",
    "\n",
    "Prenons par exemple $|z|\\le \\frac 1 8$. Quel entier $n$ choisir ? Allons, un peu de Python. Voici tout d'abord la fonction factorielle."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def fact(n):\n",
    "    p = 1\n",
    "    for k in range(1, n + 1): p = p * k\n",
    "    return p"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Puis une petite boucle."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "n = 0\n",
    "while 8 ** n * n * fact(n) <= 1e17: n = n + 1\n",
    "print(n)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Si $|z|\\le \\frac 1 8$, $n=11$ est donc suffisant pour obtenir une précision de $10^{-17}$. Sachant que les flottants Python ont moins de 17 chiffres significatifs, cela nous suffira plus qu'amplement. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 1.2.3 Le cas général"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Que faire si nous ne savons rien de $|z|$ ? Ce qui nous sauve c'est que la fonction exponentielle est un morphisme. On a pour tout entier $p$\n",
    "\n",
    "$$\\exp(\\frac z {2^p})^{2^p}=e^z$$\n",
    "\n",
    "L'idée est de diviser z par 2, puis par 2, puis par 2, etc. jusqu'à ce que le module de $\\frac z {2^p}$ soit assez petit, disons inférieur à ... $\\frac 1 8$. On se retrouve alors dans le cas précédent. On calcule une valeur approchée de $$\\exp(\\frac z {2^p})$$ puis on élève cette valeur à la puissance $2^p$. Pour cela, on remarque que $p$ élévations au carré suffisent :\n",
    "\n",
    "$$x^{2^p}=(\\ldots((x^2)^2)^2)\\ldots)^2$$\n",
    "\n",
    "Écrivons donc notre fonction exponentielle et comparons la à la fonction `cmath.exp` de Python !"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 1.2.4 La fonction"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def exp(z):\n",
    "    t = 0\n",
    "    while abs(z) > 1/8:\n",
    "        z = z / 2\n",
    "        t = t + 1\n",
    "    n = 12\n",
    "    s = 0\n",
    "    f = 1\n",
    "    p = 1\n",
    "    for k in range(1, n + 1):\n",
    "        s = s + p / f\n",
    "        f = f * k\n",
    "        p = p * z\n",
    "    for k in range(t): s = s ** 2\n",
    "    return s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z = 1.2345 + 2.245 * 1j\n",
    "print(exp(z))\n",
    "print(cmath.exp(z))\n",
    "print('différence : ', abs(exp(z) - cmath.exp(z)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Nous espérions $10^{-17}$ mais il ne faut pas rêver. Il est normal que les derniers chiffres puissent différer entre les deux fonctions, ils sont perturbés par les erreurs d'arrondi dans les calculs. Seuls des calculs avec une plus grande précision pourraient régler ce problème (ce que nous ne ferons pas)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.3 Le graphe"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "À quoi ressemble graphiquement l'exponentielle complexe ? Remarquons que $|e^z|=e^x$ et $\\arg e^z\\equiv y[2\\pi]$. Nous voyons donc que le module de $e^z$ ne dépend que de $x$, et son argument ne dépend que de $y$. Le graphe de l'exponentielle va donc être une suite de bandes verticales, et ces bandes auront des couleurs périodiques."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plot_complex(lambda z: cmath.exp(z), extent=[-6, 1, -6, 6])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ce serait presque décevant :-). Tentons maintenant $z\\mapsto e^{iz}-1$. Cette fonction a une infinité de racines, qui sont les multiples de $2\\pi$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "M = 8\n",
    "plot_complex(lambda z: cmath.exp(1j * z) - 1, extent=[-M, M, -M, M])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Remarquez les cycles de couleurs autour des racines dans le sens trigonométrique. Pourquoi le haut du graphique est-il tout noir ? Eh bien, posons $z=x+iy$. On a $e^{iz}=e^{ix}e^{-y}$ et donc $|e^{iz}|=e^{-y}$. Lorsque $y$ tend vers $+\\infty$, ce module tend donc vers 0. Conséquence : $e^{iz}-1$ tend vers $-1$ et notre convention de couleurs affiche des pixels cyans de plus en plus sombres.\n",
    "\n",
    "Passons au logarithme !"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Le logarithme"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.1 Introduction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Le module `cmath` possède une fonction `log`. Mais qu'est-ce que $\\log z$ pour $z$ complexe ?\n",
    "\n",
    "__Définition__ : Soit $z\\in\\mathbb C^*$. __UN__ logarithme de $z$ est un nombre complexe $w$ tel que $e^w=z$.\n",
    "\n",
    "Nous avons supposé $z\\ne 0$ parce que $e^w=0$ est une équation perdue d'avance. Posons donc $z=re^{it}$, où $r=|z|$ est $t=\\arg z$ est un argument de $z$. Soit $w=x+iy$. On a\n",
    "\n",
    "$$e^w=z\\Leftrightarrow e^xe^{iy}=re^{it}$$\n",
    "\n",
    "Ce qui équivaut à $x=\\ln |z|$ et $y=t+2k\\pi$ où $k\\in\\mathbb Z$. Ainsi, les logarithmes de $z$ sont les nombres complexes de la forme\n",
    "\n",
    "$$w=\\ln|z|+i\\arg z + 2ik\\pi$$\n",
    "\n",
    "où $\\arg z$ est un argument de $z$ et $k\\in\\mathbb Z$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Voici la documentation du module `cmath` :\n",
    "\n",
    "`cmath.log(x[, base])\n",
    "Returns the logarithm of x to the given base. If the base is not specified, returns the natural logarithm of x. There is one branch cut, from 0 along the negative real axis to -∞, continuous from above.`\n",
    "\n",
    "\n",
    "Traduction : pour Python, \n",
    "\n",
    "$$\\log z =\\ln|z|+i\\arg z$$\n",
    "\n",
    "où $\\arg z$ est l'unique argument de $z$ appartenant à $]-\\pi, \\pi]$. C'est ce que l'on appelle la __détermination principale du logarithme__.\n",
    "\n",
    "__Proposition__ : $\\log$ est holomorphe sur $\\Omega=\\mathbb C\\setminus \\mathbb R_-$. Et pour tout $z\\in\\Omega$, $\\log' z=\\frac 1 z$.\n",
    "\n",
    "__Démonstration__ : Nous admettrons ce résultat. \n",
    "\n",
    "La fonction $\\log$, bien que définie sur $\\mathbb C^*$ pose des problèmes pour les réels négatifs. Pour voir quel genre de problèmes, le mieux à faire est de la tracer. Mais avant, intéressons nous à la façon de calculer une valeur approchée de $\\log z$. En cas d'impatience, sautez directement au paragraphe 3.3."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2 Un algorithme de calcul du logarithme"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "__Proposition__ : Soit $z\\in\\mathbb C$ tel que $|z|<1$. On a\n",
    "\n",
    "$$\\log(1+z)=\\sum_{n=1}^\\infty(-1)^{n-1}\\frac{z^n}{n}$$\n",
    "\n",
    "$\\log(1+z)$ est donc la somme d'une série convergente. Mais remarquons que cette série converge moins rapidement que la série qui converge vers $e^z$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.2.1 Le cas réel"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Soit $x\\in\\mathbb R_+^*$. Si $x<1$, alors $\\frac 1 x>1$ et $\\ln \\frac 1 x = -\\ln x$. Supposons donc dorénavant que $x\\ge 1$.\n",
    "\n",
    "__Proposition__ : Il existe un unique entier naturel $t$ tel que $\\frac 1 2< \\frac x {2^t}\\le 1$.\n",
    "\n",
    "__Démonstration__ : L'inégalité souhaitée équivaut à\n",
    "\n",
    "$$2^{t-1}< x \\le 2^t$$\n",
    "\n",
    "L'existence d'un tel entier $t$ en découle. Précisément, \n",
    "\n",
    "$$t=1+\\lceil \\log_2 x\\rceil$$\n",
    "\n",
    "Si nous voulons calculer $\\ln x$, il nous suffit de savoir calculer $\\ln \\frac x{2^t}$, puisque\n",
    "\n",
    "$$\\ln x = \\ln \\frac x{2^t} + t\\ln 2$$\n",
    "\n",
    "Il faut évidemment aussi connaître une valeur approchée de $\\ln 2$. On peut donc se ramener au calcul de $\\ln x$ pour $\\frac 1 2 < x \\le 1$. Ce que nous supposons maintenant.\n",
    "\n",
    "Soit $w=\\frac{x-1}{1+x}$. On a $\\frac{1+w}{1-w}=x$ et on vérifie aisément que $-\\frac 1 3 <w\\le 0$. De là\n",
    "\n",
    "$$\\ln x = \\ln(1+w)-\\ln(1-w)=\\sum_{k=1}^\\infty(-1)^{k-1}\\frac {w^k} k+\\sum_{k=1}^\\infty\\frac {w^k} k$$\n",
    "\n",
    "ou encore\n",
    "\n",
    "$$\\ln x = \\sum_{k=1}^\\infty((-1)^{k-1}+1)\\frac {w^k} k=2\\sum_{k=0}^\\infty\\frac{w^{2p+1}}{2p+1}$$\n",
    "\n",
    "On peut donc approcher $\\ln x$ par une somme partielle de la série ci-dessus, quelque chose du genre\n",
    "\n",
    "$$\\sum_{k=0}^n\\frac{w^{2p+1}}{2p+1}$$\n",
    "\n",
    "Que prendre pour $n$ ? Cette série est une série alternée, car $w\\le 0$, et on vérifie aisément que son terme général décroît en valeur absolue vers 0. Le reste des sommes partielles est donc majoré en valeur absolue par son premier terme\n",
    "\n",
    "$$\\frac{|w^{2n+3}|}{2n+3}\\le \\frac 1{3^{2n+3}(2n+3)}$$\n",
    "\n",
    "Alors, combien pour $n$ ? Mettons que nous voulions une erreur inférieure à $10^{-17}$ :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "n = 0\n",
    "while 3 ** (2 * n + 3) * (2 * n + 3) <= 10 ** 17: n = n + 1\n",
    "print(n)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$n = 15$ sera parfait. Allons, programmons !"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def ln(x):\n",
    "    ln2 = 0.6931471805599453\n",
    "    if x < 1: return - ln(1 / z)\n",
    "    else:\n",
    "        t = 0\n",
    "        while x >= 1:\n",
    "            x = x / 2\n",
    "            t = t + 1\n",
    "        w = (x - 1) / (1 + x)\n",
    "        w2 = w ** 2\n",
    "        sgn = 1\n",
    "        n = 15\n",
    "        s = 0\n",
    "        for k in range(n):\n",
    "            s = s + w / (2 * k + 1)\n",
    "            w = w * w2\n",
    "        return 2 * s + t * ln2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 123.456\n",
    "print(ln(x))\n",
    "print(math.log(x))\n",
    "print(ln(x)-math.log(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.2.2 Le cas complexe"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Soit $z\\in\\mathbb C^*$. On a $\\log z =\\ln |z| + i\\arg z$ où $\\arg z\\in]-\\pi,\\pi]$. Il est donc immédiat d'obtenir une valeur approchée de la partie réelle de $\\log z$, c'est ce que nous avons fait dans le paragraphe précédent. Que faire pour la partie imaginaire ?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "__Proposition__ : Soit $z\\in\\mathbb C\\setminus \\mathbb R_-$. On a\n",
    "\n",
    "$$\\arg z = 2\\arctan\\frac{\\Im z}{\\Re z + |z|}$$\n",
    "\n",
    "__Démonstration__ : Posons $z=x+iy$. Soit $\\theta=\\arg z$. On a\n",
    "\n",
    "$$\\cos^2\\frac\\theta 2=\\frac 1 2(1+\\cos\\theta)=\\frac 1 2(1 + \\frac x {|z|})=\\frac{|z|+x} 2$$\n",
    "\n",
    "et de même\n",
    "\n",
    "$$\\sin^2\\frac\\theta 2=\\frac 1 2(1-\\cos\\theta)=\\frac 1 2(1 - \\frac x {|z|})=\\frac{|z|-x} 2$$\n",
    "\n",
    "Comme $z\\not\\in\\mathbb R_-$, on a $|z|+x\\ne 0$. De là,\n",
    "\n",
    "$$\\tan^2\\frac \\theta 2=\\frac{\\sin^2\\frac \\theta 2}{\\cos^2\\frac \\theta 2}=\\frac{|z|-x}{|z|+x}=\\frac{(|z|-x)(|z|+x)}{(|z|+x)^2}=\\frac{y^2}{(|z|+x|)^2}$$\n",
    "\n",
    "D'où\n",
    "\n",
    "$$\\tan \\frac\\theta 2 = \\pm \\frac{y}{|z|+x}$$\n",
    "\n",
    "Comme $\\theta\\in]-\\pi,\\pi[$, le signe de $\\theta$ est celui de $y$. Le $\\pm$ ci-dessus est donc un plus. Pour terminer, il reste à remarquer que $-\\frac \\pi 2<\\frac\\theta 2<\\frac \\pi 2$, on peut donc passer à l'ar tangente dans l'égalité ci-dessus pour obtenir\n",
    "\n",
    "$$\\frac \\theta 2 = \\arctan  \\frac{y}{|z|+x}$$\n",
    "\n",
    "Voici donc ci dessous une fonction renvoyant l'argument d'un nombre complexe $z$, à supposer que l'on dispose d'une fonction arc tangente !"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def argument(z):\n",
    "    if z.real == 0 and z.imag < 0: return math.pi\n",
    "    else:\n",
    "        return 2 * arctan(z.imag / (z.real + abs(z)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La fonction `log` est alors immédiate."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def log(z):\n",
    "    return ln(abs(z)) + 1j * argument(z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "__Il nous reste à écrire la fonction arc tangente.__"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Élaguons un peu. Soit $x\\in\\mathbb R$. \n",
    "\n",
    "- Si $x<0$, alors $\\arctan x = -\\arctan (-x)$.\n",
    "- Si $x>1$ alors $\\arctan x =\\frac \\pi 2 -\\arctan\\frac 1 x$ (et $0<\\frac 1 x< 1$).\n",
    "\n",
    "Il nous suffit donc de savoir calculer $\\arctan x $ pour $0\\le x \\le 1$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "__Proposition__ : Pour tout $x\\in]-1,1]$,\n",
    "\n",
    "$$\\arctan x =\\sum_{n=0}^\\infty(-1)^n\\frac{x^{2n+1}}{2n+1}$$\n",
    "\n",
    "Ce que nous avons raconté sur le logarithme réel reste valable. Si $x\\in[0,1]$ et que nous approchons $\\arctan x$ par la somme partielle\n",
    "\n",
    "$$\\sum_{k=0}^n(-1)^k\\frac{x^{2k+1}}{2k+1}$$\n",
    "\n",
    "nous obtenons une erreur majorée en valeur absolue par $\\frac{x^{2n+3}}{2n+3}$. Si $x$ est proche de 1, ou, pire, égal à 1, cette erreur est inacceptable. Vite, une solution !\n",
    "\n",
    "__Proposition__ : Soit $x\\in\\mathbb R$. On a\n",
    "\n",
    "$$\\arctan x = 2\\arctan\\frac x {1+\\sqrt {1+x^2}}$$\n",
    "\n",
    "__Démonstration__ : Pour $0\\le t<1$ on a (exercice)\n",
    "\n",
    "$$2\\arctan t= \\arctan\\frac {2t}{1-t^2}$$\n",
    "\n",
    "Soit $t=\\frac x {1+\\sqrt {1+x^2}}$. On a (exercice aussi)\n",
    "\n",
    "$$\\frac{2t}{1-t^2}=x$$\n",
    "\n",
    "d'où le résultat."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Remarquons que si $0\\le x\\le 1$, on a $0\\le t\\le \\frac x 2\\le \\frac 1 2$. Et si l'on pose $u=\\frac t {1+\\sqrt{1+t^2}}$, alors, de même, $0\\le u\\le \\frac 1 4$, et $\\arctan x =2\\arctan t=4\\arctan u$. Avec les notations ci-dessus, quelle valeur de $n$ doit-on prendre pour calculer $\\arctan u$ avec une erreur inférieure à $10^{-17}$ ? "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "n = 0\n",
    "while 4 ** (2 * n + 3) * (2 * n + 3) <= 10 ** 17: n = n + 1\n",
    "print(n)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "12 termes suffiront. Voici donc la fonction `arctan`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def arctan(x):\n",
    "    if x < 0: return - arctan(-x)\n",
    "    elif x > 1: return math.pi / 2 - arctan(1 / x)\n",
    "    else:\n",
    "        t = x / (1 + math.sqrt(1 + x ** 2))\n",
    "        u = t / (1 + math.sqrt(1 + t ** 2))\n",
    "        n = 12\n",
    "        s = 0\n",
    "        sgn = 1\n",
    "        u2 = u * u\n",
    "        for k in range(n + 1):\n",
    "            s = s + sgn * u / (2 * k + 1)\n",
    "            u = u * u2\n",
    "            sgn = - sgn\n",
    "        return 4 * s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 0.9\n",
    "print(arctan(x))\n",
    "print(math.atan(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Maintenant, notre fonction logarithme devrait fonctionner."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z = 1.234 + 5.678 * 1j\n",
    "print(log(z))\n",
    "print(cmath.log(z))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.3 Le graphe"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Après cette ((trop) longue) digression, traçons enfin le graphe du logarithme complexe."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "M = 2\n",
    "plot_complex(lambda z: cmath.log(z), extent=[-M, M, -M, M])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Que voit-on ? \n",
    "\n",
    "- Une racine en 1. Normal, puisque $\\log 1 = 0$. Remarquez le cycle des couleurs. Oui, on peut définir l'ordre de multiplicité d'une racine pour une fonction holomorphe, et nous osons dire que 1 est racine simple de $\\log$.\n",
    "- Une discontinuité sur $\\mathbb R_-^*$. Remarquez le saut des couleurs au passage des réels strictement négatifs.\n",
    "- Un gros souci en 0. Normal puisque $|\\log z|$ tend vers $+\\infty$ lorsque $z$ tend vers 0. A-t-on un pôle, comme pour les fractions rationnelles ? Non, c'est plus grave que cela. Car à gauche de 0 on a en plus de la discontinuité. Nous avons là ce que l'on appelle une __singularité non isolée__, l'extrémité de $\\mathbb R_-$. La demi-droite $\\mathbb R_-$ est appelée une __coupure__ du logarithme."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.4 Autres déterminations du logarithme"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Il existe bien d'autres __déterminations du logarithme__, c'est à dire des fonctions $\\ell$ holomorphes sur une partie de $\\mathbb C$ et telles que $e^{\\ell(z)}=z$. Par exemple, on peut choisir l'argument de $z$ dans $]-\\frac{3\\pi}{2},\\frac \\pi 2]$, auquel cas nous obtiendrons une fonction logarithme holomorphe sur $\\mathbb C$ privé des imaginaires positifs. La voici."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def mylog(z):\n",
    "    t = cmath.phase(z)\n",
    "    if math.pi / 2 < t and t <= math.pi: t = t - 2 * math.pi\n",
    "    return math.log(abs(z)) + 1j * t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "M = 2\n",
    "plot_complex(lambda z: mylog(z), extent=[-M, M, -M, M])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notre nouveau logarithme est holomorphe sur $\\mathbb C$ privé de la demi-droite $i\\mathbb R_+$.\n",
    "\n",
    "\n",
    "On peut hélas montrer qu'il n'existe aucune détermination du logarithme holomorphe sur $\\mathbb C^*$. De façon très générale (et très vague), si $\\Omega$ est un ouvert connexe de $\\mathbb C^*$, il existe une détermination du logarithme holomorphe sur $\\Omega$ si et seulement si on ne peut pas \"faire le tour de $O$\" en restant dans $\\Omega$. Par exemple, si $\\Gamma$ est une \"courbe qui joint $O$ et l'infini\", alors il existe une détermination du logarithme holomorphe sur $\\mathbb C\\setminus\\Gamma$. Un exemple fou ?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.4 Le logarithme fou"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Soit $a>1$. Prenons pour $\\Gamma$ la courbe définie par l'équation polaire $\\rho = a^\\theta$. Plus explicitement, un nombre complexe $z$ appartient à $\\Gamma$ si et seulement si $z=\\rho e^{i\\theta}$ où $\\rho = a^\\theta$.\n",
    "\n",
    "Cette courbe est une spirale qui s'enroule autour de $O$ et \"part à l'infini\". Il doit donc exister un logarithme fou qui est holomorphe sur $\\mathbb C\\setminus \\Gamma$ ! Sans autre commentaire, le voici avec son graphe."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def logfou(z, a):\n",
    "    r = abs(z)\n",
    "    theta = cmath.phase(z)\n",
    "    k = math.floor((math.log(r, a)- theta) / (2 * math.pi))\n",
    "    return math.log(r) + 1j * (theta + 2 * k * math.pi)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "M = 5\n",
    "plot_complex(lambda z: logfou(z, 1.1), extent=[-M, M, -M, M], nx=600, ny=600)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Comment fonctionne ce logarithme ? Partez de la zone violette et tournez en ne coupant jamais la spirale. L'argument de $z$ augmente, augmente indéfiniment, et tend vers $+\\infty$. En fait, sans entrer dans les détails des calculs, $\\arg z$ augmente beaucoup plus vite que $\\ln|z|$. Conséquence, $\\ln|\\ln z|$ tend vers $\\frac \\pi 2$ lorsque $z$ tend vers l'infini en spiralant. Si vous vous demandiez pourquoi tout est vert vers l'extérieur du graphe vous avez la réponse : le vert est la couleur de l'argument $\\frac\\pi 2$. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "__Exercice__ : Pourquoi le centre du dessin est-il violet ?\n",
    "\n",
    "\n",
    "__Exercice__ : Expliquez la fonction `logfou`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Les puissances"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.1 C'est quoi ?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Comment définir $z^\\alpha$ pour $z,\\alpha\\in\\mathbb C$ ?\n",
    "\n",
    "__Définition__ : Pour $z\\in\\mathbb C^*$ et $\\alpha\\in\\mathbb C$ on pose\n",
    "\n",
    "$$z^\\alpha=e^{\\alpha\\log z}$$\n",
    "\n",
    "où $\\log z$ est __un__ logarithme de $z$. De plus, pour $\\alpha\\in\\mathbb R_+^*$ on pose $0^\\alpha=0$ et on pose également $0^0=1$. En revanche, $0^\\alpha$ n'est pas défini si $\\alpha\\in\\mathbb C\\setminus\\mathbb R_+$. Abandonnez donc tout espoir de calculer $0^i$.\n",
    "\n",
    "\n",
    "__Proposition__ : Si $\\log$ est la détermination principale du logarithme, alors $z\\mapsto z^\\alpha$ est holomorphe sur $\\mathbb C\\setminus \\mathbb R_-$. Sa dérivée est la fonction $z\\mapsto \\alpha z^{\\alpha - 1}$.\n",
    "\n",
    "__Démonstration__ : C'est évident, on compose des fonctions holomorphes. La formule de dérivation des composées nous donne une valeur de la dérivée identique à celle que l'on trouve pour les fonctions de variable réelle."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Les puissances complexes vérifient-elles les propriétés \"classiques\" ? Oui pour certaines. En voici une qui fonctionne :\n",
    "\n",
    "$$z^{\\alpha+\\beta}=e^{(\\alpha+\\beta)\\log z}=e^{\\alpha\\log z}e^{\\beta\\log z}=z^\\alpha z^\\beta$$\n",
    "\n",
    "En revanche,\n",
    "\n",
    "$$(zz')^\\alpha=e^{\\alpha(\\log zz')}=e^{\\alpha(\\log z + \\log z' + 2ik\\pi)}=z^\\alpha {z'}^\\alpha e^{2i\\alpha k\\pi}$$\n",
    "\n",
    "où $k\\in\\mathbb Z$ dépend de $z$ et $z'$. Si $\\alpha\\in\\mathbb Z$ alors, oui, $(zz')^\\alpha=z^\\alpha z'^\\alpha$. Sinon, la formule classique est valable pour certains $z,z'$ mais pas pour d'autres."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2 \"La\" racine carrée"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Définissons \"la\" __racine carrée__ de $z$ comme étant $z^{\\frac 1 2}$, c'est à dire $\\exp(\\frac 1 2 \\log z)$. Cette fonction est holomorphe sur $\\mathbb C\\setminus \\mathbb R_-$. Elle est discontinue en tout réel négatif. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(cmath.sqrt(-1))\n",
    "print(cmath.sqrt(-1 - 0.0001 * 1j))\n",
    "print(cmath.sqrt(-1 + 0.0001 * 1j))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Traçons son graphe. Lorsque $z$ tourne autour de $O$, $\\sqrt z$ fait de même, mais deux fois moins vite puisque $\\arg \\sqrt z=\\frac 1 2 \\arg z$. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "M = 4\n",
    "plot_complex(lambda z: z ** (1 / 2), extent=[-M, M, -M, M], m=0.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Que voit-on ? Une discontinuité de la fonction sur $\\mathbb R_-$. Quand l'argument de $z$ passe de 0 à $\\pi$, celui de $z^{1/2}$ va de 0 (rouge) à $\\frac \\pi 2$ (vert). En revanche, quand l'argument de $z$ passe de 0 à $-\\pi$, celui de $z^{1/2}$ va de 0 (rouge) à $-\\frac \\pi 2$ (violet)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "__Exercice__ : Et la fonction racine cubique ? Et $z^{\\frac 2 3}$ ? Expérimentez."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.3 Toujours des racines carrées"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Considérons la fonction $z\\mapsto\\sqrt{z^2-1}$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def f(z): return cmath.sqrt(z ** 2 - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "M = 4\n",
    "plot_complex(f, extent=[-M, M, -M, M])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La fonction $f$ pose \"un problème\" en tout $z$ tel que $z^2-1\\in\\mathbb R_-$, c'est à dire :\n",
    "\n",
    "- Si $z\\in\\mathbb R$ et $-1\\le z \\le 1$, ou alors\n",
    "- Si $z\\in i\\mathbb R$ est imaginaire pur.\n",
    "\n",
    "Peut-on espérer diminuer le nombre de points problématiques, tout en conservant la propriété que $f(z)$ est __une__ racine carrée de $z^2-1$ ? Oui, si on remplece $f(z)$ par $-f(z)$ dans le demi-plan gauche."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def g(z):\n",
    "    w = cmath.sqrt(z ** 2 - 1)\n",
    "    if z.real < 0: return -w\n",
    "    elif z.real == 0 and z.imag > 0: return -w\n",
    "    else: return w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "M = 4\n",
    "plot_complex(g, extent=[-M, M, -M, M])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Quelques couleurs sur un graphique ne sont pas une preuve, mais il semble que nous ayons amélioré la situation. La fonction $g$ est une racine carrée de $z^2-1$ qui est (peut-être ?) holomorphe sur $\\mathbb C\\setminus [-1,1]$. Tentons une autre modification de $f$. Est-il possible de rendre la fonction régulière sur $]-1,1[$ et de repousser les problèmes aux demi-droites $]-\\infty,-1]$ et $[1,+\\infty[$ ? Oui. Considérons la fonction $h$ ci-dessous. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def h(z):\n",
    "    w = cmath.sqrt(z ** 2 - 1)\n",
    "    if z.imag < 0 and z.real > 0: return -w\n",
    "    elif z.imag > 0 and z.real < 0: return -w\n",
    "    else: return w"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Traçons $h$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "M = 4\n",
    "plot_complex(h, extent=[-M, M, -M, M])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Gagné ! Enfin, peut-être. Nos dessins nous suggèrent une probable continuité, mais ils ne prouvent certainement pas l'holomorphie. Souvenez-vous de $h$, elle reviendra au premier plan lorsque nous parlerons de la fonction arc cosinus."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.4 Les puissances bizarres"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tentons $z\\mapsto z ^i$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "M = 1\n",
    "plot_complex(lambda z: z ** 1j, extent=[-M, M, -M, M], m=0.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Cela ne ressemble à rien de ce que nous avions déjà vu. Changeons la valeur de $M$ :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "M = 0.1\n",
    "plot_complex(lambda z: z ** 1j, extent=[-M, M, -M, M], m=0.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Les couleurs ont changé complètement. En fait, les cycles de couleurs n'ont pas lieu, comme nous en avions pris l'habitude, sur des cercles de centre $O$, mais sur des __demi_droites__ passant par $O$. Bigre, qu'est-ce que cela signifie ? Posons $z=re^{i\\theta}$ où $r>0$ et $-\\pi<\\theta\\le\\pi$. On a\n",
    "\n",
    "$$z^i=e^{i\\log z}=e^{i\\ln r-\\theta}=e^{i\\ln r}e^{-\\theta}$$\n",
    "\n",
    "Ainsi, $|z^i|=e^{-\\theta}$ et $\\arg z^i=\\ln r$. Élever à la puissance $i$ intervertit en quelque sorte le module et l'argument. Je vous laisse méditer les conséquences d'une telle chose. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Encore un petit essai, fort intéressant : $z\\mapsto z^{e^{i\\pi / 4}}$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "M = 2\n",
    "plot_complex(lambda z: z ** ((1 + 1j) / math.sqrt(2)), extent=[-M, M, -M, M], m=0.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "__Exercice__ : Trouver une équation des courbes $|f(z)|=cte$. Ce sont des spirales, quel genre de spirales ?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Singularités essentielles"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1 Une fonction au comportement compliqué"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Considérons la fonction $f:z\\mapsto \\exp\\frac 1 z$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "M = 0.5\n",
    "plot_complex(lambda z: cmath.exp(1 / z), extent=[-M, M, -M, M])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La situation en 0 est terriblement compliquée. On ne voit pas des cercles qui \"tournent autour de $O$\". Au contraire :\n",
    "\n",
    "- Concernant les cercles où le module est constant, on en \"voit\" une infinité, ils ont l'air de passer par $O$ et de tous avoir en ce point une tangente verticale.\n",
    "\n",
    "- Il semblerait que nous ayons aussi des cercles où l'argument est constant, on en \"voit\" une infinité, ils ont l'air de passer par $O$ et de tous avoir en ce point une tangente horizontale.\n",
    "\n",
    "Et puis d'ailleurs est-ce que ce sont vraiment des cercles ? Que se passe-t-il exactement en 0 ?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.2 Singularité essentielle"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "__Proposition__ : Soit $f:z\\mapsto e^{1/z}$. Soit $\\varepsilon > 0$. Pour tout nombre complexe $w\\ne 0$, il existe $z\\in\\mathbb C^*$ tel que $|z|\\le\\varepsilon$ et $f(z)=w$.\n",
    "\n",
    "Dit autrement, dans tout voisinage de 0, aussi petit soit-il, la fonction $f$ est une surjection sur $\\mathbb C^*$.\n",
    "\n",
    "__Démonstration__ : Soit $z\\in\\mathbb C^*$. Un calcul très simple montre que $f(z)=w$ si et seulement si $\\frac 1 z=\\ln|w|+i(\\arg w +2k\\pi)$ où $k\\in\\mathbb Z$. Appelons $z_k$ ce nombre. On a \n",
    "\n",
    "$$|z_k|=\\frac 1 {\\sqrt{\\ln^2|w|+(\\arg w + 2k\\pi)^2}}$$ \n",
    "\n",
    "Et on peut rendre cette quantité inférieure à $\\varepsilon$ en prenant $k$ suffisamment grand.\n",
    "\n",
    "Le comportement de $f$ au voisinage de 0 est donc particulièrement compliqué. Nous avons à l'origine ce que l'on appelle une __singularité essentielle__."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.3 Les cercles tangents"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ce que nous avons vu sur le graphe de $f$ est-il bien la réalité ? Montrons-le."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Soit $z=x+iy$. On a\n",
    "\n",
    "$$\\exp(\\frac 1 z)=\\exp\\frac{x-iy}{x^2+y^2}=\\exp\\frac{x}{x^2+y^2}\\exp\\frac{-iy}{x^2+y^2}$$\n",
    "\n",
    "Ainsi, \n",
    "\n",
    "$$|\\exp(\\frac 1 z)|=\\exp\\frac{x}{x^2+y^2}\\quad{\\rm et}\\quad\\arg \\exp(\\frac 1 z)=\\frac{-iy}{x^2+y^2}$$\n",
    "\n",
    "Soit $c>0$. On a $|\\exp(\\frac 1 z)|=c$ si et seulement si $x = \\ln c(x^2+y^2)$. Posant $k=\\frac 1 {\\ln c}$, ceci équivaut à $x^2+y^2-kx=0$, ou encore\n",
    "\n",
    "$$(x-\\frac k 2)^2=y^2=\\frac{k^2} 4$$\n",
    "\n",
    "qui est bien l'équation d'un cercle passant par $O$. Le lecteur consciencieux se convaincra facilement que ce cercle a une tangente verticale en $O$. \n",
    "\n",
    "Calculs totalement analogue pour les courbes $\\arg f(z)=c$, où $c\\in\\mathbb R$. Si $c\\ne 0$, on obtient le cercle d'équation\n",
    "\n",
    "$$x^2+(y+\\frac 1 {2c})^2=\\frac 1 {4c^2}$$\n",
    "\n",
    "Si $c=0$ on obtient l'axe $Ox$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.4 À gauche de l'origine"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Soi t$c>0$ un réel fixé. Soit $\\mathcal U$ l'ensemble des nombres complexes $z=x+iy$ où $x<0$ et $|\\frac y x| \\le c$. De tels $z$ sont des nombres complexes de partie réelle négative dont on astreint l'argument à ne pas trop s'approcher de $\\pm\\frac\\pi 2$. Si vous préférez, $\\mathcal U$ est la partie du demi-plan à gauche de l'axe $Oy$ limitée par deux demi-droites faisant un angle aigu avec $\\mathbb R_-$. On a pour un tel $z$ :\n",
    "\n",
    "$$|f(z)|=\\exp\\frac{x}{x^2+y^2}\\exp\\frac 1 x \\frac 1 {1 + \\frac{y^2}{x^2}}$$\n",
    "\n",
    "On a $1 + \\frac{y^2}{x^2}\\ge k=\\frac 1 {1+c^2}$. Comme $x<0$, on en déduit que\n",
    "\n",
    "$$|f(z)|\\le \\exp\\frac k x$$\n",
    "\n",
    "et le majorant tend vers 0 lorsque $x$ tend vers 0. Ainsi, $f(z)\\to 0$ lorsque $z\\to 0, z\\in\\mathcal U$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.5 À droite de l'origine"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Si vous reprenez les calculs précédents en supposant cette fois que $x>0$ vous obtiendrez que $|f(z)|$ tend vers $+\\infty$. Comportement de $f$ totalement différent, donc, à gauche et à droite de $O$. Ceci ne se voit pas du tout sur le graphique, notre représentation n'est pas suffisante pour détecter ce genre de chose."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.6 L'axe $Oy$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Soit $t\\in\\mathbb R^*$. On a $f(it)=\\exp(-\\frac i t)$. $f(it)$ est donc de module 1, constant. En revanche, l'argument de $f(z)$ est $-\\frac 1 t$. Cet argument tend vers 0 lorsque $t$ tend vers l'infini. En revanche, lorsque $t$ tend vers 0, l'argument de $f(it)$ tend vers l'infini. Il y a donc une infinité de cycles de couleurs sur l'axe $Oy$ dans tout voisinage de $O$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. Et maintenant ?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Passez au notebook numéro 3, nous allons y explorer les fonctions trigonométriques."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
