C'est bien dommage
Prenons le cas d'une matrice A et d'un vecteur B :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 A = [1 2 ; 3 4 ; 5 6 ; 7 8] B = [2 4]Il est relativement fréquent que l'on soit amené à effectuer une opération entre la première colonne de A ([1 3 5 7]) et la première valeur de B (2) et la seconde colonne de A ([2 4 6 8]) et la seconde valeur de B (4).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 A = 1 2 3 4 5 6 7 8 B = 2 4
Par exemple, une simple soustraction, A - B qui renverrait :
Malheureusement si l'on fait directement la soustraction entre la matrice et le vecteur, MATLAB ne veut rien savoir :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 ans = -1 -2 1 0 3 2 5 4
Il faut donc utiliser une autre méthode : boucle FOR-END, code vectorisé, fonction spéciale...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 >> A-B ??? Error using ==> minus Matrix dimensions must agree.
------------------------------------------------------
Défi : Trouver la méthode la plus rapide pour effectuer une soustraction entre les colonnes d'une matrice et un vecteur
Contrainte : le code devra être contenu dans un fichier m fonction dont le nom sera votre pseudo (si votre pseudo n'est pas accepté comme nom de fonction, prenez un nom similaire ). Cette fonction prendra en argument d'entrée une matrice A et un vecteur B et retournera en argument de sortie une matrice C résultat.
Par exemple, si je (Dut) propose une solution, la première ligne du fichier sera :
Notes :
Code : Sélectionner tout - Visualiser dans une fenêtre à part function C = Dut(A,B)
- les noms de variable A,B,C sont donnés à titre indicatif et peuvent être modifiés
- rien n'empêche de faire appel à d'autres fichiers à l'intérieur de matvec.m
Alors, quelle serait la méthode la plus rapide sous MATLAB selon vous ?
A vous de jouer... donnez vos solutions à la suite de ce message
------------------------------------------------------
Les solutions proposées :
mr_samurai :
vinc-mai :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 function C = mr_samurai(A, B) C = A - ones(size(A,1),1)*B;
Caro-line :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 function C = vinc_mai(A,B) C = A - repmat(B,size(A,1),1);
tug83
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 function C = caroline(A, B) [m,n] = size(A); C = zeros(size(A)); for i=1:m C(i,:) = A(i,:)-B; end
Dut (voir le fichier MEX ici) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 function C = tug83(A,B) C = bsxfun(@minus, A, B);
------------------------------------------------------
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 function C = Dut(A,B); C = Dutmex(A,B);
Code utilisé pour la comparaison :
------------------------------------------------------
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 function [T,users,N] = microDefi2(num) if nargin == 0 num = 7; end % Taille croissante des données N = 10.^(0:num-1); % Données initiales iA = [1 2 ; 3 4 ; 5 6 ; 7 8]; iB = [2 4]; % Membres participant au défi users = {'mr_samurai' 'vinc-mai' 'caroline' 'tug83'}; nusers = numel(users); mt = 5; nT = 1; for n=1:numel(N) % Augmentation de la taille des données au fur et à mesure A = repmat(iA,1,N(n)); B = repmat(iB,1,N(n)); %% Solution de mr_samurai for k=1:mt tic C = mr_samurai(A,B); t(k) = toc; clear C end T(nT,1) = mean(t); %% Solution de vinc-mai for k=1:mt tic C = vinc_mai(A,B); t(k) = toc; clear C end T(nT,2) = mean(t); %% Solution de Caro-line for k=1:mt tic C = caroline(A,B); t(k) = toc; clear C end T(nT,3) = mean(t); %% Solution de tug83 if exist('bsxfun','builtin')==5 % Cette fonction n'est pas disponible avec toutes les versions for k=1:mt tic C = tug83(A,B); t(k) = toc; clear C end T(nT,4) = mean(t); else T(nT,4) = nan; end %% Fin des solutions proposées nT = nT +1; end
Temps d'exécution :
MATLAB R2008a - Windows XP - 2GHz - 2Go Ram
MATLAB R2007a - Windows Vista SP1 - 2GHz - 2Go Ram
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 N mr_samurai vinc-mai caroline tug83 Dut 1 0.000848 0.000932 0.001002 0.000739 0.000249 10 0.000036 0.000076 0.000020 0.000045 0.000012 100 0.000036 0.000081 0.000018 0.000055 0.000019 1000 0.000107 0.000126 0.000053 0.000164 0.000106 10000 0.001491 0.001802 0.000913 0.001691 0.001289 100000 0.021650 0.033351 0.033862 0.018619 0.017151 1000000 0.242351 0.342116 0.294612 0.189642 0.179889
MATLAB R2008b - Linux 64bits - Processeur 8 cœurs
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 N mr_samurai vinc-mai caroline tug83 1 0.166230 0.000183 0.003227 0.002319 10 0.001539 0.000057 0.000020 0.000032 100 0.000035 0.000065 0.000019 0.000045 1000 0.000185 0.000277 0.000150 0.000202 10000 0.003575 0.003802 0.003620 0.002428 100000 0.027099 0.030994 0.028084 0.020660 1000000 0.264510 0.301678 0.280330 0.207564
Matlab 2008a - Linux 32 bits - 3.2GHz - 2Go
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 N mr_samurai vinc-mai caroline tug83 Dut 1 0.000021 0.000043 0.000014 0.000025 0.000009 10 0.000013 0.000039 0.000009 0.000022 0.000008 100 0.000017 0.000042 0.000011 0.000029 0.000014 1000 0.000080 0.000079 0.000042 0.000098 0.000074 10000 0.001122 0.000519 0.000773 0.001603 0.000893 100000 0.017785 0.023169 0.025011 0.011389 0.012374 1000000 0.185730 0.246647 0.260227 0.115151 0.127354
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 N mr_samurai vinc-mai caroline tug83 Dut 1 0.000078 0.000135 0.000062 0.000084 0.000327 10 0.000036 0.000131 0.000026 0.000062 0.000052 100 0.000050 0.000142 0.000039 0.000082 0.000073 1000 0.000222 0.000157 0.000055 0.000193 0.000163 10000 0.002153 0.001704 0.000903 0.001920 0.001592 100000 0.023430 0.027308 0.028055 0.019134 0.018004 1000000 0.247297 0.259067 0.275122 0.186231 0.174071
- N est l'ordre de grandeur du nombre de colonne de A (A possède 4*N colonnes)
- les résultats sont donnés en secondes
------------------------------------------------------
Partager