Skip to content
Snippets Groups Projects
Commit 8040bc70 authored by Olivier Cots's avatar Olivier Cots
Browse files

update metadata octave kernel

parent 0f9d15d0
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id: tags:
# Didacticiel Matlab
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.
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".
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.
## 1) Définition de matrices
Pour définir un **vecteur ligne** :
%% Cell type:code id: tags:
``` python
``` octave
V_ligne = [1 3 5 7 9]
```
%% Cell type:markdown id: tags:
Pour définir un **vecteur colonne** :
%% Cell type:code id: tags:
``` python
``` octave
V_colonne = [2; 4; 6; 8; 10]
```
%% Cell type:markdown id: tags:
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**.
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 id: tags:
``` python
``` octave
M = [1 3 5 7 9; 2 4 6 8 10]
```
%% Cell type:markdown id: tags:
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 id: tags:
``` python
``` octave
M = [V_ligne; V_colonne]
```
%% Cell type:markdown id: tags:
À 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.
En transposant V_colonne (V_colonne' ou transpose(V_colonne)), on résout ce problème de dimensions :
%% Cell type:code id: tags:
``` python
``` octave
M = [V_ligne; V_colonne']
```
%% Cell type:markdown id: tags:
Comme les valeurs de M sont régulièrement espacées, il est possible d'utiliser des **plages de valeurs** avec un certain pas.
Exécutez les deux instructions suivantes et identifiez à chaque fois les bornes de la plage ainsi que le pas.
%% Cell type:code id: tags:
``` python
``` octave
Enum1 = 3:7:90
```
%% Cell type:code id: tags:
``` python
``` octave
Enum2 = 5:3:20
```
%% Cell type:markdown id: tags:
Essayez de réécrire V_ligne, V_colonne et M en utilisant des plages.
%% Cell type:code id: tags:
``` python
``` octave
V_ligne =
```
%% Cell type:code id: tags:
``` python
``` octave
V_colonne =
```
%% Cell type:code id: tags:
``` python
``` octave
M =
```
%% Cell type:markdown id: tags:
Vérifiez avec les solutions données ci-dessous.
**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 id: tags:
``` python
``` octave
V_ligne = 1:2:9
V_colonne = (2:2:10)'
V_colonne = transpose(2:2:10)
M = [1:2:9; 2:2:10]
```
%% Cell type:markdown id: tags:
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).
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 id: tags:
``` python
``` octave
M0 = zeros(3, 5)
M1 = ones(3, 5)
M2 = ones(4, 4)
M3 = ones(4)
Id = eye(4)
```
%% Cell type:markdown id: tags:
## 2) Opérations sur les matrices
Il est possible d'ajouter une constante à un vecteur/une matrice :
%% Cell type:code id: tags:
``` python
``` octave
MplusTrois = M+3
```
%% Cell type:markdown id: tags:
Il est possible de multiplier un vecteur/une matrice par une constante :
%% Cell type:code id: tags:
``` python
``` octave
troisFoisM = 3*M
```
%% Cell type:markdown id: tags:
Il est possible d'additionner des matrices de mêmes tailles
%% Cell type:code id: tags:
``` python
``` octave
MplusMplusM = M+M+M
```
%% Cell type:markdown id: tags:
Attention, sous certaines conditions, Matlab permet les additions entre une matrice et un vecteur s'ils ont une dimension en commun.
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 id: tags:
``` python
``` octave
M + [1 3 5 7 9]
```
%% Cell type:code id: tags:
``` python
``` octave
M + [1 3 5 7 9; 1 3 5 7 9]
```
%% Cell type:markdown id: tags:
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.
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 id: tags:
Le produit matriciel usuel entre M1 de taille (m,k) et M2 de taille (k,n) donne une matrice de taille (m,n).
Il se fait comme suit :
%% Cell type:code id: tags:
``` python
``` octave
M*V_colonne
```
%% Cell type:code id: tags:
``` python
``` octave
V_ligne*V_colonne
```
%% Cell type:code id: tags:
``` python
``` octave
V_colonne*V_ligne
```
%% Cell type:markdown id: tags:
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 id: tags:
``` python
``` octave
ones(2,1) * [1 3 5 7 9]
```
%% Cell type:markdown id: tags:
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 id: tags:
``` python
``` octave
repmat(M, 4, 2)
```
%% Cell type:markdown id: tags:
Ainsi, pour répliquer [1 3 5 7 9] en une matrice de tailles (2,5), on peut faire :
%% Cell type:code id: tags:
``` python
``` octave
repmat([1 3 5 7 9], 2, 1)
```
%% Cell type:markdown id: tags:
Il est possible de vectoriser une matrice. Le vecteur obtenu est **la concaténation des colonnes** de la matrice.
%% Cell type:code id: tags:
``` python
``` octave
M_vectorise = M(:)
```
%% Cell type:markdown id: tags:
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 id: tags:
``` python
``` octave
I = [200 180 170 190 155; 205 190 195 165 150; 210 215 175 155 190]
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]
I.*Coefficients % Produit élément par élément de I et de Coefficients
```
%% Cell type:code id: tags:
``` python
``` octave
I.*I % Matrice des carrés des éléments de I
```
%% Cell type:code id: tags:
``` python
``` octave
I.^3 % Matrice de chaque élément de I élevé à la puissance 3
```
%% Cell type:markdown id: tags:
Certaines fonctions s'effectuent sur tous les éléments d'une matrice sans qu'il soit nécessaire de le préciser avec un ".".
C'est notamment le cas des fonctions usuelles cosinus **cos**, sinus **sin**, racine carrée **sqrt**, etc :
%% Cell type:code id: tags:
``` python
``` octave
racineI = sqrt(I)
```
%% Cell type:code id: tags:
``` python
``` octave
I - racineI.*racineI
```
%% Cell type:markdown id: tags:
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 id: tags:
## 3) Modification des éléments d'une matrice
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 id: tags:
``` python
``` octave
Z1 = zeros(7, 5); % Ce point-virgule en fin de ligne permet de ne pas afficher le résultat de l'instruction
Z1(2, 3) = 4
```
%% Cell type:markdown id: tags:
On remarque qu'en Matlab, les indices commencent à 1 et non à 0 comme dans de nombreux langages (C, Python...).
Une deuxième syntaxe consiste à donner **l'indice absolu** de l'élément. De nouveau, on compte selon les colonnes :
%% Cell type:code id: tags:
``` python
``` octave
Z1(5) = 18
```
%% Cell type:code id: tags:
``` python
``` octave
Z1(13) = 21
```
%% Cell type:markdown id: tags:
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 id: tags:
``` python
``` octave
[ligne, colonne] = ind2sub(size(Z1), 13)
indice_absolu = sub2ind(size(Z1), 2, 4)
```
%% Cell type:markdown id: tags:
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 id: tags:
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 id: tags:
``` python
``` octave
Z2 = zeros(9, 7);
Z2(2, 3:7) = V_ligne
```
%% Cell type:code id: tags:
``` python
``` octave
Z2(4:8, 1) = V_colonne
```
%% Cell type:code id: tags:
``` python
``` octave
Z2(5:6, 3:7) = M
```
%% Cell type:markdown id: tags:
Il est possible d'extraire une sous-matrice en indiquant les plages d'indices désirées. Par exemple :
%% Cell type:code id: tags:
``` python
``` octave
Z2(3:8, 1:5)
```
%% Cell type:markdown id: tags:
On peut également indiquer un pas. Essayez de prédire ce que renvoie l'instruction suivante puis exécutez-la :
%% Cell type:code id: tags:
``` python
``` octave
Z2(2:2:6, 3:2:7)
```
%% Cell type:markdown id: tags:
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 id: tags:
``` python
``` octave
A = [3 4 2; 5 5 5; 9 0 3]
Z2(2:2:6, 3:2:7) = A
```
%% Cell type:markdown id: tags:
La longueur d'un vecteur peut être obtenue par la fonction **length** :
%% Cell type:code id: tags:
``` python
``` octave
longueur = length(V_ligne)
```
%% Cell type:markdown id: tags:
L'utilisation de **length** sur une matrice est déconseillé car la fonction ne retourne alors que la plus grande dimension de la matrice.
Le **nombre de lignes** et le **nombre de colonnes** d'une matrice peuvent être obtenus avec **size** en faisant :
%% Cell type:code id: tags:
``` python
``` octave
Z3 = zeros(6, 4)
nb_lignes = size(Z3, 1)
nb_colonnes = size(Z3, 2)
plus_grande_dimension = length(Z3)
```
%% Cell type:markdown id: tags:
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 id: tags:
``` python
``` octave
Z3(4, 1:nb_colonnes) = 99
Z3(1:nb_lignes, 2) = -55
```
%% Cell type:markdown id: tags:
On peut utiliser le symbole ":" qui indique de considérer tous les éléments de la ligne (ou de la colonne) :
%% Cell type:code id: tags:
``` python
``` octave
Z4 = zeros(6, 4)
Z4(3, :) = 11
Z4(:, 4) = -33
```
%% Cell type:markdown id: tags:
Enfin, il est possible d'utiliser le mot clé "end" à la place de nb_lignes ou nb_colonnes :
%% Cell type:code id: tags:
``` python
``` octave
Z5 = zeros(6, 4)
Z5(2, 1:end) = 222
Z5(1:end, 1) = 666
```
%% Cell type:markdown id: tags:
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 id: tags:
``` python
``` octave
Z6 = zeros(6, 4)
Z6([2, 5, 7, 12, 13, 14, 19]) = 1
```
%% Cell type:markdown id: tags:
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 id: tags:
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 id: tags:
``` python
``` octave
I = [200 180 170 190 155; 205 190 195 165 150; 210 215 175 155 190]
I <= 177
```
%% Cell type:markdown id: tags:
Pour récupérer les indices des valeurs de I inférieures à 177 avec **find** :
%% Cell type:code id: tags:
``` python
``` octave
find(I <= 177)
```
%% Cell type:markdown id: tags:
On peut alors récupérer les valeurs de I inférieures à 177 en faisant :
%% Cell type:code id: tags:
``` python
``` octave
I(find(I <= 177))
```
%% Cell type:markdown id: tags:
L'instruction suivante, plus épurée, renvoie le même résultat :
%% Cell type:code id: tags:
``` python
``` octave
I(I <= 177)
```
%% Cell type:markdown id: tags:
Ainsi, pour mettre à 0 tous les éléments de I inférieures à 177, on peut écrire :
%% Cell type:code id: tags:
``` python
``` octave
I(I<=177) = 0
```
%% Cell type:markdown id: tags:
qui est la version plus épurée de :
%% Cell type:code id: tags:
``` python
``` octave
I(find(I<=177)) = 0
```
%% Cell type:markdown id: tags:
## 4) Fonctions utiles
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 id: tags:
``` python
``` octave
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]
J1 = J(:) % Vectorisation de J
J2 = reshape(J, 3, 8)
J3 = reshape(J, 6, 4)
J4 = reshape(J, 8, 3)
J5 = reshape(J, 24, 1) % équivalent à J(:)
```
%% Cell type:markdown id: tags:
La fonction **max** permet de récupérer l'élément d'un vecteur (colonne ou ligne) de valeur maximale, ainsi que son indice.
Il s'agit d'une fonction qui peut renvoyer plusieurs sorties, tout comme **size**.
%% Cell type:code id: tags:
``` python
``` octave
W = [4, 12, 3, 7, 6]
```
%% Cell type:markdown id: tags:
Observez les deux syntaxes suivantes et identifiez les différences :
%% Cell type:code id: tags:
``` python
``` octave
valeur_maximale = max(W)
```
%% Cell type:code id: tags:
``` python
``` octave
[valeur_maximale, indice_du_maximum] = max(W)
```
%% Cell type:markdown id: tags:
Si l'on ne précise qu'une seule sortie, **max** ne renvoie que la valeur maximale.
Pour obtenir l'indice du maximum, il faut demander deux sorties entre crochets comme dans la deuxième syntaxe.
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 id: tags:
``` python
``` octave
[~, indice_du_maximum] = max(W)
```
%% Cell type:markdown id: tags:
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 id: tags:
``` python
``` octave
J
maxima = max(J)
[~, indices_maxima] = max(J)
```
%% Cell type:markdown id: tags:
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 id: tags:
``` python
``` octave
W
valeurs_ordre_croissant = sort(W, 'ascend') % Par défaut, sort utilise ascend s'il n'y a pas de 2ème paramètre
valeurs_ordre_decroissant = sort(W, 'descend')
```
%% Cell type:code id: tags:
``` python
``` octave
[valeurs_ordre_croissant, indices_ordre_croissant] = sort(W, 'ascend')
```
%% Cell type:code id: tags:
``` python
``` octave
[~, indices_ordre_croissant] = sort(W, 'ascend')
```
%% Cell type:markdown id: tags:
On peut vérifier que W(indices_ordre_croissant) donne valeurs_ordre_croissant :
%% Cell type:code id: tags:
``` python
``` octave
W(indices_ordre_croissant)
valeurs_ordre_croissant
```
%% Cell type:markdown id: tags:
La fonction **mean** renvoie :
- la moyenne des éléments d'un vecteur lorsqu'elle est utilisée sur un vecteur ;
- les moyennes de chaque colonne ou de chaque ligne d'une matrice lorsqu'elle est utilisée sur une matrice.
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 id: tags:
``` python
``` octave
V = [2 3 5 8 12]
mean(V)
M = [1 3 5 7 9; 2 4 6 8 10]
moyennes_par_colonnes = mean(M, 1)
moyennes_par_lignes = mean(M, 2)
moyennes_par_defaut = mean(M)
```
%% Cell type:markdown id: tags:
De façon similaire, la fonction **sum** renvoie :
- la somme des éléments d'un vecteur lorsqu'elle est utilisée sur un vecteur ;
- les sommes de chaque colonne ou de chaque ligne d'une matrice lorsqu'elle est utilisée sur une matrice.
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 id: tags:
``` python
``` octave
V = [2 3 5 8 12]
sum(V)
M = [1 3 5 7 9; 2 4 6 8 10]
sommes_par_colonnes = sum(M, 1)
sommes_par_lignes = sum(M, 2)
sommes_par_defaut = sum(M)
```
%% Cell type:markdown id: tags:
Ainsi, les moyennes peuvent être calculées soit avec **mean**, soit avec **sum** et **size**.
%% Cell type:code id: tags:
``` python
``` octave
M = [1 3 5 7 9; 2 4 6 8 10];
mean(M, 1)
sum(M, 1)/size(M, 1)
mean(M, 2)
sum(M, 2)/size(M, 2)
```
%% Cell type:markdown id: tags:
## 5) Les boucles **for**
%% Cell type:markdown id: tags:
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 id: tags:
``` python
``` octave
somme = 0;
for i = 1:10
somme = somme + i % Ajouter un ';' en fin de ligne permet d'éviter l'affichage à chaque tour de boucle
end
```
%% Cell type:markdown id: tags:
Cet exemple illustre bien l'intérêt d'ajouter des ';' en fin de ligne pour éviter l'affichage.
Dans l'exemple suivant, nous souhaitons calculer une matrice C qui est la somme de deux matrices A et B.
Nous montrons comment le faire de deux manières différentes :
- avec une boucle **for**
- matriciellement
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 id: tags:
``` python
``` octave
A = rand(2000,1500);
B = rand(size(A));
C = zeros(size(A));
tic
% Avec une boucle for
for i = 1:size(C, 1)
for j = 1:size(C, 2)
C(i, j) = A(i, j) + B(i, j);
end
end
toc
```
%% Cell type:code id: tags:
``` python
``` octave
A = rand(2000, 1500);
B = rand(size(A));
C = zeros(size(A));
tic
C = A + B;
toc
```
%% Cell type:markdown id: tags:
Bien souvent, le fait d'utiliser des boucles **for** augmente les temps de calcul.
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.
Pour illustrer un cas où se passer de boucle **for** n'est pas évident, nous proposons l'exemple d'une quantification d'histogramme.
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.
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 id: tags:
``` python
``` octave
M = rand(800, 600);
Histogramme = zeros(1, 10);
tic
for i = 1:size(M, 1)
for j = 1:size(M, 2)
valeur = floor(M(i, j)*10); % pour obtenir un indice entre 0 et 9
indice = valeur+1; % les indices en Matlab commencent à 1
Histogramme(indice) = Histogramme(indice) + 1;
end
end
toc
```
%% Cell type:code id: tags:
``` python
``` octave
M = rand(800, 600);
Histogramme = zeros(1, 10);
tic
M = repmat(M(:), 1, 10);
intervalles1 = 0:0.1:0.9;
intervalles2 = 0.1:0.1:1;
Histogramme = sum(M >= intervalles1 & M < intervalles2);
toc
```
%% Cell type:markdown id: tags:
Le symbole **&** désigne ici le ET logique.
De la même façon, on peut écrire un OU logique avec le symbole **|**
%% Cell type:markdown id: tags:
## 6) Exemple complet : distance moyenne entre deux points d'un cercle
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.
On se propose de calculer la distance moyenne entre deux points situés sur un cercle de rayon 1.
Pour cela, nous tirons aléatoirement 100 paires de points et calculons les distances entre points, paire par paire.
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 id: tags:
``` python
``` octave
nb_points = 100;
thetas1 = 2*pi*rand(1, nb_points); % Pour tirer nb_points angles entre 0 et 2*pi
thetas2 = 2*pi*rand(1, nb_points); % Pour tirer nb_points autres angles entre 0 et 2*pi
points1 = [cos(thetas1); sin(thetas1)]; % Pour créer nb_points points sur le cercle unité
points2 = [cos(thetas2); sin(thetas2)]; % Pour créer nb_points autres points sur le cercle unité
distances = sqrt(sum((points1 - points2).^2,1));
% (points1 - points2).^2 contient les (x2-x1)^2 sur la première ligne et les (y2-y1)^2 sur la deuxième ligne
% sum(points1 - points2).^2,1) est un vecteur contenant les (x2-x1)^2+(y2-y1)^2
% sqrt(sum(points1 - points2).^2,1)) est un vecteur contenant les Racine((x2-x1)^2+(y2-y1)^2), donc les distances
distance_moyenne = mean(distances)
4/pi % Valeur théorique à trouver
```
%% Cell type:markdown id: tags:
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 id: tags:
## 7) Lecture et affichage d'images
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).
Les valeurs sont prises entre 0 et 255 inclus.
À titre d'exemples :
- (r = 255, g = 0, b = 0) donne du rouge vif
- (r = 255, g = 255, b = 0) donne du jaune vif
- (r = 128, g = 128, b = 128) donne du gris
- pour des images en niveaux de gris, 0 correspond au noir et 255 au blanc
Vous pouvez sélectionner une couleur et obtenir son code RGB sur le site suivant : https://htmlcolorcodes.com/fr/selecteur-de-couleur/
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.
Matlab dispose de quelques images internes.
La lecture d'une image se fait avec la fonction **imread** :
%% Cell type:code id: tags:
``` python
``` octave
I = imread('einstein.jpg')
```
%% Cell type:code id: tags:
``` python
``` octave
imagesc(I);
```
%% Cell type:markdown id: tags:
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.
Il est possible de modifier la palette de couleurs avec l'instruction **colormap** comme suit :
%% Cell type:code id: tags:
``` python
``` octave
colormap gray;
imagesc(I);
```
%% Cell type:markdown id: tags:
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.
Lorsque l'on affiche des images en couleur, il n'y a pas de colormap à gérer.
%% Cell type:code id: tags:
``` python
``` octave
I = imread('fruits.jpg'); % En mettant un ";" après la fermeture de parenthèse, la matrice n'est pas affichée
```
%% Cell type:code id: tags:
``` python
``` octave
imagesc(I);
```
%% Cell type:markdown id: tags:
## 8) Erreurs classiques
On ne parvient pas toujours à écrire un code sans erreur du premier coup.
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.
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 id: tags:
``` python
``` octave
Matrice = 256*rand(320, 240)); % Matrice de nombres aléatoires entre 0 et 256
```
%% Cell type:code id: tags:
``` python
``` octave
% On souhaite ajouter à chaque colonne de A sa colonne suivante. La dernière colonne de A reste inchangée.
Matrice(:, 1:end-1) = Matrice(:, 1:end-1) + matrice(:, 1:end);
```
%% Cell type:code id: tags:
``` python
``` octave
% On souhaite ensuite centrer les valeurs en retirant la valeur moyenne de la matrice obtenue.
Matrice = Matrice - repmat(mean(meen(Matrice)), 320, 240);
```
%% Cell type:code id: tags:
``` python
``` octave
% On souhaite mettre à 0 tous les coefficients négatifs.
(Matrice < 0) = 0;
```
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment