|
Publicité | |||||||||||||||||||||||
|
|
#1 (permalink) |
![]() Date d'inscription: novembre 2006
Localisation: Toulouse, France
Âge: 33
Messages: 10 017
|
C'est bien dommage
![]() Prenons le cas d'une matrice A et d'un vecteur B : Code :
A = [1 2 ; 3 4 ; 5 6 ; 7 8] B = [2 4] Code :
A =
1 2
3 4
5 6
7 8
B =
2 4
Par exemple, une simple soustraction, A - B qui renverrait : Code :
ans =
-1 -2
1 0
3 2
5 4
Code :
>> 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 : Code :
function C = Dut(A,B)
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 : Code :
function C = mr_samurai(A, B) C = A - ones(size(A,1),1)*B; Code :
function C = vinc_mai(A,B) C = A - repmat(B,size(A,1),1); Code :
function C = caroline(A, B)
[m,n] = size(A);
C = zeros(size(A));
for i=1:m
C(i,:) = A(i,:)-B;
end
Code :
function C = tug83(A,B) C = bsxfun(@minus, A, B); Code :
function C = Dut(A,B); C = Dutmex(A,B); Code utilisé pour la comparaison : Code :
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 Code :
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
Code :
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
Code :
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 :
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
Dernière modification par Dut ; 30/10/2008 à 23h28. |
|
|
|
|
#2 (permalink) |
|
Membre émérite
![]() Date d'inscription: décembre 2007
Localisation: ile-de-france
Âge: 26
Messages: 942
|
Salut,
J'ouvre le bal Code :
function C = mr_samurai(A, B)
% Micro-Défi 2
%
if nargin == 0
A = rand(50000,100);
B = rand(1,100);
end
C = A - ones(size(A,1),1) * B;
++
__________________
Matlab 2008b / Vista Dernière modification par mr_samurai ; 05/11/2009 à 15h17. |
|
|
|
|
|
#5 (permalink) | |
![]() Date d'inscription: mars 2007
Localisation: Grasse - FR
Âge: 35
Messages: 6 647
|
Faut pas baisser les bras
![]() En plus la rapidité d'exécution dépendra aussi de la taille des matrices sur lesquelles on travaille : une méthode pourra être bien pour des matrices de grande taille alors qu'une autre sera plus efficace sur des matrices de petite taille. L'énoncé ne donnant pas la taille des matrices.... ![]() Donc moi je me lance (en piquant le début du samurai) : Code :
function C = caroline(A, B)
% Micro-Défi 2
%
%doit retourner C tq C(i,j) = A(i,j) - B(j)
%Gestion des arguments
if nargin == 0
N=50000;
M=100;
A = rand(N,M);
B = rand(1,M);
end
%Vérifier que A et B ont le même nombre de colonnes
[m,n] = size(A);
[p,q] = size(B);
if p~=1 || n~=q
error('pas bon');
return
end
%Note : sans la pré-allocation
%Pour N=500 t=0.1 alors qu'avec t=0.001
%Je n'ai pas eu le courage d'attendre pour N=50000 !
C=zeros(size(A));
for i=1:m
C(i,:) = A(i,:)-B;
end
Citation:
![]() Mais je ne suis pas sure que ce soit toujours vrai suivant les entrées qu'on prendra. |
|
|
|
|
|
#6 (permalink) |
|
Membre émérite
![]() Date d'inscription: décembre 2007
Localisation: ile-de-france
Âge: 26
Messages: 942
|
Voici mon script de test :
Code :
clc
clear
A = rand(50000,100);
B = rand(1,100);
nb = 100;
%---- S1
tic
for z=1:nb
C = A - repmat(B,size(A,1),1);
end
toc
clear C
%---- S2
tic
for z=1:nb
C = zeros(size(A));
for u=1:size(A,1)
C(u,:) = A(u,:) - B;
end
end
toc
clear C
%---- S3
tic
for z=1:nb
C = A - ones(size(A,1),1) * B;
end
toc
clear C
Code :
Elapsed time is 10.358000 seconds. % REMAPT Elapsed time is 10.407000 seconds. % BOUCLE FOR Elapsed time is 8.429000 seconds. % ONES * B .++
__________________
Matlab 2008b / Vista |
|
|
|
|
|
#7 (permalink) |
![]() Date d'inscription: mars 2007
Localisation: Grasse - FR
Âge: 35
Messages: 6 647
|
Ben tu dois avoir une bête de course, avec le même code j'obtiens :
Code :
Elapsed time is 15.810041 seconds.%REPMAT Elapsed time is 13.523129 seconds.%BOUCLE FOR Elapsed time is 14.859095 seconds.%ONES Code :
Elapsed time is 12.789178 seconds. Elapsed time is 13.511811 seconds. Elapsed time is 15.273793 seconds. Pfff...Pô juste. |
|
|
|
|
#8 (permalink) |
|
Membre éprouvé
![]() Date d'inscription: novembre 2007
Messages: 423
|
Voici les temps que j'obtiens
Code 1er essai :
Elapsed time is 14.831326 seconds.%Repmat Elapsed time is 29.354350 seconds.%Boucle for Elapsed time is 13.074401 seconds.%ones Code 2èmeessai :
Elapsed time is 14.202258 seconds. Elapsed time is 28.605043 seconds. Elapsed time is 12.782492 seconds. ones semble être la méthode la plus rapide pour l'instant. La boucle for est vraiment lente chez moi! |
|
|
|
|
#9 (permalink) | |
![]() Date d'inscription: mars 2007
Localisation: Grasse - FR
Âge: 35
Messages: 6 647
|
Citation:
Non par contre il serait intéressant que tu nous donnes : - ta version de MATLAB (Samurai et moi n'avons déjà pas la même) - ton OS (là on a le même) Et puis bon pour le faire proprement il faudrait tout fermer à côté mais personnellement j'ai la flemme donc on va laisser le Responsable juger
|
|
|
|
|
|
#11 (permalink) |
![]() Date d'inscription: juin 2006
Localisation: dans le lubéron
Âge: 30
Messages: 1 541
|
Allez moi aussi je me lance , je vais utiliser bsxfun (une feature dispo depuis la R2007a):
Code :
A = [1 2 ; 3 4 ; 5 6 ; 7 8];
B = [2 4];
C = bsxfun(@minus, A, B)
C =
-1 -2
1 0
3 2
5 4
Dernière modification par Dut ; 07/10/2008 à 14h24. |
|
|
|
|
#12 (permalink) |
|
Membre Confirmé
![]() Date d'inscription: août 2007
Messages: 294
|
Code :
%---- S4
C = zeros(size(A));
tic
for z=1:nb
for u=1:size(A,2)
C(:, u) = A(:, u) - B(u);
end
end
toc
Dernière modification par Dut ; 13/10/2008 à 00h05. |
|
|
|
|
|
#13 (permalink) |
|
Membre Confirmé
![]() Date d'inscription: août 2007
Messages: 294
|
solution utilisant les coordinees homogenes... lente, juste postee a titre informatif
Juste un commentaire en ce qui concerne la solution avec repmat, il existe des version mex plus rapides en general que celle de matlab, voir par exemple http://research.microsoft.com/~minka...re/lightspeed/ Code :
%---- S5
tic
for z=1:nb
% A en coordinees homogenes
hA = [A ones(size(A,1), 1)];
% B en form de matrice
hB = diag(ones(1, numel(B)+1));
hB(end,1:end-1) = -B;
% translation
hC = hA * hB;
% retour aux coordinees usuelles
hC = hC(1:end, 1:end-1);
end
toc
|
|
|
|
|
|
#14 (permalink) |
![]() Date d'inscription: novembre 2006
Localisation: Toulouse, France
Âge: 33
Messages: 10 017
|
Le premier message a été mis à jour avec les temps d'exécution pour des matrices de différentes tailles.
Si certains pouvaient faire tourner la fonction microDefi2.m et me retourner la variable T dans un fichier mat avec la configuration de l'ordinateur (OS, processeur), on pourrait faire un semblant de comparatif par machine A utiliser comme ceci : Code :
T = microDefi2; Code :
num = 6; T = microDefi2(num); Pensez à nettoyer MATLAB avant d'exécuter le code : Code :
clear all
__________________
. Langages : MATLAB - C | Outils : MATLAB R2009a - Code::Blocks (svn 5966) - GCC 4.4.1 | OS : Kubuntu 9.10 - Windows XP SP2 . • J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" (Saint Huck) • Hjartað Hamast (Bamm Bamm Bamm) (traduction française : Le cœur bat) (enfin je crois... je parle pas islandais !) Dernière modification par Dut ; 22/10/2008 à 22h40. |
|
|
|
|
#15 (permalink) |
![]() Date d'inscription: novembre 2006
Localisation: Toulouse, France
Âge: 33
Messages: 10 017
|
Voila une idée que personne ne semble avoir creusé... sans parler d'utiliser un MEX de repmat, je rappelle que les structures itératives peuvent aussi être intégrées dans un fichier MEX...
Quelqu'un veut essayer ?
__________________
. Langages : MATLAB - C | Outils : MATLAB R2009a - Code::Blocks (svn 5966) - GCC 4.4.1 | OS : Kubuntu 9.10 - Windows XP SP2 . • J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" (Saint Huck) • Hjartað Hamast (Bamm Bamm Bamm) (traduction française : Le cœur bat) (enfin je crois... je parle pas islandais !) |
|
|
|
|
![]() |
||
[Défis][2] Pourquoi les matrices et les vecteurs ne s'entendent pas mieux ?
|
||
| Outils de la discussion | |
|
|