diff --git a/tutoriels/matlab/matlab_2022_2023.ipynb b/tutoriels/matlab/matlab_2022_2023.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..1e2cb45ed72d954243f714db2d444107886f4044
--- /dev/null
+++ b/tutoriels/matlab/matlab_2022_2023.ipynb
@@ -0,0 +1,1743 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Didacticiel Matlab\n",
+    "\n",
+    "Ce didacticiel aborde la plupart des fonctionnalités utilisées dans les TP de Matlab, notamment pour les TP de probas et de stats. Vous pouvez exécuter les blocs de texte et de code un par un en prenant le temps de bien les comprendre.\n",
+    "\n",
+    "Avant de commencer, assurez-vous que le noyau Octave est sélectionné. Pour cela, si la barre inférieure indique \"No Kernel\", cliquez dessus et choisissez \"Octave\".\n",
+    "\n",
+    "Une fois ce noyau sélectionné, vous pouvez lancer successivement chaque cellule au fur et à mesure de votre lecture en cliquant sur la triangle dans la barre supérieure.\n",
+    "\n",
+    "## 1) Définition de matrices\n",
+    "\n",
+    "Pour définir un **vecteur ligne** :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "V_ligne = [1 3 5 7 9]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Pour définir un **vecteur colonne** :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "V_colonne = [2; 4; 6; 8; 10]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "De manière générale, on utilise **des espaces (ou des virgules) comme séparateur horizontal** et le **point virgule comme séparateur vertical**.\n",
+    "La même règle s'applique à la définition d'une matrice. Essayez de prédire la matrice qui sera définie par l'instruction suivante avant de l'exécuter :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "M = [1 3 5 7 9; 2 4 6 8 10]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "On peut également construire M à partir de la **concaténation** des vecteurs définis précédemment. On pourrait penser à écrire quelque chose comme :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "M = [V_ligne; V_colonne]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "À l'exécution de cette ligne, une erreur de dimensions est levée. En effet, V_ligne est de taille 1x5 et V_colonne est de taille 5x1.\n",
+    "En transposant V_colonne (V_colonne' ou transpose(V_colonne)), on résout ce problème de dimensions :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "M = [V_ligne; V_colonne']"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Comme les valeurs de M sont régulièrement espacées, il est possible d'utiliser des **plages de valeurs** avec un certain pas.\n",
+    "Exécutez les deux instructions suivantes et identifiez à chaque fois les bornes de la plage ainsi que le pas."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Enum1 = 3:7:90"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Enum2 = 5:3:20"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Essayez de réécrire V_ligne, V_colonne et M en utilisant des plages."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "V_ligne ="
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "V_colonne = "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "M ="
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    " Vérifiez avec les solutions données ci-dessous.\n",
+    " **Attention à ne pas écrire V_colonne = 2:2:10'** car la transposition ne s'applique alors qu'à 10 et on obtiendrait un vecteur ligne."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "V_ligne = 1:2:9\n",
+    "V_colonne = (2:2:10)'\n",
+    "V_colonne = transpose(2:2:10)\n",
+    "M = [1:2:9; 2:2:10]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Enfin, il est possible de définir des matrices ne contenant que des 0 ou que des 1, ou encore des matrices identités (des 1 sur la diagonale et des 0 partout ailleurs).\n",
+    "Dans tous ces cas, il faut indiquer les dimensions de la matrice souhaitée. Si une seule dimension est donnée, elle est utilisée comme nombre de lignes et de colonnes : on obtient alors une matrice carrée."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "M0 = zeros(3, 5)\n",
+    "M1 = ones(3, 5)\n",
+    "M2 = ones(4, 4)\n",
+    "M3 = ones(4)\n",
+    "Id = eye(4)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 2) Opérations sur les matrices\n",
+    "\n",
+    "Il est possible d'ajouter une constante à un vecteur/une matrice :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "MplusTrois = M+3"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Il est possible de multiplier un vecteur/une matrice par une constante :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "troisFoisM = 3*M"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Il est possible d'additionner des matrices de mêmes tailles"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "MplusMplusM = M+M+M"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Attention, sous certaines conditions, Matlab permet les additions entre une matrice et un vecteur s'ils ont une dimension en commun.\n",
+    "Le vecteur est alors répliqué selon la dimension non commune pour faire la même taille que la matrice. Par exemple, les deux instructions suivantes sont équivalentes :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "M + [1 3 5 7 9]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "M + [1 3 5 7 9; 1 3 5 7 9]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "M est de taille (2,5) et V_ligne = [1 3 5 7 9] est de taille (1,5) donc, lors de l'addition, V_ligne est répliqué deux fois pour faire la taille de M.\n",
+    "Vous nous déconseillons d'utiliser cette réplication propre à Matlab et nous verrons plus loin comment répliquer manuellement un vecteur ou une matrice."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Le produit matriciel usuel entre M1 de taille (m,k) et M2 de taille (k,n) donne une matrice de taille (m,n).\n",
+    "Il se fait comme suit :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "M*V_colonne"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "V_ligne*V_colonne"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "V_colonne*V_ligne"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Il est alors possible de répliquer un vecteur en le multipliant par un vecteur ones de taille adaptée. Par exemple, pour répliquer [1 3 5 7 9] de taille (1,5) en [1 3 5 7 9; 1 3 5 7 9] de taille (2,5), on peut faire l'instruction suivante :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ones(2,1) * [1 3 5 7 9]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Enfin, il existe la fonction **repmat** (pour réplique matrice) qui permet de répliquer une matrice un certain nombre de fois horizontalement et un certain nombre de fois verticalement pour obtenir une plus grande matrice. Par exemple :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "repmat(M, 4, 2)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Ainsi, pour répliquer [1 3 5 7 9] en une matrice de tailles (2,5), on peut faire :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "repmat([1 3 5 7 9], 2, 1)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Il est possible de vectoriser une matrice. Le vecteur obtenu est **la concaténation des colonnes** de la matrice."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "M_vectorise = M(:)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Sur des matrices de mêmes tailles, il est possible d'effectuer des **opérations élément par élément**, comme suit :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "I = [200 180 170 190 155; 205 190 195 165 150; 210 215 175 155 190]\n",
+    "Coefficients = [0.5 0.2 0.4 0.8 1; 0.4 0.2 0 1 0.9; 0.75 0.5 0.6 1 0.1]\n",
+    "\n",
+    "I.*Coefficients % Produit élément par élément de I et de Coefficients"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "I.*I % Matrice des carrés des éléments de I"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "I.^3 % Matrice de chaque élément de I élevé à la puissance 3"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Certaines fonctions s'effectuent sur tous les éléments d'une matrice sans qu'il soit nécessaire de le préciser avec un \".\".\n",
+    "C'est notamment le cas des fonctions usuelles cosinus **cos**, sinus **sin**, racine carrée **sqrt**, etc :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "racineI = sqrt(I)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "I - racineI.*racineI"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Dans cet exemple, on remarque que l'on obtient pas une matrice entièrement composée de 0 car la précision de la machine sur les opérations flottantes est limitée. Notez la présence du facteur multiplicatif 1.0e-13."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 3) Modification des éléments d'une matrice\n",
+    "\n",
+    "Lorsque l'on veut modifier la valeur d'un élément en particulier, une première syntaxe consiste à préciser le numéro de ligne et le numéro de colonne de l'élément :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Z1 = zeros(7, 5); % Ce point-virgule en fin de ligne permet de ne pas afficher le résultat de l'instruction\n",
+    "Z1(2, 3) = 4"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "On remarque qu'en Matlab, les indices commencent à 1 et non à 0 comme dans de nombreux langages (C, Python...).\n",
+    "Une deuxième syntaxe consiste à donner **l'indice absolu** de l'élément. De nouveau, on compte selon les colonnes :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Z1(5) = 18"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Z1(13) = 21"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Il existe deux fonctions **sub2ind** et **ind2sub** qui permettent de convertir un indice absolu en indices relatifs (numéros de ligne et de colonne) et inversement. Il est nécessaire de donner la taille de la matrice considérée en entrée de ces fonctions :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "[ligne, colonne] = ind2sub(size(Z1), 13)\n",
+    "indice_absolu = sub2ind(size(Z1), 2, 4)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "La fonction **ind2sub** est une fonction qui peut renvoyer plusieurs sorties : elle renvoie l'indice de ligne et l'indice de colonne. Nous donnerons d'autres exemples de ce genre de fonctions plus loin."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Pour modifier plusieurs éléments simultanément, il faut indiquer les indices des éléments à modifier et donner les nouvelles valeurs de ces éléments dans une matrice de taille adaptée. Nous donnons plusieurs exemples ci-dessous, prenez le temps de les comprendre :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Z2 = zeros(9, 7);\n",
+    "Z2(2, 3:7) = V_ligne"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Z2(4:8, 1) = V_colonne"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Z2(5:6, 3:7) = M"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Il est possible d'extraire une sous-matrice en indiquant les plages d'indices désirées. Par exemple :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Z2(3:8, 1:5)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "On peut également indiquer un pas. Essayez de prédire ce que renvoie l'instruction suivante puis exécutez-la :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Z2(2:2:6, 3:2:7)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "La sous-matrice obtenue est de taille (3,3). Il est donc possible de modifier tous ces éléments d'un coup en donnant les nouvelles valeurs dans une matrice de taille (3,3), comme dans l'exemple suivant. Prenez le temps de bien localiser les éléments de A dans la matrice Z2 :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "A = [3 4 2; 5 5 5; 9 0 3]\n",
+    "Z2(2:2:6, 3:2:7) = A"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "La longueur d'un vecteur peut être obtenue par la fonction **length** :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "longueur = length(V_ligne)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "L'utilisation de **length** sur une matrice est déconseillé car la fonction ne retourne alors que la plus grande dimension de la matrice.\n",
+    "\n",
+    "Le **nombre de lignes** et le **nombre de colonnes** d'une matrice peuvent être obtenus avec **size** en faisant :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Z3 = zeros(6, 4)\n",
+    "nb_lignes = size(Z3, 1)\n",
+    "nb_colonnes = size(Z3, 2)\n",
+    "plus_grande_dimension = length(Z3)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Il existe plusieurs façons de redéfinir une ligne (ou une colonne) entière. On peut donner une plage d'indices allant de 1 à nb_lignes ou nb_colonnes :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Z3(4, 1:nb_colonnes) = 99\n",
+    "Z3(1:nb_lignes, 2) = -55"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "On peut utiliser le symbole \":\" qui indique de considérer tous les éléments de la ligne (ou de la colonne) :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Z4 = zeros(6, 4)\n",
+    "Z4(3, :) = 11\n",
+    "Z4(:, 4) = -33"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Enfin, il est possible d'utiliser le mot clé \"end\" à la place de nb_lignes ou nb_colonnes :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Z5 = zeros(6, 4)\n",
+    "Z5(2, 1:end) = 222\n",
+    "Z5(1:end, 1) = 666"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Pour modifier simultanément plusieurs éléments, on utilise un vecteur d'indices absolus. Par exemple, pour mettre la valeur 1 aux indices absolus 2, 5, 7, 12, 13, 14, 19 d'une matrice de tailles (6,4), on utilise :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Z6 = zeros(6, 4)\n",
+    "Z6([2, 5, 7, 12, 13, 14, 19]) = 1"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "La fonction **sub2ind** évoquée précédemment peut s'avérer utile pour récupérer un indice absolu à partir des numéros de ligne et de colonne d'un élément. En pratique, on n'utilise rarement ces conversions car Matlab dispose de fonctions qui permettent de s'en passer. Nous donnons un exemple ci-dessous."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Supposons que l'on dispose d'une matrice I et que l'on souhaite remplacer tous les éléments de I de valeur inférieure à un certain seuil (disons 177) par 0. L'instruction I <= 177 renvoie une matrice booléenne :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "I = [200 180 170 190 155; 205 190 195 165 150; 210 215 175 155 190]\n",
+    "I <= 177"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Pour récupérer les indices des valeurs de I inférieures à 177 avec **find** :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "find(I <= 177)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "On peut alors récupérer les valeurs de I inférieures à 177 en faisant :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "I(find(I <= 177))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "L'instruction suivante, plus épurée, renvoie le même résultat :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "I(I <= 177)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Ainsi, pour mettre à 0 tous les éléments de I inférieures à 177, on peut écrire :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "I(I<=177) = 0"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "qui est la version plus épurée de :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "I(find(I<=177)) = 0"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Enfin, pour tester l'égalité entre deux matrices (ou vecteurs), on pourrait être tentés de faire :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "A = [pi, 2*pi, 3*pi; 4*pi, 5*pi, 6*pi] \n",
+    "B = [3.1416, 6.2832, 9.4248; 12.5664, 15.7080, 18.8496]\n",
+    "A == B"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Les valeurs affichées dans A et dans B sont les mêmes. Pourtant, la matrice de booléens A == B ne contient que des 0 (associés à la valeur \"faux\"). Deux problèmes entrent en jeu :\n",
+    "- d'une part, Matlab n'affiche qu'un certain nombre de décimales ;\n",
+    "- d'autre part, lorsque l'on manipule des nombres flottants, on manipule en vérité des valeurs à une précision machine près.\n",
+    "\n",
+    "La façon standard de vérifier que deux flottants sont égaux consiste donc à vérifier que leur différence en valeur absolue est inférieur à un certain seuil de précision fixé par l'utilisateur en fonction du contexte. Par exemple :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "abs(pi-3.1416) < 0.001\n",
+    "abs(pi-3.1416) < 0.000001"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "De façon analogue, la vérification d'égalité entre deux matrices impliquera :\n",
+    "- de vérifier qu'elles ont la même taille (donc le même nombre de coefficients) ;\n",
+    "- que les différences en valeur absolue des coefficients terme à terme sont inférieures à un certain seuil."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 4) Fonctions utiles\n",
+    "On peut modifier la forme d'une matrice avec la fonction **reshape** : la seule contrainte est que le nombre d'éléments total doit rester le même. À nouveau, l'ordre des éléments se retrouve dans la vectorisation de la matrice, comme illustré ci-dessous sur une matrice de taille (4,6) (donc à 24 éléments). Prenez le temps de bien comprendre les exemples ci-dessous :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "J = [200 180 170 190 155 120; 205 190 195 165 150 60; 210 215 175 155 190 160; 125 155 165 145 200 185]\n",
+    "J1 = J(:) % Vectorisation de J\n",
+    "J2 = reshape(J, 3, 8)\n",
+    "J3 = reshape(J, 6, 4)\n",
+    "J4 = reshape(J, 8, 3)\n",
+    "J5 = reshape(J, 24, 1) % équivalent à J(:)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "La fonction **max** permet de récupérer l'élément d'un vecteur (colonne ou ligne) de valeur maximale, ainsi que son indice.\n",
+    "Il s'agit d'une fonction qui peut renvoyer plusieurs sorties, tout comme **size**."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "W = [4, 12, 3, 7, 6]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Observez les deux syntaxes suivantes et identifiez les différences :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "valeur_maximale = max(W)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "[valeur_maximale, indice_du_maximum] = max(W)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Si l'on ne précise qu'une seule sortie, **max** ne renvoie que la valeur maximale.\n",
+    "Pour obtenir l'indice du maximum, il faut demander deux sorties entre crochets comme dans la deuxième syntaxe.\n",
+    "Si l'on ne souhaite se servir que de l'indice du maximum, il est possible de se passer de la sortie correspondant à la valeur du maximum avec le symbole \"~\" :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "[~, indice_du_maximum] = max(W)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Dans le cas d'une matrice, la fonction **max** permet de récupérer la valeur maximale de chaque colonne ainsi que son indice."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "J\n",
+    "maxima = max(J)\n",
+    "[~, indices_maxima] = max(J)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "De la même façon, la fonction **sort** permet de trier les valeurs par ordre croissant ('ascend') ou décroissant ('descend') et de renvoyer les indices correspondants si deux sorties sont demandées."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "W\n",
+    "valeurs_ordre_croissant = sort(W, 'ascend') % Par défaut, sort utilise ascend s'il n'y a pas de 2ème paramètre\n",
+    "valeurs_ordre_decroissant = sort(W, 'descend')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "[valeurs_ordre_croissant, indices_ordre_croissant] = sort(W, 'ascend')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "[~, indices_ordre_croissant] = sort(W, 'ascend')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "On peut vérifier que W(indices_ordre_croissant) donne valeurs_ordre_croissant :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "W(indices_ordre_croissant)\n",
+    "valeurs_ordre_croissant"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "La fonction **mean** renvoie :\n",
+    "- la moyenne des éléments d'un vecteur lorsqu'elle est utilisée sur un vecteur ;\n",
+    "- les moyennes de chaque colonne ou de chaque ligne d'une matrice lorsqu'elle est utilisée sur une matrice.\n",
+    "\n",
+    "Pour préciser si la moyenne doit être calculée par lignes ou par colonnes, il est nécessaire d'ajouter un deuxième argument égal à 1 (par colonnes) ou à 2 (par lignes). Par défaut, en l'absence de deuxième argument, la moyenne est calculée par colonnes (valeur par défaut : 1)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "V = [2 3 5 8 12]\n",
+    "mean(V)\n",
+    "\n",
+    "M = [1 3 5 7 9; 2 4 6 8 10]\n",
+    "moyennes_par_colonnes = mean(M, 1)\n",
+    "moyennes_par_lignes = mean(M, 2)\n",
+    "moyennes_par_defaut = mean(M)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "De façon similaire, la fonction **sum** renvoie :\n",
+    "- la somme des éléments d'un vecteur lorsqu'elle est utilisée sur un vecteur ;\n",
+    "- les sommes de chaque colonne ou de chaque ligne d'une matrice lorsqu'elle est utilisée sur une matrice.\n",
+    "De nouveau, pour préciser si les moyennes doivent être calculées par lignes ou par colonnes, on ajoute un deuxième argument égal à 1 (par colonnes) ou à 2 (par lignes). Par défaut, si l'on n'indique pas de deuxième argument, il est égal à 1."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "V = [2 3 5 8 12]\n",
+    "sum(V)\n",
+    "\n",
+    "M = [1 3 5 7 9; 2 4 6 8 10]\n",
+    "sommes_par_colonnes = sum(M, 1)\n",
+    "sommes_par_lignes = sum(M, 2)\n",
+    "sommes_par_defaut = sum(M)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Ainsi, les moyennes peuvent être calculées soit avec **mean**, soit avec **sum** et **size**."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "M = [1 3 5 7 9; 2 4 6 8 10];\n",
+    "mean(M, 1)\n",
+    "sum(M, 1)/size(M, 1)\n",
+    "mean(M, 2)\n",
+    "sum(M, 2)/size(M, 2)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Enfin, il est possible de consulter la document d'une fonction avec la commande **help**. Des exemples numériques sont notamment donnés en fin de documentation :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "help sum"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 5) Définir une fonction"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Il est possible de définir des fonctions en donnant ses paramètres d'entrée et de sortie.\n",
+    "Attention, cette fonctionnalité n'étant pas disponible sur notebook, vous aurez le message d'erreur suivant en exécutant le bloc : \"Error: Function definition not supported in this context. Create functions in code file\".\n",
+    "L'idée est avant tout de voir la syntaxe d'une défintion de fonction.\n",
+    "\n",
+    "Par exemple, si l'on veut définir une fonction appelée **calculs_basiques** qui, à partir de deux entrées **a** et **b** renvoie trois sorties contenant respectivement la somme, la différence et le produit de **a** et **b**, on peut écrire :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "function [somme, difference, produit] = calculs_basiques(A, B)\n",
+    "    somme = A+B;\n",
+    "    difference = A-B;\n",
+    "    produit = A.*B;\n",
+    "end"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Il serait également possible de stocker ces trois valeurs dans un vecteur et de n'avoir que ce vecteur en sortie. On écrirait alors :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "function resultats = calculs_basiques_variante(A, B)\n",
+    "    resultats = [A+B, A-B, A*B];\n",
+    "end"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Il faut faire bien attention à la façon dont sont appelées les fonctions dans le code. Par exemple, si l'on écrit :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "resultats = calculs_basiques(3, 5);"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "resultats sera égal à 8 car il ne contiendra que la première sortie de **calculs_basiques** (somme). On a déjà abordé ce point en présentant les fonctions **sort** et **max** : elles peuvent retourner plusieurs sorties mais ne retournent que la première d'entre elles si l'on ne précise pas avec des crochets les sorties désirées.\n",
+    "\n",
+    "À l'inverse, si l'on écrit :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "[somme, difference, produit] = calculs_basiques_variante(3, 5);"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "une erreur sera affichée car une seule sortie est attendue de la part de la fonction **calculs_basiques_variante**."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 6) Les structures de contrôle\n",
+    "### 6.1) Les boucles for"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Lorsque l'on veut faire une boucle **for** en Matlab, on précise un vecteur contenant toutes les valeurs que doit prendre l'indice de boucle (i dans l'exemple donné ci-dessous). Par exemple, pour une boucle de 1 à 1000 on utilisera le vecteur [1 2 3 ... 1000] qui s'écrit plus simplement 1:1000."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "somme = 0;\n",
+    "for i = 1:10\n",
+    "    somme = somme + i  % Ajouter un ';' en fin de ligne permet d'éviter l'affichage à chaque tour de boucle\n",
+    "end"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Cet exemple illustre bien l'intérêt d'ajouter des ';' en fin de ligne pour éviter l'affichage.\n",
+    "\n",
+    "Dans l'exemple suivant, nous souhaitons calculer une matrice C qui est la somme de deux matrices A et B.\n",
+    "Nous montrons comment le faire de deux manières différentes :\n",
+    "- avec une boucle **for**\n",
+    "- matriciellement\n",
+    "\n",
+    "Pour chaque méthode, nous mesurons le temps d'exécution en appelant les instructions **tic** et **toc** respectivement avant et après le bloc de code dont on veut mesurer le temps d'exécution."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "A = rand(2000,1500);\n",
+    "B = rand(size(A));\n",
+    "C = zeros(size(A));\n",
+    "\n",
+    "tic\n",
+    "% Avec une boucle for\n",
+    "for i = 1:size(C, 1)\n",
+    "    for j = 1:size(C, 2)\n",
+    "        C(i, j) = A(i, j) + B(i, j);\n",
+    "    end\n",
+    "end\n",
+    "toc"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "A = rand(2000, 1500);\n",
+    "B = rand(size(A));\n",
+    "C = zeros(size(A));\n",
+    "\n",
+    "tic\n",
+    "C = A + B;\n",
+    "toc"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Bien souvent, le fait d'utiliser des boucles **for** augmente les temps de calcul.\n",
+    "Il n'est cependant pas toujours évident de se passer de ces boucles, mais nous vous demanderons de les éviter au maximum lorsqu'elles sont remplaçables par d'autres fonctions ou opérations matricielles.\n",
+    "\n",
+    "Pour illustrer un cas où se passer de boucle **for** n'est pas évident, nous proposons l'exemple d'une quantification d'histogramme.\n",
+    "Nous souhaitons compter le nombre d'éléments d'une matrice dont la valeur est comprise entre 0 et 0.1, entre 0.1 et 0.2, entre 0.2 et 0.3...et entre 0.9 et 1.\n",
+    "De nouveau, nous proposons une version avec boucle **for** et une version sans. Prenez le temps de bien comprendre les deux versions :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "M = rand(800, 600);\n",
+    "\n",
+    "Histogramme = zeros(1, 10);\n",
+    "\n",
+    "tic\n",
+    "for i = 1:size(M, 1)\n",
+    "    for j = 1:size(M, 2)\n",
+    "        valeur = floor(M(i, j)*10);  % pour obtenir un indice entre 0 et 9\n",
+    "        indice = valeur+1;  % les indices en Matlab commencent à 1\n",
+    "        Histogramme(indice) = Histogramme(indice) + 1;\n",
+    "    end\n",
+    "end\n",
+    "toc"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "M = rand(800, 600);\n",
+    "\n",
+    "Histogramme = zeros(1, 10);\n",
+    "\n",
+    "tic\n",
+    "M = repmat(M(:), 1, 10);\n",
+    "intervalles1 = 0:0.1:0.9;\n",
+    "intervalles2 = 0.1:0.1:1;\n",
+    "\n",
+    "Histogramme = sum(M >= intervalles1 & M < intervalles2);\n",
+    "toc"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Le symbole **&** désigne ici le ET logique.\n",
+    "De la même façon, on peut écrire un OU logique avec le symbole **|**"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### 6.2) Utilisation de while et if"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Nous illustrons rapidement l'utilisation de **while** et **if** au travers de l'exemple d'une fonction cherchant à déterminer si un nombre **n** est premier ou non en calculant le reste de la division euclidienne de tous les nombres de 2 à racine carrée (**sqrt**) de **n** et en déclarant que le nombre n'est pas premier si l'un de ces restes est nul. En Matlab, on peut écrire :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "function primalite = est_premier(n)\n",
+    "    primalite = 1;\n",
+    "    indice = 2;\n",
+    "    while indice <= sqrt(n) & primalite\n",
+    "        if mod(n, indice) == 0\n",
+    "            primalite = 0;\n",
+    "        end\n",
+    "        indice = indice + 1;\n",
+    "    end\n",
+    "end"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 7) Affichage de courbes\n",
+    "\n",
+    "### 7.1) plot de R dans R\n",
+    "\n",
+    "Il est possible de tracer des courbes avec la fonction **plot**.\n",
+    "Commençons par un exemple simple :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "X = [3, 5, 7, 8, 11, 15];\n",
+    "Y = [3, 4, -5, 6, 1, 10];\n",
+    "plot(X, Y);"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Pour ajouter un titre à la figure, on peut faire :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "plot(X, Y);\n",
+    "title('Tracer de Y en fonction de X');"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "On peut également ajouter du texte le long des axes :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "plot(X, Y);\n",
+    "title('Tracer de Y en fonction de X');\n",
+    "xlabel('Valeurs contenues dans X');\n",
+    "ylabel('Valeurs contenues dans Y');"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "On peut préciser la couleur du tracé de la façon suivante :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "plot(X, Y,'r');"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Si on ne souhaite qu'avec des points non reliés, on peut indiquer le type de marqueurs (parmi *, +, o)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "plot(X, Y,'*');"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Pour combiner marqueur et couleur :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "plot(X, Y,'r*');"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "On peut regrouper plusieurs figures avec la fonction **subplot** : on indique d'abord le nombre de lignes n, le nombre de colonnes m et enfin l'indice (entre 1 et n\\*m) de la figure que l'on dessine. On peut choisir pour chaque sous-figure d'ajouter un titre et des étiquettes sur les axes ou non :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "subplot(2,2,1);\n",
+    "plot(X, Y);\n",
+    "title('Titre de la sous-figure 1')\n",
+    "\n",
+    "subplot(2,2,2);\n",
+    "plot(X, Y,'r');\n",
+    "xlabel('Axe X de la figure 2')\n",
+    "\n",
+    "subplot(2,2,3);\n",
+    "plot(X, Y,'*');\n",
+    "ylabel('Axe Y de la figure 3')\n",
+    "\n",
+    "subplot(2,2,4);\n",
+    "plot(X, Y,'r*');\n",
+    "title('Titre de la sous-figure 4')\n",
+    "xlabel('Axe X de la figure 4')\n",
+    "ylabel('Axe Y de la figure 4')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### 7.2) plot de R² dans R\n",
+    "\n",
+    "La fonction **contour(X, Y, Z)** permet un affichage en lignes de niveaux. De nouveau, nous illustrons son utilisation au travers d'un exemple. Nous commençons par définir deux axes X et Y gradués à chaque unité de -20 à 20 : X et Y sont donc deux vecteurs de taille 41. Une valeur z est attribuée à chaque couple (x, y). Pour pouvoir utiliser **contour**, il faut stocker tous les valeurs z dans une matrice Z (qui seront donc de taille 41x41).\n",
+    "\n",
+    "Pour avoir une certaine régularité dans les lignes de niveaux de l'exemple ci-dessous, nous calculons chaque valeur de Z à partir des valeurs voisines et perturbons la valeur d'une quantité comprise entre -0.5 et 0.5 (rand-0.5). Il aurait été possible de simplement assigner une valeur aléatoire, mais les lignes de niveaux auraient alors été plus difficiles à visualiser."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "X = -20:20;\n",
+    "Y = -20:20;\n",
+    "Z = zeros(41,41);\n",
+    "for i = 2:41\n",
+    "    for j = 2:41\n",
+    "        Z(i,j) = rand - 0.5 + (Z(i-1,j-1)+Z(i-1,j)+Z(i,j-1))/3;\n",
+    "    end\n",
+    "end\n",
+    "contour(X, Y, Z);"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Enfin, la documentation Matlab détaille et illustre tous les types d'affichage possibles (on y retrouve notamment des histogrammes et des courbes en 3D) sur la page suivante : https://www.mathworks.com/help/matlab/creating_plots/types-of-matlab-plots.html"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 8) Lecture et affichage d'images\n",
+    "\n",
+    "En Matlab, les images sont représentées par des matrices dont chaque élément représente le niveau de gris (pour des images en noir et blanc) ou la couleur (pour des images en couleur) d'un pixel de l'image. Pour des images en niveaux de gris, les matrices associées sont bidimensionnelles et sont de taille (nb_lignes, nb_colonnes). Pour des images en couleur, les matrices associées sont tridimensionnelles et sont de taille (nb_lignes, nb_colonnes, 3) : les 3 canaux de la troisième dimension permettent d'encoder le niveau de couleur (rouge, vert ou bleu) du pixel (codage RGB).\n",
+    "\n",
+    "Les valeurs sont prises entre 0 et 255 inclus.\n",
+    "\n",
+    "À titre d'exemples :\n",
+    "- (r = 255, g = 0, b = 0) donne du rouge vif\n",
+    "- (r = 255, g = 255, b = 0) donne du jaune vif\n",
+    "- (r = 128, g = 128, b = 128) donne du gris\n",
+    "- pour des images en niveaux de gris, 0 correspond au noir et 255 au blanc\n",
+    "\n",
+    "Vous pouvez sélectionner une couleur et obtenir son code RGB sur le site suivant : https://htmlcolorcodes.com/fr/selecteur-de-couleur/\n",
+    "\n",
+    "De manière générale, les fonctions d'affichage seront déjà écrites dans les TP de probabilités et statistiques. Nous présentons donc rapidement les principales fonctions.\n",
+    "\n",
+    "Matlab dispose de quelques images internes.\n",
+    "La lecture d'une image se fait avec la fonction **imread** :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "I = imread('einstein.jpg')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "imagesc(I);"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Pour l'affichage des images en niveaux de gris, Matlab utilise une palette de couleurs. Par défaut, il s'agit de couleurs allant du jaune/vert pour les niveaux de gris élevés au bleu pour les niveaux de gris faibles.\n",
+    "Il est possible de modifier la palette de couleurs avec l'instruction **colormap** comme suit :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "colormap gray;\n",
+    "imagesc(I);"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Ci-dessous, un exemple d'image en couleur. Notez que la matrice est affichée canal par canal : I(:,:,1) correspond au canal rouge, I(:,:,2) au canal vert et I(:,:,3) au canal bleu. En pratique, on n'affichera pas les matrices. Pour cela, vous pouvez ajouter un \";\" en fin de ligne.\n",
+    "\n",
+    "Lorsque l'on affiche des images en couleur, il n'y a pas de colormap à gérer."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "I = imread('fruits.jpg');  % En mettant un \";\" après la fermeture de parenthèse, la matrice n'est pas affichée"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "imagesc(I);"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 9) Exemple complet : distance moyenne entre deux points d'un cercle\n",
+    "Nous présentons ici un exemple de programme Matlab faisant appel à différentes fonctionnalités présentées précédemment. Assurez-vous de bien comprendre chacune des lignes de code.\n",
+    "\n",
+    "On se propose de calculer la distance moyenne entre deux points situés sur un cercle de rayon 1.\n",
+    "Pour cela, nous tirons aléatoirement 100 paires de points et calculons les distances entre points, paire par paire.\n",
+    "Pour faire ce tirage aléatoire, nous utilisons la fonction **rand** qui tire des valeurs aléatoires entre 0 et 1 (selon une loi uniforme) et multiplions par 2\\*pi pour avoir des angles entre 0 et 2\\*pi et donc des points sur le cercle unité en utilisant **cos** et **sin**."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "nb_points = 100;\n",
+    "\n",
+    "thetas1 = 2*pi*rand(1, nb_points); % Pour tirer nb_points angles entre 0 et 2*pi\n",
+    "thetas2 = 2*pi*rand(1, nb_points); % Pour tirer nb_points autres angles entre 0 et 2*pi\n",
+    "\n",
+    "points1 = [cos(thetas1); sin(thetas1)]; % Pour créer nb_points points sur le cercle unité\n",
+    "points2 = [cos(thetas2); sin(thetas2)]; % Pour créer nb_points autres points sur le cercle unité\n",
+    "\n",
+    "distances = sqrt(sum((points1 - points2).^2,1));\n",
+    "% (points1 - points2).^2 contient les (x2-x1)^2 sur la première ligne et les (y2-y1)^2 sur la deuxième ligne\n",
+    "% sum(points1 - points2).^2,1) est un vecteur contenant les (x2-x1)^2+(y2-y1)^2\n",
+    "% sqrt(sum(points1 - points2).^2,1)) est un vecteur contenant les Racine((x2-x1)^2+(y2-y1)^2), donc les distances\n",
+    "\n",
+    "distance_moyenne = mean(distances)\n",
+    "\n",
+    "4/pi % Valeur théorique à trouver"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Essayez d'augmenter la valeur de nb_points. Plus elle est grande, plus vous devriez trouver une distance moyenne proche de la distance moyenne théorique."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## 10) Erreurs classiques\n",
+    "\n",
+    "On ne parvient pas toujours à écrire un code sans erreur du premier coup.\n",
+    "Au travers de messages d'erreur, Matlab indique généralement le type d'erreur rencontré (problème de dimension, variable non définie...) et la ligne à laquelle se produit l'erreur.\n",
+    "\n",
+    "Dans cette partie, nous vous fournissons plusieurs instructions Matlab qui renvoient une erreur lorsqu'elles sont lancées. À vous de comprendre d'où proviennent les erreurs et de les corriger :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Matrice = 256*rand(320, 240));  % Matrice de nombres aléatoires entre 0 et 256"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "% On souhaite ajouter à chaque colonne de A sa colonne suivante. La dernière colonne de A reste inchangée.\n",
+    "Matrice(:, 1:end-1) = Matrice(:, 1:end-1) + matrice(:, 1:end);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "% On souhaite ensuite centrer les valeurs en retirant la valeur moyenne de la matrice obtenue.\n",
+    "Matrice = Matrice - repmat(mean(meen(Matrice)), 320, 240);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "% On souhaite mettre à 0 tous les coefficients négatifs.\n",
+    "(Matrice < 0) = 0;"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Matlab",
+   "language": "matlab",
+   "name": "matlab"
+  },
+  "language_info": {
+   "codemirror_mode": "octave",
+   "file_extension": ".m",
+   "help_links": [
+    {
+     "text": "MetaKernel Magics",
+     "url": "https://metakernel.readthedocs.io/en/latest/source/README.html"
+    }
+   ],
+   "mimetype": "text/x-octave",
+   "name": "matlab",
+   "version": "0.16.9"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}