{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "c56b5b66",
   "metadata": {},
   "source": [
    "# Feuille d'exercices 6\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "```{admonition} Objectifs\n",
    "* Nombres réels\n",
    "* Notion de précision\n",
    "* Affichage graphique\n",
    "```\n",
    "\n",
    "## Exercice 1. Manipulation de nombre flottant avec une précision donnée\n",
    "\n",
    "\n",
    "**Question 1 :** Effectuer successivement les instructions suivantes.\n",
    "1. Stocker dans une variable `x` le rationnel $1/7$.\n",
    "1. Stocker dans une variable `R1` le corps des réels à une précision de $1$ bit.\n",
    "1. Quelle puissance de $2$  (éventuellement d'exposant négatif) est la plus proche de $1/7$ ? Effectuer une coercion de `x` dans `R1`, puis vérifier votre réponse.\n",
    "1. Stocker dans une variable `R3` le corps des réels à une précision de $3$ bits.\n",
    "1. Effectuer une coercion de `x` dans `R3`, puis retrouver la mantisse et l'exposant correspondant. On pourra également s'aider de la méthode `.sign_mantissa_exponent()`.\n",
    "1. En effectuant une coercion de `x` dans une structure appropriée, donner les $100$ premières décimales de $1/7$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9fde054b",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 1/7\n",
    "R1 = RealField(1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c3a6e6ab",
   "metadata": {},
   "source": [
    "La puissance de $2$ la plus proche de $1/7$ est $2^{-3} = 1/8$. Vérifions-le :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "604255ff",
   "metadata": {},
   "outputs": [],
   "source": [
    "R1(x) == 1/8"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8478b9dd",
   "metadata": {},
   "outputs": [],
   "source": [
    "R3 = RealField(3)\n",
    "y = R3(x)\n",
    "y.sign_mantissa_exponent()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "46f44b14",
   "metadata": {},
   "source": [
    "La mantisse vaut $5$ et l'exposant $-5$. En effet, le nombre représenté sur $3$ bits le plus proche de $17$ est $\\frac{5}{32} = 2^{-3} + 2^{-5} = 5 \\times 2^{-5}$. On le vérifie une nouvelle fois :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a7c9de6c",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(y)\n",
    "print(y == 5/32)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9ca5f646",
   "metadata": {},
   "source": [
    "Enfin, les $100$ premières décimales de $1/7$ sont :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "56b6e32e",
   "metadata": {},
   "outputs": [],
   "source": [
    "nombres_bits = ceil(100*log(10,2))\n",
    "print(RealField(nombres_bits)(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "74934e6d",
   "metadata": {},
   "source": [
    "## Exercice 2. Affichage graphique simple\n",
    "\n",
    "**Question 1 :** Tracer sur un même graphique les fonctions cosinus (en bleu) et sinus (en rouge), entre $0$ et $4\\pi$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c0cee16c",
   "metadata": {},
   "outputs": [],
   "source": [
    "plot(cos, [0, 4*pi], color=\"blue\") +  plot(sin, [0, 4*pi], color=\"red\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f23fdce8",
   "metadata": {},
   "source": [
    "**Question 2 :** \n",
    "- Tracer la fonction tangente entre $-\\pi$ et $\\pi$.\n",
    "- Puis, essayer de rendre le tracé plus \"représentatif\" en imposant une valeur maximale et minimale à l'ordonnée.\n",
    "- Pourquoi pensez-vous qu'il y a des droites verticales ? Les retirer en ajoutant l'argument optionnel `detect_poles=True` dans la fonction `plot()`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "33aef7fc",
   "metadata": {},
   "outputs": [],
   "source": [
    "plot(tan, [-pi, pi])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dc6b8fae",
   "metadata": {},
   "outputs": [],
   "source": [
    "plot(tan, [-pi, pi], ymax = 10, ymin = -10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5b41e622",
   "metadata": {},
   "outputs": [],
   "source": [
    "plot(tan, [-pi, pi], ymax = 10, ymin = -10, detect_poles=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe4e373d",
   "metadata": {},
   "source": [
    "## Exercice 3. Série harmonique\n",
    "\n",
    "On considère la suite $(H_n)_{n \\ge 1}$ définie comme : $H_n = \\sum_{i=1}^n \\frac{1}{n}$. Cette suite est appelée \"série harmonique\".\n",
    "\n",
    "**Question 1 :** Écrire une fonction `calcule_H(n)` qui prend en entrée un entier naturel `n` et qui retourne le terme $H_n$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7e17b0cc",
   "metadata": {},
   "outputs": [],
   "source": [
    "def H(n):\n",
    "    res = 0\n",
    "    for i in range(1, n+1):\n",
    "        res += 1/i\n",
    "    return res\n",
    "    \n",
    "print(H(3))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6d80b88d",
   "metadata": {},
   "source": [
    "**Question 2 :** Tracer sur un même graphique :\n",
    "- les $100$ premiers termes de la suite $H_n$,\n",
    "- la fonction $\\ln(x)$ pour $x \\in [1, 100]$.\n",
    "\n",
    "Pour tracer les termes de la série harmonique, on rappelle qu'on peut utiliser la fonction `points(L)` qui prend en entrée une liste de points de la forme $[ (x_1, y_1), \\dots, (x_k, y_k) ]$ , et qui retourne un objet graphique (comme le ferait `plot`) représentant tous les points de coordoonées $(x_i, y_i)$ de la liste."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0801dd4b",
   "metadata": {},
   "outputs": [],
   "source": [
    "points([[i, H(i)] for i in range(100)]) + plot(ln, [1, 100], color=\"red\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "136f4546",
   "metadata": {},
   "source": [
    "**Question 3 :** La différence $H_n - \\ln(n)$ semble converger vers une constante. La calculer approximativement. Pour cela, on pourra calculer des termes de $u_n := H_n - \\ln(n)$ jusqu'à ce que deux termes consécutifs de la suite $(u_n)$ soit distants de moins de $10^{-8}$.\n",
    "\n",
    "*Indication supplémentaire :* comme la convergence est lente, on pourra essayer de :\n",
    "- reformuler la valeur de $u_{n+1}-u_n$ pour éviter de calculer des sommes\n",
    "- calculer les $u_{n+1}-u_n$ avec des ordre $n$ allant de $100$ en $100$ plutôt que de $1$ et $1$\n",
    "\n",
    "Puis, comparer la valeur obtenue à l'objet `euler_gamma` de Sagemath."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2766ae4d",
   "metadata": {},
   "outputs": [],
   "source": [
    "def calcule_constante():\n",
    "    n = 2\n",
    "    eps = 10**(-8)\n",
    "    e = 1\n",
    "    while abs(e) > eps :\n",
    "        # e = H(n) - ln(n) - H(n-1) + ln(n-1) \n",
    "        e = 1/n - ln(n/(n-1))\n",
    "        n += 1\n",
    "    print(\"n =\", n)\n",
    "    return H(n)-ln(n)\n",
    "\n",
    "g = calcule_constante()\n",
    "print(float(g))\n",
    "print(float(euler_gamma))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bdb28ad9",
   "metadata": {},
   "source": [
    "## Exercice 4. Produit de Wallis et une mauvaise approximation rationnelle de $\\pi$\n",
    "\n",
    "En 1656, Wallis a démontré que \n",
    "\n",
    "$$\n",
    "    \\frac{\\pi}{2} = \\prod_{n=1}^\\infty \\frac{4n^2}{4n^2-1}.\n",
    "$$\n",
    "\n",
    "Nous allons utiliser cette formule pour obtenir une approximation rationnelle (mais peu efficace) de $\\pi$.\n",
    "\n",
    "**Question 1 :** Écrire une fonction `produit_wallis(k)` qui prend en entrée un entier strictement positif `k`, et qui retourne le produit \n",
    "\n",
    "$$\n",
    "P_k := \\prod_{n=1}^k \\frac{4n^2}{4n^2-1}.\n",
    "$$\n",
    "\n",
    "Vérifier ensuite que $P_1 = \\frac{4}{3}$ et que $P_6 = \\frac{1048576}{693693}$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "abf93a07",
   "metadata": {},
   "outputs": [],
   "source": [
    "def produit_wallis(k):\n",
    "    res = 1\n",
    "    for n in range(1, k+1):\n",
    "        res *= (4*n**2)/(4*n**2-1)\n",
    "    return res\n",
    "\n",
    "print(produit_wallis(1))\n",
    "print(produit_wallis(6))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7c5b04a3",
   "metadata": {},
   "source": [
    "**Question 2 :** Afficher le nombre flottant associé à $2 P_{100}$, puis vérifier qu'il a au moins une décimale en commun avec $\\pi$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c61bc769",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(RealField()(2*produit_wallis(100)))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "41eda19b",
   "metadata": {},
   "source": [
    "**Question 3 :**  Quelle est la plus petite valeur de $k$ pour laquelle les nombres $2 P_k$ et $\\pi$ ont au moins $3$ décimales en commun ? Quel est alors le nombre de chiffres du dénominateur $d$ de la fraction  $2 P_k$ (calculer la partie entière supérieure de $\\log_{10}(d)$ pour obtenir cela) ?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e2e15ae9",
   "metadata": {},
   "outputs": [],
   "source": [
    "k = 1\n",
    "w = produit_wallis(k)\n",
    "while abs(pi - 2*w) > 10**(-3):\n",
    "    k += 1\n",
    "    w = produit_wallis(k)\n",
    "print(k)\n",
    "print(\"Le dénominateur a\", ceil(log(w.denominator(), 10)), \"chiffres décimaux\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9cc5d5bb",
   "metadata": {},
   "source": [
    "**Remarque :** on peut s'épargner des calculs répétés avec les instructions suivantes :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6d7959db",
   "metadata": {},
   "outputs": [],
   "source": [
    "k = 0\n",
    "w = 1\n",
    "seuil = 10**(-3)\n",
    "while abs(pi - 2*w) > seuil:\n",
    "    k += 1\n",
    "    t = 4*k**2\n",
    "    w *= t/(t-1)\n",
    "print(k)\n",
    "print(\"Le dénominateur a\", ceil(log(w.denominator(), 10)), \"chiffres décimaux\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dd951fee",
   "metadata": {},
   "source": [
    "**Remarque :** Cette manière de calculer les décimales de $\\pi$ est donc très peu efficace."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Sagemath",
   "language": "python",
   "name": "sagemath"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
