{"cells":[{"cell_type":"markdown","metadata":{},"source":"Variabilité\n===========\n\n**Date:** vendredi 8 septembre 2023\n\n"},{"cell_type":"markdown","metadata":{},"source":["## Capacité numérique:\n\n"]},{"cell_type":"markdown","metadata":{},"source":["

\nSimuler, à l’aide d’un langage de programmation ou d’un tableur,
\nun processus aléatoire permettant de caractériser la variabilité
\nde la valeur d’une grandeur composée
\n

\n\n"]},{"cell_type":"markdown","metadata":{},"source":["## Outils\n\n"]},{"cell_type":"markdown","metadata":{},"source":["On rappelle quelques bases fondamentales pour l'utilisation de python\nen sciences physiques. En préambule, rappelons que `python` utilise\ndes règles d'**indentation** strictes.\n\n"]},{"cell_type":"markdown","metadata":{},"source":["### Modules\n\n"]},{"cell_type":"markdown","metadata":{},"source":["On aura besoin de charger des bibliothèques nommées `modules` pour\naccéder à certaines fonctions.\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[],"source":["import math"]},{"cell_type":"markdown","metadata":{},"source":["Les fonctions qu'elle apporte seront appelées par `math.nom_de_la_fonction`\n\n"]},{"cell_type":"markdown","metadata":{},"source":["### Variables et affectation\n\n"]},{"cell_type":"markdown","metadata":{},"source":["On peut manipuler des entiers, des flottants, sur lesquels on peut\nutiliser les opérations usuelles et qu'on affecte à des variables par\n`=`. La structure avec `f'` permet par exemple de former une chaîne de\ncaractères utilisant les valeurs des variables.\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[],"source":["a = 2\nb,c = 3,5\nd = a + b\nprint(d, a + c)\nprint(f'la valeur de d est: {d}')\nprint(f'le quotient par / de deux entiers est un flottant \"d/2\": {d/2}')\nprint(f'la division euclidienne est obtenue par \"d//2\": {d//2}')\nprint(f'son reste est obtenu par \"d%2\": {d%2}')\nprint(f'on élève à une puissance en utilisant \"pow\" ou \"**\": {pow(a,4)} ou {a**5}')\n\nprint(f'on peut préciser l\\'approximation décimale des flottants: ln(12) = {math.log(12):.3f}')\nprint(f'on utilise une notation scientifique avec \".2e\" = {math.log(12):.2e}')"]},{"cell_type":"markdown","metadata":{},"source":["Sur les chaînes de caractères, on utilisera par exemples les\nopérations suivantes:\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[],"source":["a = \"bonjour\"\nb = \" \"\nc = \"la HX2\"\nprint(f'\"+\" désigne la concaténation: {a+b+c}')\nprint(f'\"*\" n désigne la répétition n fois: {a*5}')"]},{"cell_type":"markdown","metadata":{},"source":["### Listes et slicing\n\n"]},{"cell_type":"markdown","metadata":{},"source":["On manipulera souvent des listes de variables, de types\nvariables. Comme tous les objets en `python`, elles possèdent des\n`méthodes` accessibles par la notation `objet.methode`:\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[],"source":["a = \"bonjour\"\nb = 3.5\nc = 2\nliste = [a,b]\nliste.append(c)\nprint(f'on accède à un élément de position donnée par liste[0]: \"{liste[0]}')\nprint(f'liste[-1] désigne le dernier élément: \"{liste[2]}')\nprint(f'les opérateurs + et * n joignent ou dupliquent les éléments d\\'une liste:{liste+liste, 3*liste}')\nprint(f'le nombre d\\'éléments est donné par \"len\": {len(liste)}')"]},{"cell_type":"markdown","metadata":{},"source":["On peut former des listes en utilisant des boucles `for`, des\nconditions `if`.\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":"[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]"}],"source":["autre_liste = [3*i for i in range(10) if 2*i<19]\nprint(autre_liste)"]},{"cell_type":"markdown","metadata":{},"source":["On peut «trancher» les listes (slice en anglais) pour n'en prendre que\ncertains éléments en choisissant le premier, le dernier, et\nl'incrément.\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[],"source":["print(f'un élément sur deux entre le deuxième et le septième: {autre_liste[1:6:2]}')\nprint(f'un élément sur trois entre le premier et l\\'avant dernier: {autre_liste[:-2:3]}')\nprint(f'tous les éléments supérieurs à 13: {[ i for i in autre_liste if i > 13]}')"]},{"cell_type":"markdown","metadata":{},"source":["### Numpy\n\n"]},{"cell_type":"markdown","metadata":{},"source":["Pour manipuler des données numériques, tracer des courbes, on\nutilisera un type de liste particulier, les `numpy.array` facilitant\nles manipulations d'un grand nombre de données en parallèle. On en\nfait ici un alias `np` plus court à écrire.\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[],"source":["import numpy as np\n\nabscisses = np.array(range(10))\nordonnees = abscisses + 2\nordonnees2 = abscisses *2\nordonnees3 = abscisses * abscisses\nordonnees4 = np.sqrt(abscisses)\nprint(f'les opérateurs usuels comme \"+,*\" s\\'appliquent à chacun des éléments de la liste: {ordonnees}' )\nprint(ordonnees4[-1],ordonnees3[2],ordonnees2[0])"]},{"cell_type":"markdown","metadata":{},"source":["### Fonctions et boucles\n\n"]},{"cell_type":"markdown","metadata":{},"source":["On définit des fonctions avec `def`, le corps de la fonction doit\nensuite être indenté de 4 espaces, tout comme les éléments des\nboucles et structures conditionnelles.\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[],"source":["def ma_fonction(ma_variable):\n seuil = 8\n if ma_variable > seuil:\n return ma_variable\n else:\n print(\"trop petit\")\n return seuil\nprint(ma_fonction(12))\nprint(ma_fonction(5))"]},{"cell_type":"markdown","metadata":{},"source":["### Courbes\n\n"]},{"cell_type":"markdown","metadata":{},"source":["Le module `matplotlib` permet de tracer des ensembles de points: on\nutilisera le plus souvent des `np.array` pour les abscisses et les\nordonnées. La méthode `np.linspace` permet d'utiliser un grand nombre\nde points d'abscisses, uniformément répartis dans un intervalle.\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[],"source":["import matplotlib.pyplot as plt\nxmin = 0\nxmax = 12\nNpoints = 200\nAbscissesII = np.linspace(xmin,xmax,Npoints)\nOrdonneesII = np.power(AbscissesII,3)\nOrdonneesIII = np.power(AbscissesII,.5)\n\nfig,(axeII,axeIII) = plt.subplots(2,1) # pour organiser plusieurs graphes sur unemême figure \naxeII.plot(AbscissesII,OrdonneesII,label=\"cube\")\naxeII.legend()\naxeIII.plot(AbscissesII,OrdonneesIII,label=\"racine\")\naxeIII.legend()\nfig.suptitle(\"Ceci est un titre\")\naxeII.set_xlabel(\"abscisses\")\naxeII.set_xlabel(None)\naxeIII.set_xlabel(\"abscisses\")\naxeII.set_ylabel(\"ordonnees\")\naxeIII.set_ylabel(\"ordonnees\")"]},{"cell_type":"markdown","metadata":{},"source":["On pourra consulter [https://matplotlib.org/cheatsheets/>](https://matplotlib.org/cheatsheets/>)pour plus de\nprécisions.\n\n"]},{"cell_type":"markdown","metadata":{},"source":["## Chute libre\n\n"]},{"cell_type":"markdown","metadata":{},"source":["### Dispositif expérimental\n\n"]},{"cell_type":"markdown","metadata":{},"source":["On cherche à mesurer l'accélération de la pesanteur $g$ en étudiant la\nchute libre d'un corps dans le vide. Le dispositif consiste en:\n\n- un objet de masse $m$ en chute libre dans le vide;\n- est lâché sans vitesse initiale d'une altitude $h_1$;\n- sa vitesse $v$ est mesurée par un capteur spécifique quand il passe\n en un point d'altitude $h_2 < h_1$.\n\n"]},{"cell_type":"markdown","metadata":{},"source":["### Modèle\n\n"]},{"cell_type":"markdown","metadata":{},"source":["Montrer qu'on a:\n\n\\begin{equation*}\nv^2 = 2 g (h_1 -h_2)\n\\end{equation*}\n\n"]},{"cell_type":"markdown","metadata":{},"source":["### Incertitudes\n\n"]},{"cell_type":"markdown","metadata":{},"source":["On cherche à observer l'effet sur l'incertitude sur la mesure de $g$ des\nsources d'incertitude suivantes:\n\n- incertitude sur les lectures des altitudes $h_1$ et $h_2$ sur une règle;\n\n- incertitude sur la mesure de la vitesse par un capteur.\n\nOn **simule** ici numériquement les répartitions des valeurs mesurées\npour ces grandeurs si on reproduisait un grand nombre de fois la\nmanipulation, en supposant connue la loi de répartition des erreurs.\n\n"]},{"cell_type":"markdown","metadata":{},"source":["#### Lecture des altitudes sur une règle\n\n"]},{"cell_type":"markdown","metadata":{},"source":["On suppose une répartition uniforme d'erreurs entre deux graduations\nde la règle distantes de $\\Delta h$.\n\nOn rappelle que l'incertitude-type vaut alors:\n\n\\begin{equation*}\n \\Delta h/(2 \\sqrt{3})\n\\end{equation*}\n\nOn utilisera la fonction `random.random_sample` pour tirer un nombre\nflottant aléatoire correspondant à une altitude lue entre deux\ngraduations de la règle.\n\n"]},{"cell_type":"markdown","metadata":{},"source":["#### Mesure de la vitesse\n\n"]},{"cell_type":"markdown","metadata":{},"source":["On suppose une répartition d'erreurs autour d'une vitesse $v$ donnée\npar une loi normale d'incertitude-type $\\Delta v$.\n\nOn utilisera la fonction `random.normal` pour tirer un nombre flottant\naléatoire correspondant cette loi normale.\n\n"]},{"cell_type":"markdown","metadata":{},"source":["## Code\n\n"]},{"cell_type":"markdown","metadata":{},"source":["### Fonctions permettant de réaliser les tirages aléatoires\n\n"]},{"cell_type":"markdown","metadata":{},"source":["On utilise les fonctions offertes par `numpy.random`\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[],"source":["# tirage aléatoire pour une loi normale de moyenne X[0] et d'incertitude-type X[1]\ndef tirage_normal(X):\n return X[0] + X[1]*np.random.normal()\n\n# tirage aléatoire pour une répartition uniforme entre X[0] et X[1]\ndef tirage_uniforme(X):\n return X[0] + (X[1]-X[0])*np.random.random_sample()"]},{"cell_type":"markdown","metadata":{},"source":["### Paramètres\n\n"]},{"cell_type":"markdown","metadata":{},"source":["On suppose pour cette simulation connue les valeurs vraies de $g$,\n$h_1$ et $h_2$. On en déduit celle de $v$.\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[],"source":["# Accélération de la pesanteur\ng = 9.80665 #en m/s, valeur normale de la CGPM\n\n# Hauteur de chute\nh1 = 3 # en m\nh2 = 2 # en m\nh0 = h1-h2\nDeltah = 5e-3 # en m, demi-largeur de la lecture de h\n\n# Vitesse atteinte\nv0 = np.sqrt(2* g * h0) # en m/s\nDeltav = 1e-2 # en m/s, incertitude-type sur la mesure de v"]},{"cell_type":"markdown","metadata":{},"source":["### Simulation des mesures\n\n"]},{"cell_type":"markdown","metadata":{},"source":["On crée des listes `numpy array` de mesures de $h_1$, $h_2$ et $v$\npour faciliter leur manipulation.\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[],"source":["# Mesures\nN = 10000 # nombre de points de mesure\ng_calculee = np.array([])\n\nh1min = h1-Deltah\nh1max = h1+Deltah\nh2min = h2-Deltah\nh2max = h2+Deltah\n\nMesuresV = np.array([tirage_normal([v0,Deltav]) for i in range(N)])\nMesuresH1 = np.array([tirage_uniforme([h1min,h1max]) for i in range(N)])\nMesuresH2 = np.array([tirage_uniforme([h2min,h2max]) for i in range(N)])"]},{"cell_type":"markdown","metadata":{},"source":["### Étude de $g$\n\n"]},{"cell_type":"markdown","metadata":{},"source":["On calcule les valeurs de $g$, leur valeur moyenne et l'écart-type de\nleur distribution.\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[],"source":["# Valeurs de $h = h1-h2\nMesuresH = MesuresH1 - MesuresH2\n# On pourrait faire la même chose sans numpy array avec:\n# MesuresH = [MesuresH1[i] - MesuresH2[i] for i in range(N)]\n# ou\n# for i in range(N)\n# MesuresH[i] = MesuresH1[i] - MesuresH2[i]\n\n# Valeurs calculées de g = v^2/(2h)\ng_calculees = MesuresV**2/(2*MesuresH)\ng_moyenne = np.average(g_calculees)\nStdevg = np.std(g_calculees,ddof=1)\nprint(f'moyenne des valeurs calculées de g: {g_moyenne:.3e}')\nprint(f'incertitude-type sur les valeurs calculées de g: {Stdevg:.3e}')"]},{"cell_type":"markdown","metadata":{},"source":["L'argument `ddof=1` passé à la méthode `std` de `numpy` est\nnécessaire pour utiliser le terme en $\\sqrt{N-1}$ dans la\ndéfinition de l'écart-type corrigé:\n\n\\begin{equation*}\n \\sigma = \\sqrt{\\frac{1}{N-1}{\\sum_{i=1}^N \\left(m_i-\\overline{m}\\right)^2}},\n\\end{equation*}\n\nOn affiche un histogramme de ces valeurs.\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[],"source":["histo,(axehisto)=plt.subplots(1,1)\naxehisto.hist(g_calculees, bins = 50, color = 'blue', edgecolor = 'black')\naxehisto.set_xlabel('g (m/s^2)')\naxehisto.set_ylabel('effectif')\nhisto.suptitle(f'Pour {N} iterations')\nhisto.show()"]},{"cell_type":"markdown","metadata":{},"source":["## Questions\n\n"]},{"cell_type":"markdown","metadata":{},"source":["### Manipulations élémentaires\n\n"]},{"cell_type":"markdown","metadata":{},"source":["1. Créer une liste nommée `liste1` contenant les entiers pairs entre\n $4 et 20$.\n\n1. Créer une liste `liste2` contenant leurs produits par $3$.\n\n1. Transformer ces listes en `numpy.array` et en déduire leurs\n produits termes à terme de leurs éléments.\n\n1. Créer une fonction `somme(n)` qui renvoie la somme des $1/p^2$\n pour $p \\in [1;n]$. On peut montrer que `somme(n)` tend vers\n $\\pi^2/6$ quand $n\\to\\infty$.\n \n Calculer la différence relative pour quelques grandeurs valeurs de $n$, et\n l'afficher en notation scientifique. La valeur de $\\pi$ est\n accessible par `np.pi`.\n\n1. Tracer la courbe représentative de $x\\mapsto e^(-x/2) cos (2\\pi\n x)$ pour $x \\in [0;5]$. On utilisera les fonctions `np.exp` et\n `np.cos` (dont les arguments sont des radians).\n\n"]},{"cell_type":"markdown","metadata":{},"source":["### Incertitudes composées\n\n"]},{"cell_type":"markdown","metadata":{},"source":["1. Afficher l'écart-type relative des mesures de $g$.\n\n1. Afficher les incertitudes-types et les incertitudes-types relatives\n sur $v$, $h1$, $h2$.\n\n1. Afficher l'écart-type des valeurs mesurées de $h$ et comparer à\n l'incertitude-type composée à partir des incertitudes-types de\n $h_1$ et $h_2$. Calculer l'incertitude-type relative sur $h$.\n\n1. Déterminer et afficher l'incertitude-type relative composée sur $g$\n en fonction des incertitudes-types relatives précédentes et\n comparer à l'écart-type relatif sur $g$.\n \n On a $g = v^2/(2 h)$, soit $\\Delta g/g = \\sqrt{4 (\\Delta v/v)^2 +\n (\\Delta h/h)^2}$, qu'on compare à l'écart-type des valeurs\n calculées de $v$.\n\n1. Augmenter d'un facteur 10 la précision sur la vitesse? Quel est\n l'effet sur la précision de la détermination de $g$. Commenter.\n\n"]},{"cell_type":"markdown","metadata":{},"source":["### Effet du nombre de mesures\n\n"]},{"cell_type":"markdown","metadata":{},"source":["1. Changer le nombre d'itérations $N$ d'un facteur 100 dans un sens ou\n dans l'autre. Cela change-t-il les résultats précédents?\n\n1. Pour un jeu de $N = 1e4$ mesures, effectuer des moyennes de $m =\n 100$ et étudier l'incertitude-type des $N/m = 100$ mesures\n obtenues. Vérifier qu'il est réduit d'un rapport $\\sqrt{m}$.\n\n"]}],"metadata":{"org":null,"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.5.2"}},"nbformat":4,"nbformat_minor":0}