Remplacer "ismember" pour plus rapide
Bonjour,
Je cherche à remplacer "ismember" par une technique plus rapide. Supposons que j'aie un vecteur de N valeurs et un vecteur de M valeurs, je veux connaître les indices de N où il y a une des valeurs de M.
Autrement dit :
Cependant, voilà que pour N = 100 valeurs et M = 10 valeurs, je peux faire beaucoup plus rapide :
Code:
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
| clear all;
close all;
clc;
n = 100;
a = randperm(n);
b = ceil(rand(1,ceil(n/10))*n);
na = numel(a);
nb = numel(b);
all(logical((sum(ones(nb,1) * a == b' * ones(1,na),1))) == ismember(a,b))
pause(1);
tic;
for i=1:1e5
logical(sum(ones(nb,1) * a == b' * ones(1,na),1));
end
toc;
pause(1);
tic;
for i=1:1e5
ismember(a,b);
end
toc; |
Code:
1 2
| Elapsed time is 1.049054 seconds.
Elapsed time is 5.080566 seconds. |
Cependant, cela reste vrai pour N et M plus petits que 100. Autrement, la multiplication que j'effectue devient trop lourde (NB : Cette multiplication est plus rapide que "repmat"). En fait, si N = 100 et M = 100, "ismember" devient un peu plus rapide, mais si N = 100 et M = 50, je suis tout de même encore pratiquement deux fois plus rapide que "ismember".
N'y a-t-il pas moyen de faire simple et rapide, du style N(N==M) ? Ce qui ne fonctionne pas puisque M n'est ni un scalaire, ni de même dimension que N et s'il l'était, ça ne fonctionnerait pas plus puisque c'est une comparaison élément par élément.
Bref, je fais la guerre aux boucles "for". "ismember" contient d'ailleurs une boucle "for".
Merci,
Éric