{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Bibliothèques"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np # manipulation des tableaux\n",
    "from math import *\n",
    "import matplotlib.pyplot as plt # tracé de graphiques"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Manipulations de tableaux numpy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Créations de tableaux"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "A=np.zeros(10) # création d'un tableau de 0  à une dimension, de 10 valeurs\n",
    "B=np.zeros((3,5)) # création d'un tableau de 0 à deux dimensions de 3 lignes (1iere dimension) et 5 colonnes (2è dimension)\n",
    "C=np.ones(5) # création d'un tableau de 1 à une dimension, de 10 valeurs\n",
    "D=np.linspace(1,10,4) # tableau qui contient 4 valeurs régulièrement espacées, entre 1 (inclus) et 10 (inclus)\n",
    "E=np.arange(1,10,2) # tableau des valeurs régulièrement espacées, par pas de 2, entre 1 (inclus) et 10 (exclu)\n",
    "F=np.array([1,5,2,10,20,4]) # conversion de la liste [1,5,2,10,20,4] en tableau numpy\n",
    "print('A=',A)\n",
    "print('B=',B)\n",
    "print('C=',C)\n",
    "print('D=',D)\n",
    "print('E=',E)\n",
    "print('F=',F)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Opérations sur les tableaux"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Récupération de certains éléments"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "D[2] # récupération de l'élément de rang 3 de D"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "F[1:4] # récupération des éléments du tableau du rang 1 inclus au rang 4 exclus"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "F[2:] # récupération des éléments du tableau à partir du rang 1 inclus"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "F[:4] # récupération des éléments du tableau jusqu'au rang 4 exclus (3 inclus)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "B=np.zeros((3,5)) # création d'un tableau de 0 à deux dimensions de 3 lignes (1iere dimension) et 5 colonnes (2è dimension)\n",
    "B[:,0]=[1,2,3] # modification de toutes les lignes  de la colonne 0\n",
    "print(B)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(0,len(B[0])-1):  # len(B[0]) : nbre d'éléments dans la ligne 0 = nbre de colonnes\n",
    "    B[:,i+1]=B[:,i]*2 # la colonne i+1 est égale à 2 fois la colonne i\n",
    "print(B)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "B[0,:] # je récupère toute la ligne 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "B[1:3,1:4] # je récupère les lignes de rangs 1 à 3 exclu, et les colonnes de rangs 1 à 4 exclu"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Sommes, produits, et autres fonctions opérées sur les tableaux"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "CE=C+E # somme terme à terme des éléments de C E\n",
    "print(CE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "np.sqrt(B) # Toutes les fonctions mathématiques usuelles sont disponibles dans le module numpy et s'appliquent à l'ensemble des termes du tableau placé en argument."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "G=np.array([0,pi/4,pi/2,3*pi/4,pi,5*pi/4,3*pi/2,7*pi/4,2*pi])\n",
    "print(G)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "np.cos(G)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "np.sin(G)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Tracé de graphes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Code élémentaire"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x=np.array([7, 10, 9, 4, 6, 1, 0, 8, 3, 5]) # valeurs des abscisses séparées par des virgules\n",
    "y=np.array([6, 0, 8, 7, 3, 4, 0, 4, 10, 8]) # valeurs des ordonnées séparées par des virgules"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "plt.plot(x, y, 'bo',label='nom de la courbe') # Représenter y en fonction de x avec ronds bleus\n",
    "plt.xlabel('légende à adapter') # Légende axe de abscisses\n",
    "plt.ylabel('légende à adapter') # Légende axe des ordonnées\n",
    "plt.title('titre à adapter') # Titre\n",
    "plt.legend() # Afficher la légende (utile si plusieurs courbes sur le même graphique)\n",
    "plt.grid() # Quadrillage\n",
    "plt.show() # Affiche le graphique"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Options\n",
    "plt.plot(x,y,'couleur stylepoint styletrait',paramètres)\n",
    "\n",
    "couleur : première lettre anglaise de la couleur (b, g, y, c, r, m, w ou k pour le noir)\n",
    "\n",
    "style point  x (croix), X (croix pleine), + (plus), P (plus plein), . (pixel), o (rond) , * (étoile), d (carreau)\n",
    "\n",
    "styletrait  - ligne continue, -- (ligne en tiret), :(pointillé),  -. (point tiret), , (pixel) , v (triangle)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "plt.plot(x, y, 'r+--',label='nom de la courbe') # Représenter y en fonction de x avec plus rouge reliés par une ligne pointillés\n",
    "plt.xlabel('légende à adapter') # Légende axe de abscisses\n",
    "plt.ylabel('légende à adapter') # Légende axe des ordonnées\n",
    "plt.title('titre à adapter') # Titre\n",
    "plt.legend() # Afficher la légende (utile si plusieurs courbes sur le même graphique)\n",
    "plt.grid() # Quadrillage\n",
    "plt.show() # Affiche le graphique"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z=[5, 19, 9, 13, 2, 4, 2, 10, 3, 19]\n",
    "plt.plot(x, z, 'yd',label='nom de la courbe1') # Représenter z en fonction de x avec losanges jaunes\n",
    "plt.plot(x, y, 'k+',label='nom de la courbe2') # Représenter y en fonction de x avec + noirs\n",
    "plt.xlabel('légende à adapter') # Légende axe de abscisses\n",
    "plt.ylabel('légende à adapter') # Légende axe des ordonnées\n",
    "plt.title('titre à adapter') # Titre\n",
    "plt.legend() # Afficher la légende (utile si plusieurs courbes sur le même graphique)\n",
    "plt.grid() # Quadrillage\n",
    "plt.show() # Affiche le graphique"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Histogramme"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.hist(x, bins='rice') # Représentation de l'histogramme des valeurs de x, avec optimisation du nombre de classes (rôle de 'rice')\n",
    "plt.title('Histogramme de x')\n",
    "plt.xlabel(\"x (préciser l'unité)\")\n",
    "plt.ylabel('Effectifs')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Fonctions statistiques"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xmoy=np.mean(x) # moyenne des valeurs de x\n",
    "print('Valeur moyenne de x=',xmoy)\n",
    "xet=np.std(x,ddof=1) # écart-type des valeurs de x\n",
    "print('Ecart type de de x=',xet)\n",
    "# Si les mesures x sont issues de mesure, l'incertitude-type s'obtient avec:\n",
    "u_x=xet/sqrt(len(x))\n",
    "print('Incertitude-type sur x :',u_x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Régression linéaire"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Renseigner les grandeurs x et y dans des array au préalable.\n",
    "x=np.array([,,,,])\n",
    "y=np.array([,,,,])\n",
    "\n",
    "# Ajout des barres d'incertitude sur la grandeur portée en y (on suppose celles sur x négligeables)\n",
    "u_y = valeur ou tableau # Incertitude-type sur la grandeur portée en y\n",
    "plt.errorbar(x, y, yerr=u_y, fmt='go') # Tracé du nuage de points en vert avec les barres d'incertitude en y.\n",
    "\n",
    "# Régression linéaire de y en fonction de x (équation y = p[0]*x+p[1])\n",
    "p=np.polyfit(x, y, 1) # 1  : fonction linéaire = polynôme d'ordre 1\n",
    "pente=p[0] # pente de la droite \n",
    "ord_origine=p[1] # ordonnée à l'origine\n",
    "\n",
    "plt.plot(x,np.polyval(p,x)) # Tracé de la droite de régression (p en fonction de x)\n",
    "plt.xlabel('à adapter')\n",
    "plt.ylabel('à adapter')\n",
    "plt.title('à adapter')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Monte-Carlo"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sur une mesure unique"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Supposons que l'on cherche à estimer une grandeur $y$ donnée par $y = f(x_1,x_2,...)$ avec les $x_i$ des données résultants d'une mesure et $f$ une fonction connue.\n",
    "\n",
    "Pour chaque mesure $x_i$ on estime l'intervalle dans lequel il est raisonnable que la mesure s'y trouve : on définit les variables ximin et ximax.\n",
    "\n",
    "La valeur de $y$ est donnée par l'application de la formule. \n",
    "\n",
    "Pour estimer l'incertitude-type sur y, il faut remonter à la variabilité de  $y$, qui est elle-même une conséquence de la variabilité des $x_i$.\n",
    "\n",
    "Simulation Monte-Carlo:\n",
    "- Choisir un nombre $N$ de simulations à réaliser (très grand);\n",
    "- Réaliser $N$ simulations par tirage aléatoire uniformément réparties dans l'intervalle défini précédemment pour les différents grandeurs mesurées xi.\n",
    "- Déterminer les valeurs de $y$ pour chaque expérience.\n",
    "\n",
    "Exploitation\n",
    "- La moyenne des $y_k$ permet de retrouver la valeur $y$.\n",
    "- L'incertitude-type de $y$ est l'écart-type de la distribution des $y_k$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Intervalles estimés expérimentalement de x1 et x2\n",
    "# Valeurs extrêmes de x1\n",
    "x1min=\n",
    "x1max=\n",
    "# Valeurs extrêmes de x2\n",
    "x2min=\n",
    "x2max=\n",
    "\n",
    "# Mise en oeuvre de la simulation Monte-Carlo\n",
    "# Nombre de simulations à effectuer\n",
    "N=\n",
    "# Tableaux des N tirages aléatoires réparties uniformément\n",
    "x1_MC=np.random.uniform(x1min,x1max,N) # tableau de N valeurs aléatoires entre x1min et x1max\n",
    "x2_MC=np.random.uniform(x2min,x2max,N) # tableau de N valeurs aléatoires entre x2min et x2max\n",
    "# Tableaux des N résultats par application de la formule exprimant y en fonction de x1 et x2\n",
    "y_MC=x1_MC*x2_MC # (si y=x1*x2)\n",
    "\n",
    "# Expoitation : \n",
    "# Valeur de y \n",
    "y=np.mean(y_MC)\n",
    "# Incertitude-type sur y :\n",
    "u_y=np.std(y_MC,ddof=1)\n",
    "# Résultat : \n",
    "print('y=',y,'u_y=',u_y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sur une régression linéaire"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Supposons que l'on cherche à vérifier un modèle $y = ax + b$ et que l'on ait, après expérience, un ensemble de valeurs expérimentales $\\{x_i\\}$ et $\\{y_i\\}$ qui possèdent chacun une certaine variabilité. La régression linéaire simple permet, à partir de l'ensemble des points expérimentaux, de trouver UNE valeur de $a$ et UNE valeur de $b$. \n",
    "\n",
    "Pour estimer l'incertitude-type de ces paramètres, il faut réaliser des ensembles de nouvelles mesures $\\{x_i\\}$ et $\\{y_i\\}$ puis réaliser une nouvelle régression linéaire. En réalisant un grand nombre de fois cette opération, on obtiendra, en prenant les écarts-types, les valeurs des incertitudes-types sur les paramètres. On utilise pour cela la méthode de Monte-Carlo."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Mesures effectuées\n",
    "x=np.array([ , , , , , ])       # séries de mesures de x\n",
    "y=np.array([ , , , , , ])       # séries de mesures de y\n",
    "Delta_x=np.array([ , , , , , ]) # demi-largeur des intervalles de x\n",
    "Delta_y=np.array([ , , , , , ]) # demi-largeur des intervalles de y\n",
    "\n",
    "N=     # nombre d'expériences simulées\n",
    "liste_a_MC=[] # liste des N pentes déterminées par régression linéaire\n",
    "liste_b_MC=[] # liste des N ordonnées à l'origine déterminées par régression linéaire \n",
    "\n",
    "# On simule N expériences similaires à celle effectuée précédemment\n",
    "for k in range(N):\n",
    "    L_xk=[] # kieme série de mesures de x\n",
    "    L_yk=[] #  kieme série de mesures de y\n",
    "    for i in range(len(x)):\n",
    "        # pour chaque valeur de x et y précédente on génère une valeur\n",
    "        # aléatoire dans l'intervalle [x-Delta_x,x+Delta_x],\n",
    "        # et dans l'intervalle  [y-Delta_y,y+Delta_y] \n",
    "        x_k=np.random.uniform(x[i]-Delta_x[i],x[i]+Delta_x[i]) # une valeur de x générée aléatoirement\n",
    "        y_k=np.random.uniform(y[i]-Delta_y[i],y[i]+Delta_y[i]) # une valeur de y générée aléatoirement\n",
    "        L_xk.append(x_k)\n",
    "        L_yk.append(y_k)\n",
    "    # on détermine pour l'expérience k simulée, la régression linéaire\n",
    "    reg_k=np.polyfit(L_xk,L_yk,1)\n",
    "    a_k=reg_k[0] # pente de l'expérience simulée k\n",
    "    b_k=reg_k[1] # ordonnée à l'origine de l'expérience simulée k\n",
    "    # on ajoute ces résultats aux listes\n",
    "    liste_a_MC.append(a_k)\n",
    "    liste_b_MC.append(b_k)\n",
    "\n",
    "# Valeurs moyennes des N valeurs générées de a et b\n",
    "a_moy=np.mean(liste_a_MC)\n",
    "b_moy=np.mean(liste_b_MC)\n",
    "# Incertitudes-types sur a et b (=écarts-types des N valeurs générées)\n",
    "u_a=np.std(liste_a_MC,ddof=1)\n",
    "u_b=np.std(liste_b_MC,ddof=1)"
   ]
  }
 ],
 "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.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
