FAQ MATLAB
FAQ MATLABConsultez toutes les FAQ
Nombre d'auteurs : 11, nombre de questions : 172, dernière mise à jour : 29 septembre 2022
- Comment obtenir un tirage aléatoire sur un nombre donné d'éléments d'une matrice ?
- Comment transformer une matrice MxN en vecteur Px1 ?
- Comment arrondir un nombre réel ?
- Comment arrondir un réel à un nombre de chiffres significatifs ?
- Comment obtenir la partie décimale d'un nombre réel ?
- Comment normaliser les valeurs d'une matrice dans l'intervalle [0 1] ?
- Comment obtenir le nombre d'occurrences des valeurs d'une matrice ?
- Comment trouver la valeur minimale (ou maximale) avec sa position ?
- Comment ajouter/supprimer des lignes/colonnes à un tableau ?
- Comment obtenir des valeurs uniques sans les trier ?
- Comment effectuer un tri de valeurs ou de chaînes de caractères ?
- Comment regrouper des éléments selon des valeurs communes ?
Pour obtenir une liste de N éléments tirés aléatoirement d'une matrice, il est possible d'utiliser les fonctions numelDocumentation de la fonction numel et randpermDocumentation de la fonction randperm.
Par exemple, pour obtenir aléatoirement 5 valeurs d'une matrice 4x4 :
% Une matrice 4x4
X = [4 6 6 6
9 0 7 1
7 8 7 7
9 9 3 0];
% Nombre d'éléments à tirer
n = 5;
% Génération de la permutation des indices [1:nombre d'éléments de X]
nX = numel(X);
idx = randperm(nX);
% Sélection des n premiers indices permutés
X(idx(1:n))
Pour transformer une matrice de dimension MxN en un vecteur de dimension Px1 (avec P = MxN), il est possible d'utiliser la fonction reshapeDocumentation de la fonction reshape :
>> X = rand(2,3)
X =
0.2785 0.9575 0.1576
0.5469 0.9649 0.9706
>> X = reshape(X,[],1)
X =
0.2785
0.5469
0.9575
0.9649
0.1576
0.9706
Il est également possible de se servir des propriétés de l'indexage linéaire et de l'opérateur colon : comme ceci :
>> X = rand(2,3)
X =
0.9572 0.8003 0.4218
0.4854 0.1419 0.9157
>> X = X(:)
X =
0.9572
0.4854
0.8003
0.1419
0.4218
0.9157
On note que la matrice est redimensionnée colonne par colonne. Si on souhaite obtenir une réorganisation ligne par ligne, on procédera à une transposition de la matrice avant.
>> X = rand(2,3)
X =
0.7922 0.6557 0.8491
0.9595 0.0357 0.9340
>> X = X.'
X =
0.7922 0.9595
0.6557 0.0357
0.8491 0.9340
>> X = X(:)
X =
0.7922
0.6557
0.8491
0.9595
0.0357
0.9340
Lien : Qu'est-ce que l'indexage linéaire ?
Lien : Qu'est-ce que l'indexage logique ?
Lien : Introduction à la gestion des matrices sous MATLABTutoriel Introduction à la gestion des matrices sous MATLAB
Il existe quatre fonctions différentes pour ne conserver que la partie entière d'un nombre réel : floor, ceil, fix et round.
floorDocumentation de la fonction floor arrondit un nombre réel vers l'infini négatif (-Inf) :
>> x = [-3.9 -2.5 -1.2 0 1.2 2.5 3.9]
x =
-3.9000 -2.5000 -1.2000 0 1.2000 2.5000 3.9000
>> floor(x)
ans =
-4 -3 -2 0 1 2 3
ceilDocumentation de la fonction ceil arrondit un nombre réel vers l'infini positif (+Inf) :
>> x = [-3.9 -2.5 -1.2 0 1.2 2.5 3.9]
x =
-3.9000 -2.5000 -1.2000 0 1.2000 2.5000 3.9000
>> ceil(x)
ans =
-3 -2 -1 0 2 3 4
fixDocumentation de la fonction fix arrondit un nombre réel vers 0 :
>> x = [-3.9 -2.5 -1.2 0 1.2 2.5 3.9]
x =
-3.9000 -2.5000 -1.2000 0 1.2000 2.5000 3.9000
>> fix(x)
ans =
-3 -2 -1 0 1 2 3
roundDocumentation de la fonction round arrondit un nombre réel vers l'entier le plus proche :
>> x = [-3.9 -2.5 -1.2 0 1.2 2.5 3.9]
x =
-3.9000 -2.5000 -1.2000 0 1.2000 2.5000 3.9000
>> round(x)
ans =
-4 -3 -1 0 1 3 4
Pour arrondir un nombre réel à un nombre de chiffres significatifs, il suffit d'appliquer la formule suivante :
x = floor(10^n*x)*10^-n;
Où x représente le nombre réel à arrondir et n le nombre de chiffres significatifs à conserver.
Exemple :
>> x = pi
x =
3.1416
>> n = 2;
>> x = floor(10^n*x)*10^-n
x =
3.1400
Note : on peut remplacer la fonction floorDocumentation de la fonction floor par les autres fonctions d'arrondissage (roundDocumentation de la fonction round ou ceilDocumentation de la fonction ceil) en fonction du comportement désiré.
Attention : la technique ci-dessus ne devrait pas être utilisée pour tester l'égalité entre deux valeurs réelles arrondies. Dans ce cas, on préfèrera la technique suivante pour comparer deux réels A et B avec une précision de n chiffres significatifs :
abs(A-B) < 10^-n;
Lien : Pourquoi 0.3-0.2-0.1 est-il différent de 0 ?
Lien : Comment arrondir un nombre réel ?
La solution la plus simple consiste à soustraire à un nombre réel sa partie entière déterminée avec la fonction fixDocumentation de la fonction fix :
>> x = [-3.9 -2.5 -1.2 0 1.2 2.5 3.9]
x =
-3.9000 -2.5000 -1.2000 0 1.2000 2.5000 3.9000
>> x - fix(x)
ans =
-0.9000 -0.5000 -0.2000 0 0.2000 0.5000 0.9000
Pour ramener les valeurs d'une matrice dans l'intervalle [0 1], on procède ainsi :
M = M - min(M(:));
M = M/max(M(:));
Cette méthode fonctionne quelles que soient les dimensions de la matrice ou du tableau de départ.
Exemple :
>> M = rand(1,2,2)
M(:,:,1) =
0.6787 0.7577
M(:,:,2) =
0.7431 0.3922
>> M = M - min(M(:));
>> M = M/max(M(:));
>> M
M(:,:,1) =
0.7839 1.0000
M(:,:,2) =
0.9600 0
ou en une seule ligne :
M = (M - min(M(:)))/(max(M(:))-min(M(:)));
Bien entendu, cette méthode ne fonctionne qu'avec des matrices et des tableaux de classe permettant le stockage de valeurs réelles. Si on l'emploie avec une variable de classe uint8 par exemple, le résultat ne sera pas bon :
>> M = uint8([1 2 ; 3 4])
M =
1 2
3 4
>> M = M - min(M(:));
>> M = M/max(M(:));
>> M
M =
0 0
1 1
Dans ce cas, il faut convertir la matrice en classe Double avant de faire les opérations :
M = uint8([70 30 149 129
173 127 57 178
167 245 192 227
41 87 65 245])
M = double(M);
M = M - min(M(:));
M = M/max(M(:))
M =
70 30 149 129
173 127 57 178
167 245 192 227
41 87 65 245
M =
0.1860 0 0.5535 0.4605
0.6651 0.4512 0.1256 0.6884
0.6372 1.0000 0.7535 0.9163
0.0512 0.2651 0.1628 1.0000
Lien : Comment trouver la valeur minimale (ou maximale) avec sa position ?
Pour obtenir le nombre d'occurrences de chaque valeur dans un vecteur, on combine les fonctions uniqueDocumentation de la fonction unique et histcDocumentation de la fonction histc comme ceci :
>> V = [1 3 4 3 8 8 1 1]
V =
1 3 4 3 8 8 1 1
>> uV = unique(V)
uV =
1 3 4 8
>> n = histc(V,uV)
n =
3 2 1 2
>> [uV(:) n(:)]
ans =
1 3
3 2
4 1
8 2
Pour une matrice de dimensions quelconques, il suffit juste de faire ceci :
>> V = [1 3 4 3 ; 8 8 1 1]
V =
1 3 4 3
8 8 1 1
>> uV = unique(V)
uV =
1
3
4
8
>> n = histc(V(:),uV) % Utilisation de l'opérateur colon (:)
n =
3
2
1
2
>> [uV(:) n(:)]
ans =
1 3
3 2
4 1
8 2
Dans un vecteur
Afin d'obtenir le minimun/maximum d'un vecteur, il suffit d'utiliser les fonctions minDocumentation de la fonction min et maxDocumentation de la fonction max de MATLAB :
valeurMin = min(vecteur);
valeurMax = max(vecteur);
Si de plus on souhaite obtenir sa position, il faut demander le deuxième argument de sortie de ces mêmes fonctions :
[valeurMin position] = min(vecteur);
[valeurMax, position] = max(vecteur);
Attention : si toutefois il existe plusieurs valeurs égales au minimum/maximum, seule la position de la première trouvée sera retournée. On pourra alors utiliser la fonction findDocumentation de la fonction find pour obtenir les autres positions.
position = find(vecteur==min(vecteur));
position = find(vecteur==max(vecteur));
Il faudra dans ce cas faire attention à la comparaison des nombres réels : Pourquoi 0.3-0.2-0.1 est-il différent de 0 ?
Dans un tableau ND
Si l'on souhaite obtenir les minimums/maximums d'un tableau dont la dimension est supérieure à 1, on utilise de même les fonctions min et max, mais sur le tableau indexé linéairement grâce à l'opérateur colon (symbole« : »).
[valeurMin position] = min(tableau(:));
[valeurMax, position] = max(tableau(:));
Afin de récupérer les coordonnées (i,j,k…) du tableau, on utilise la fonction ind2subDocumentation de la fonction ind2sub sur la position obtenue comme ceci :
[i, j, k, . . .] = ind2sub(size(tableau), position)
Note : ces manipulations sont applicables à n'importe quel tableau (numérique, de cellules, de structures…) et restent valides avec un indexage logique).
-
Ajout d'une ligne à la fin
SélectionnezT = rand(4,7) T(end+1,end) = 0
% Ajout de zéros par défaut
T(end+1,:) = 2% Ajout d'une ligne de 2
T(end+1,:) = rand(1,7)% Ajout d'une nouvelle ligne de valeurs
-
Ajout d'une colonne à la fin
SélectionnezT = rand(4,7) T(end,end+1) = 0
% Ajout de zéros par défaut
T(:,end+1) = 2% Ajout d'une colonne de 2
T(:,end+1) = rand(4,1)% Ajout d'une nouvelle colonne de valeurs
-
Ajout d'une ligne au début
SélectionnezT = rand(4,7) T = [ones(1,7) ; T]
% Ou
T = cat(1 , ones(1,7) , T) -
Ajout d'une colonne au début
SélectionnezT = rand(4,7) T = [ones(4,1) T]
% Ou
T = cat(2 , ones(4,1) , T) -
Insertion d'une ligne
SélectionnezT = rand(4,7) ligne = 2; T = [T(1:ligne-1,:) ; ones(1,7) ; T(ligne:end,:)]
% Ou
T = cat(1 , T(1:ligne-1,:) , ones(1,7) , T(ligne:end,:) ) -
Insertion d'une colonne
SélectionnezT = rand(4,7) colonne = 5; T = [T(:,1:colonne-1) ones(4,1) T(:,colonne:end)]
% Ou
T = cat(2 , T(:,1:colonne-1) , ones(4,1) , T(:,colonne:end) )
Pour des dimensions supérieures, on utilisera essentiellement la fonction catDocumentation de la fonction cat.
Pour effectuer la suppression d'éléments, on leur affecte la valeur vide [] :
-
suppression d'une ligne
SélectionnezT = rand(4,7) ligne = 2; T(ligne,:) = []
-
suppression d'une colonne
SélectionnezT = rand(4,7) colonne = 2; T(:,colonne) = []
Lien : Génération de matrices usuellesTutoriel Génération de matrices usuelles
La fonction uniqueDocumentation de la fonction unique renvoie les résultats uniques triés par ordre croissant plutôt que par ordre d'apparition. L'algorithme utilisé effectue un tri avant de vérifier les valeurs adjacentes égales.
Exemple :
>> A = [9 2 6 7 7 3 2 5 6 9];
>> C = unique(A)
C =
2 3 5 6 7 9
% au lieu de
9 2 6 7 3 5
Pour obtenir les valeurs selon leur ordre d'apparition on peut procéder comme suit :
[~, ia] = unique(A, 'first'
);
ia = sort(ia);
C = A(ia);
[~,ic] = ismember(A,C);
Ou se passer de la fonction unique en procédant ainsi :
[Vs, IX] = sort(A(:));
idx(IX) = [true ; diff(Vs) ~= 0];
ia = find(idx);
C = A(ia);
[~,ic] = ismember(A,C);
Depuis la version R2012a de MATLAB, on peut utiliser le paramètre 'stable'
de la fonction unique :
C = unique(A, 'stable'
);
Dans les deux cas on utilisera la fonction sortDocumentation de la fonction sort.
Pour un tableau de valeurs, à moins de spécifier l'argument dim, la fonction sort effectuera par défaut le tri sur la première dimension de taille > 1. Si l'on souhaite obtenir un tri par valeurs décroissantes, on mettra l'argument mode à 'descend'
.
>> A = [ 3 7 5
6 8 3
0 4 2 ];
>> sort(A) % tri par ordre croissant sur la première dimension par défaut
ans =
% | | |
% v v v
0 4 2
3 7 3
6 8 5
>> sort(A,2) % tri par ordre croissant sur la deuxième dimension
ans =
-> 3 5 7
-> 3 6 8
-> 0 2 4
>> sort(A,2,'descend'
) % tri par ordre décroissant sur la deuxième dimension
ans =
7 5 3 <-
8 6 3 <-
4 2 0 <-
Dans le cas de chaînes de caractères contenues dans un tableau de cellules, le tri se fera selon la table ASCII (ce qui implique que le tri est sensible à la casse).
Il n'est pas possible de spécifier la dimension ni l'ordre du tri, celui-ci se fera sur le tableau de cellules entier de façon linéaire (voir Qu'est-ce que l'indexage linéaire ?) et renverra un vecteur.
>> noms = {'Martin'
, 'Durand'
, 'Dupond'
};
>> prenoms = {'Jacques'
, 'Jean'
, 'Paul'
};
>> sort(noms)
ans =
'Dupond'
'Durand'
'Martin'
>> sort([noms ; prenoms])
ans =
'Dupond'
'Durand'
'Jacques'
'Jean'
'Martin'
'Paul'
Remarque : outre le tableau trié, la fonction sort peut retourner en second argument les indices qui permettent de retrouver le tableau trié à partir du tableau non trié :
>> noms = {'Martin'
, 'Durand'
, 'Dupond'
};
>> [nomsTries, indices] = sort(noms);
>> [noms(indices) ; nomsTries]
ans =
'Dupond'
'Durand'
'Martin'
'Dupond'
'Durand'
'Martin'
ce qui permet de trier un tableau selon une seule ligne ou une seule colonne :
>> nomsPrenoms = {...
'Martin'
, 'Durand'
, 'Dupond'
;
'Jacques'
, 'Jean'
, 'Paul'
};
>> [~, indices] = sort(nomsPrenoms(1,:)); % tri selon les noms (première ligne)
>> nomsPrenoms(:,indices)
ans =
'Dupond'
'Durand'
'Martin'
'Paul'
'Jean'
'Jacques'
L'astuce consiste à combiner les fonctions uniqueDocumentation de la fonction unique et accumarrayDocumentation de la fonction accumarray.
Prenons ce tableau de valeurs :
T = [1 10 4 8
1 1 2 2
1 7 2 2
1 6 7 3
1 8 8 5
2 5 7 8
2 1 4 1
2 1 5 4
2 6 1 3
2 4 8 3
2 8 7 1
3 3 7 4
3 9 1 6
3 3 10 7
3 1 8 8
4 2 6 3
4 3 8 9
4 3 6 2
5 8 2 6
5 7 2 3
6 4 1 10
6 10 8 8
6 2 1 4
7 6 2 7
8 1 9 3
8 8 8 1
9 8 7 5
9 8 4 6
10 1 8 4
10 7 6 8];
pour lequel nous souhaiterions regrouper chaque ligne ayant une première valeur commune.
Nous utilisons dans un premier temps la fonction unique sur la première colonne et récupérons ses premier et troisième arguments de sortie :
[C,~,ic] = unique( T(:,1) );
puis nous utilisons la fonction accumarray permettant de rassembler les valeurs. Dans l'exemple qui suit, nous regroupons celles de la deuxième colonne :
>> groupes = accumarray(ic(:), T(:,2), [numel(C) 1], @(x) {x})
groupes =
[5x1 double] % groupe 1 => [10 ; 1 ; 7 ; 6 ; 8]
[6x1 double] % groupe 2 => [5 ; 1 ; 1 ; 6 ; 4 ; 8]
[4x1 double] % groupe 3 => [3 ; 9 ; 3 ; 1]
[3x1 double] % groupe 4 => [2 ; 3 ; 3]
[2x1 double] % groupe 5 => [8 ; 7]
[3x1 double] % groupe 6 => [4 ; 10 ; 2]
[ 6] % groupe 7 => [6]
[2x1 double] % groupe 8 => [1 ; 8]
[2x1 double] % groupe 9 => [8 ; 8]
[2x1 double] % groupe 10 => [1 ; 7]
Vous obtiendrez en sortie un tableau de cellules dont chaque cellule représente un groupe, vous pourrez par la suite accéder à chaque groupe par groupes{1}, groupes{2}…
À noter qu'au lieu de simplement regrouper les valeurs ensemble, vous pouvez appliquer une fonction particulière dessus, par exemple mean calculant ainsi la moyenne de chaque groupe :
>> groupes = accumarray(ic(:), T(:,2), [numel(C) 1], @mean)
groupes =
6.4000 % mean([10 ; 1 ; 7 ; 6 ; 8])
4.1667 % mean([5 ; 1 ; 1 ; 6 ; 4 ; 8])
4.0000 % mean([3 ; 9 ; 3 ; 1)
2.6667 % mean([2 ; 3 ; 3])
7.5000 % mean([8 ; 7])
5.3333 % mean([4 ; 10 ; 2])
6.0000 % mean([6])
4.5000 % mean([1 ; 8])
8.0000 % mean([8 ; 8])
4.0000 % mean([1 ; 7])
Remarque : vous ne pouvez pas rentrer directement plusieurs colonnes dans la fonction accumarray afin de les regrouper de la même façon, vous pouvez par contre rentrer des indices à la place et les utiliser judicieusement dans la fonction anonyme :
>> indices = 1:size(T,1);
>> groupes = accumarray(ic(:), indices(:), [numel(C) 1], @(idx) {T(idx,:)})
groupes =
[5x4 double]
[6x4 double]
[4x4 double]
[3x4 double]
[2x4 double]
[3x4 double]
[1x4 double]
[2x4 double]
[2x4 double]
[2x4 double]
Lien : Que représente le symbole @ ?
Lien : Comment obtenir des valeurs uniques sans les trier ?