{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "3a1f6948",
   "metadata": {},
   "source": [
    "# Feuille d'exercices 10\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "```{admonition} Objectifs\n",
    "* Variables aléatoires\n",
    "* Statistiques\n",
    "```\n",
    "\n",
    "\n",
    "\n",
    "## Exercice 1 : variable aléatoire discrète\n",
    "\n",
    "**Question 1 :** Créer une variable aléatoire discrète `X` de distribution :\n",
    "\n",
    "$$\n",
    "    (0.4, 0.3, 0.2, 0.1)\n",
    "$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4f5de64c",
   "metadata": {},
   "outputs": [],
   "source": [
    "X = GeneralDiscreteDistribution([0.4, 0.3, 0.2, 0.1])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7928e15d",
   "metadata": {},
   "source": [
    "**Question 2 :** Tirer aléatoirement $10000$ valeurs selon $X$, et stocker ces valeurs dans une liste `L`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "57f33cee",
   "metadata": {},
   "outputs": [],
   "source": [
    "L = [ X.get_random_element() for _ in range(10000) ]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1e50a43e",
   "metadata": {},
   "source": [
    "La méthode de liste `L.count(i)` permet de compter le nombre d'occurences de l'élément `i` dans le liste `L`.\n",
    "\n",
    "**Question 3 :** Dans une liste `B`, stocker à la position `i`  le nombre d'occurences de `i` dans la liste `L` créée à la question précédente."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "de475300",
   "metadata": {},
   "outputs": [],
   "source": [
    "B = [ L.count(i) for i in range(4) ]\n",
    "print(B)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eb963248",
   "metadata": {},
   "source": [
    "**Question 4 :** Visualiser la liste `B` sous forme de diagramme à barre, avec la fonction `bar_chart(B, ymin=0)`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "da607927",
   "metadata": {},
   "outputs": [],
   "source": [
    "bar_chart(B, ymin=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "437b91d2",
   "metadata": {},
   "source": [
    "## Exercice 2 : variable aléatoire continue\n",
    "\n",
    "\n",
    "**Question 1 :** Créer une variable aléatoire $G$ de distribution gaussienne et de variance $\\sigma = 1$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "591dba81",
   "metadata": {},
   "outputs": [],
   "source": [
    "sigma = 1\n",
    "G = RealDistribution(\"gaussian\", sigma)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1d48d82",
   "metadata": {},
   "source": [
    "**Question 2 :** Tirer aléatoirement $10000$ valeurs selon $G$, et stocker ces valeurs dans une liste `M`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "46d303b5",
   "metadata": {},
   "outputs": [],
   "source": [
    "M = [ G.get_random_element() for _ in range(10000) ]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "642438f3",
   "metadata": {},
   "source": [
    "**Question 3 :** Calculer la moyenne de ces $10000$ valeurs, puis comparer à la valeur espérée ($0$)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b5bf5a61",
   "metadata": {},
   "outputs": [],
   "source": [
    "moyenne = sum(M)/10000\n",
    "print(moyenne)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0261f745",
   "metadata": {},
   "source": [
    "**Question 4 :** Calculer une approximation de l'écart-type de ces $10000$ valeurs :\n",
    "\n",
    "$$\n",
    "\\sqrt{\\frac{1}{10000} \\sum_{i=0}^{9999} M_i^2}\n",
    "$$\n",
    "\n",
    "puis comparer à la valeur espérée ($\\sqrt{\\sigma} = 1$)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fe70fbf2",
   "metadata": {},
   "outputs": [],
   "source": [
    "ecart = sqrt(sum([m**2 for m in M])/10000)\n",
    "print(ecart)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "38b0a718",
   "metadata": {},
   "source": [
    "## Exercice 3 : approximation de $\\pi$\n",
    "\n",
    "**Question 1 :** Écrire une fonction `interieur_disque(x, y)` qui teste si un point de coordonnées $(x,y)$ est à l'intérieur du cercle de centre $(0, 0)$ et de rayon $1$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dea5ccbf",
   "metadata": {},
   "outputs": [],
   "source": [
    "def interieur_disque(x, y):\n",
    "    return x**2 + y**2 <= 1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "319f5945",
   "metadata": {},
   "source": [
    "**Question 2 :** Écrire une fonction `tirages_carre(N)` qui retourne une liste de $N$ points $(x, y)$, tirés uniformément dans $[-1, 1]^2$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "888b5a02",
   "metadata": {},
   "outputs": [],
   "source": [
    "def tirages_carre(N):\n",
    "    n = 0\n",
    "    res = []\n",
    "    for i in range(N):\n",
    "        x = uniform(-1, 1)\n",
    "        y = uniform(-1, 1)\n",
    "        res.append([x,y])\n",
    "    return res"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d2c07cc7",
   "metadata": {},
   "source": [
    "**Question 3 :** Afficher sur un même grahique le cercle unité (en bleu) et $100$ points tirés selon la méthode de la question pérécedente (en rouge).\n",
    "\n",
    "*Indication : pour afficher un cercle, on peut utiliser la fonction `circle(P, r)`, qui crée un cercle de centre `P` (un point du plan sous la forme d'une liste de ses deux coordonnées) et de rayon `r` (une valeur positive).*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eac2f38f",
   "metadata": {},
   "outputs": [],
   "source": [
    "T = tirages_carre(100)\n",
    "circle([0,0], 1) + points(T, aspect_ratio=1, color='red')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c24f8cd",
   "metadata": {},
   "source": [
    "Pour de grandes valeurs de $N$, le rapport $r = \\frac{N_{\\rm in}}{N}$ entre le nombre de tirages à l'intérieur du disque et le nombre de tirages total, tend vers le rapport $a = \\frac{{\\rm aire(disque)}}{{\\rm aire(carré)}}$ des aires du disque et du carré $[-1, 1]^2$.\n",
    "\n",
    "**Question 4 :** Déduire de la remarque précédente une approximation de $\\pi$, en tirant $10000$ points."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8d9df4ee",
   "metadata": {},
   "outputs": [],
   "source": [
    "N = 10000\n",
    "T = tirages_carre(N)\n",
    "\n",
    "cpt = 0\n",
    "for point in T:\n",
    "    if interieur_disque(point[0], point[1]):\n",
    "        cpt += 1\n",
    "print(4*float(cpt)/N)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "98aee550",
   "metadata": {},
   "source": [
    "## Exercice 4 : fougère de Barnsley\n",
    "\n",
    "Le but de cet exercice est de produire la **fractale** appelée \"fougère de Barnsley\", référence [ici](https://fr.wikipedia.org/wiki/Foug%C3%A8re_de_Barnsley).\n",
    "\n",
    "Pour construire cette fractale, on considère $4$ matrices $M_1$, $M_2$, $M_3$, $M_4$ et $4$ vecteurs $b_1$, $b_2$, $b_3$ et $b_4$ :\n",
    "\n",
    "$$\n",
    "M_1 = \\begin{pmatrix} 0 & 0 \\\\ 0 & 0.16 \\end{pmatrix},\\quad \n",
    "M_2 = \\begin{pmatrix} 0.8 &  0.04 \\\\-0.04 & 0.85 \\end{pmatrix},\\quad \n",
    "M_3 = \\begin{pmatrix} 0.2 & -0.26 \\\\ 0.23 &  0.22 \\end{pmatrix},\\quad \n",
    "M_4 = \\begin{pmatrix} -0.15 & 0.28 \\\\ 0.26 & 0.24 \\end{pmatrix}\n",
    "$$\n",
    "\n",
    "$$\n",
    "b_1 = \\begin{pmatrix} 0 \\\\ 0\\end{pmatrix},\\quad \n",
    "b_2 = \\begin{pmatrix} 0 \\\\ 1.6 \\end{pmatrix},\\quad \n",
    "b_3 = \\begin{pmatrix} 0 \\\\ 1.6 \\end{pmatrix},\\quad \n",
    "b_4 = \\begin{pmatrix} 0 \\\\ 0.44 \\end{pmatrix}\n",
    "$$\n",
    "\n",
    "Cette fractale est produite de la manière suivante :\n",
    "- on part du point initial $P_0 = (x_0, y_0) = (0, 0)$\n",
    "- puis, pour tout $n$, le point $P_n$ est construit en fonction de $P_{n-1}$ avec un processus aléatoire :\n",
    "  - avec probabilité $0.01$, on a $P_n = M_1 P_{n-1} + b_1$\n",
    "  - avec probabilité $0.85$, on a $P_n = M_2 P_{n-1} + b_2$\n",
    "  - avec probabilité $0.07$, on a $P_n = M_3 P_{n-1} + b_3$\n",
    "  - avec probabilité $0.07$, on a $P_n = M_4 P_{n-1} + b_4$\n",
    "  \n",
    "Pour un entier $N$ fixé, la fractale de Barnsley de taille $N$ correspond à l'ensemble des points $P_0, \\dots, P_{N-1}$ ainsi construits.\n",
    "\n",
    "Voici la fractale voulue (avec $250000$ points).\n",
    "\n",
    "\n",
    "\n",
    "```{image} ../../images/fougere.png\n",
    ":alt: fougere\n",
    ":width: 60%\n",
    ":align: center\n",
    "```\n",
    "\n",
    "\n",
    "\n",
    "**Question.** Construire une fonction `fougere(N)` qui construit la liste des points de la fractale de Barnsley de taille $N$.\n",
    "\n",
    "Puis, afficher cette fractale pour $N = 1000$, $N = 10000$ et si possible, $N= 100000$. Pour l'affichage, on utilisera un nuage de points verts de taille `size=2` ou `size=1`, et on enlèvera les axes de la figure avec l'option `axes=False`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b8c9f716",
   "metadata": {},
   "outputs": [],
   "source": [
    "def fougere(N=10000, mysize=1, mycolor=\"green\"):\n",
    "\n",
    "    M1 = matrix(2, 2, [0., 0., 0., 0.16])\n",
    "    M2 = matrix(2, 2, [0.85, 0.04, -0.04, 0.85]) # 0.85\n",
    "    M3 = matrix(2, 2, [0.2, -0.26, 0.23, 0.22]) # 0.20\n",
    "    M4 = matrix(2, 2, [-0.15, 0.28, 0.26, 0.24])\n",
    "\n",
    "    b1 = vector([0., 0.])\n",
    "    b2 = vector([0., 1.60])\n",
    "    b3 = vector([0., 1.60])\n",
    "    b4 = vector([0., 0.44])\n",
    "\n",
    "    P = vector([0, 0])\n",
    "\n",
    "    L = [P]\n",
    "\n",
    "    for i in range(N):\n",
    "        r = randint(0,99)\n",
    "        if r < 1:\n",
    "            P = M1*P + b1\n",
    "        elif r < 86:\n",
    "            P = M2*P + b2\n",
    "        elif r < 93:\n",
    "            P = M3*P + b3\n",
    "        else:\n",
    "            P = M4*P + b4\n",
    "        L.append(P)\n",
    "    return points(L, axes=False, size=mysize, color=mycolor)\n",
    "    \n",
    "fougere(1000).show()\n",
    "fougere(10000).show()\n",
    "fougere(100000).show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Sagemath",
   "language": "python",
   "name": "sagemath"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
