55 votes

Fonction Map dans MATLAB ?

Je suis un peu surpris que MATLAB ne dispose pas d'une fonction Map. J'en ai donc créé une moi-même, car c'est une fonction dont je ne peux pas me passer. Existe-t-il une meilleure version ? Existe-t-il une bibliothèque de programmation fonctionnelle standard pour MATLAB qui m'échappe ?

function results = map(f,list)
% why doesn't MATLAB have a Map function?
results = zeros(1,length(list));
for k = 1:length(list)
    results(1,k) = f(list(k));
end

end

L'usage serait par exemple

map( @(x)x^2,1:10)

91voto

gnovice Points 70970

La réponse courte : la fonction intégrée ARRAYFUN fait exactement ce que votre carte pour les tableaux numériques :

>> y = arrayfun(@(x) x^2,1:10)
y =

     1     4     9    16    25    36    49    64    81   100

Il existe deux autres fonctions intégrées qui se comportent de manière similaire : CELLFUN (qui opère sur les éléments des tableaux de cellules) et STRUCTFUN (qui opère sur chaque champ d'une structure).

Cependant, ces fonctions ne sont souvent pas nécessaires si vous tirez parti de la vectorisation, en particulier en utilisant la méthode des éléments. opérateurs arithmétiques . Pour l'exemple que vous avez donné, une solution vectorisée serait :

>> x = 1:10;
>> y = x.^2
y =

     1     4     9    16    25    36    49    64    81   100

Certaines opérations s'effectuent automatiquement entre les éléments (comme l'ajout d'une valeur scalaire à un vecteur), tandis que d'autres opérateurs ont une syntaxe spéciale pour les opérations par élément (indiquées par un "." devant l'opérateur). De nombreuses fonctions de MATLAB sont conçues pour opérer sur des arguments vectoriels et matriciels à l'aide d'opérations par élément, et ne nécessitent donc pas de fonctions map.

En résumé, voici quelques façons différentes de mettre au carré chaque élément d'un tableau :

x = 1:10;       %# Sample array
f = @(x) x.^2;  %# Anonymous function that squares each element of its input

%# Option #1:
y = x.^2;  %# Use the element-wise power operator

%# Option #2:
y = f(x);  %# Pass a vector to f

%# Option #3:
y = arrayfun(f,x);  %# Pass each element to f separately

Bien sûr, pour une opération aussi simple, l'option 1 est le choix le plus judicieux.

9voto

kwatford Points 11658

En plus des opérations vectorielles et par éléments, il y a également cellfun pour le mappage des fonctions sur les tableaux de cellules. Par exemple :

cellfun(@upper, {'a', 'b', 'c'}, 'UniformOutput',false)
ans = 
    'A'    'B'    'C'

Si 'UniformOutput' est vrai (ou non fourni), il tentera de concaténer les résultats en fonction des dimensions du tableau de cellules, comme suit

cellfun(@upper, {'a', 'b', 'c'})
ans =
ABC

2voto

Dario Points 26259

Vous n'avez pas besoin map puisqu'une fonction scalaire qui est appliquée à une liste de valeurs est appliquée à chacune des valeurs et fonctionne donc de manière similaire à map . Essayez juste

l = 1:10
f = @(x) x + 1

f(l)

Dans votre cas particulier, vous pourriez même écrire

l.^2

2voto

doc Points 21

Une solution assez simple, utilisant la vectorisation de Matlab, serait la suivante :

a = [ 10 20 30 40 50 ]; % the array with the original values
b = [ 10 8 6 4 2 ]; % the mapping array
c = zeros( 1, 10 ); % your target array

Maintenant, en tapant

c( b ) = a

renvoie à

c = 0    50     0    40     0    30     0    20     0    10

c( b ) est une référence à un vecteur de taille 5 avec les éléments de c aux indices donnés par b. Maintenant, si vous attribuez des valeurs à ce vecteur de référence, les valeurs originales de c sont écrasées, puisque c( b ) contient des références aux valeurs de c et aucune copie.

1voto

Dima Points 19888

Si Matlab ne dispose pas d'une fonction map intégrée, c'est peut-être pour des raisons d'efficacité. Dans votre implémentation, vous utilisez une boucle pour itérer sur les éléments de la liste, ce qui est généralement mal vu dans le monde de Matlab. La plupart des fonctions intégrées de Matlab sont "vectorisées", c'est-à-dire qu'il est plus efficace d'appeler une fonction sur un tableau entier que d'itérer sur celui-ci et d'appeler la fonction pour chaque élément.

En d'autres termes, cette

a = 1:10;
a.^2

est beaucoup plus rapide que ce

a = 1:10;
map(@(x)x^2, a)

en supposant votre définition de la carte.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X