38 votes

poignée de fonction dans MATLAB

Quelqu'un peut-il m'expliquer la signification de l'opérateur @ (function handle) et pourquoi l'utiliser ?

49voto

gnovice Points 70970

El fonction poignée opérateur dans MATLAB agit essentiellement comme un pointeur vers une instance spécifique d'une fonction. Certaines des autres réponses ont abordé quelques-unes de ses utilisations, mais j'ajouterai ici une autre utilisation que j'en fais souvent : maintenir l'accès à des fonctions qui ne sont plus "dans la portée".

Par exemple, la fonction suivante initialise une valeur compter et renvoie ensuite un identifiant de fonction à une fonction imbriquée. incrémenter :

function fHandle = start_counting(count)

  disp(count);
  fHandle = @increment;

  function increment
    count = count+1;
    disp(count);
  end

end

Puisque la fonction incrémenter es un fonction imbriquée il ne peut être utilisé que dans le cadre de la fonction démarrage du comptage (c'est-à-dire l'espace de travail de démarrage du comptage est sa "portée"). Cependant, en renvoyant un handle à la fonction incrémenter je peux toujours l'utiliser en dehors de démarrage du comptage et il conserve toujours l'accès aux variables de l'espace de travail de démarrage du comptage ! Cela me permet de faire ceci :

>> fh = start_counting(3);  %# Initialize count to 3 and return handle
     3

>> fh();  %# Invoke increment function using its handle
     4

>> fh();
     5

Remarquez comment nous pouvons continuer à incrémenter le compte même si nous sommes en dehors de la fonction démarrage du comptage . Mais vous pouvez faire quelque chose d'encore plus intéressant en appelant démarrage du comptage à nouveau avec un numéro différent et en stockant la poignée de la fonction dans une autre variable :

>> fh2 = start_counting(-4);
    -4

>> fh2();
    -3

>> fh2();
    -2

>> fh();  %# Invoke the first handle to increment
     6

>> fh2();  %# Invoke the second handle to increment again
    -1

Remarquez que ces deux compteurs différents fonctionnent indépendamment. La fonction gère fh y fh2 pointent vers différentes instances de la fonction incrémenter avec des espaces de travail différents contenant des valeurs uniques pour compter .

En plus de ce qui précède, l'utilisation de poignées de fonction en conjonction avec des fonctions imbriquées peut également contribuer à rationaliser la conception de l'interface utilisateur graphique, comme je l'illustre dans le document suivant cet autre poste SO .

18voto

Les poignées de fonction sont un outil extrêmement puissant dans Matlab. Un bon début est de lire l'aide en ligne, qui vous donnera bien plus que ce que je peux faire. A l'invite de commande, tapez

doc function_handle

Une poignée de fonction est un moyen simple de créer une fonction en une seule ligne. Par exemple, supposons que je souhaite intégrer numériquement la fonction sin(k*x), où k a une valeur fixe et externe. Je pourrais utiliser une fonction en ligne, mais un identifiant de fonction est beaucoup plus propre. Définir une fonction

k = 2;
fofx = @(x) sin(x*k);

Voyez que je peux maintenant évaluer la fonction fofx à la ligne de commande. MATLAB sait ce qu'est k, nous pouvons donc utiliser fofx comme une fonction maintenant.

fofx(0.3)
ans =
         0.564642473395035

En fait, nous pouvons faire circuler fofx comme une variable. Par exemple, appelons quad pour faire l'intégration numérique. Je vais choisir l'intervalle [0,pi/2].

quad(fofx,0,pi/2)
ans =
         0.999999998199215

Comme vous pouvez le voir, c'est quad qui a fait l'intégration numérique. (Au passage, une fonction en ligne aurait été au moins un ordre de magitude plus lente, et beaucoup moins facile à travailler).

x = linspace(0,pi,1000);
tic,y = fofx(x);toc
Elapsed time is 0.000493 seconds.

À titre de comparaison, essayez une fonction en ligne.

finline = inline('sin(x*k)','x','k');
tic,y = finline(x,2);toc
Elapsed time is 0.002546 seconds.

L'avantage d'une poignée de fonction est que vous pouvez la définir à la volée. Minimiser la fonction cos(x), sur l'intervalle [0,2*pi] ?

xmin = fminbnd(@(x) cos(x),0,2*pi)
xmin =
          3.14159265358979

Il existe de très nombreuses autres utilisations des poignées de fonction dans MATLAB. Je n'ai fait qu'effleurer la surface ici.

15voto

Dan Vinton Points 11975

Avertissement : code non testé...

L'opérateur de gestion des fonctions vous permet de créer une référence à une fonction et de la faire circuler comme n'importe quelle autre variable :

% function to add two numbers
function total = add(first, second) 
    total = first + second;
end

% this variable now points to the add function
operation = @add;

Une fois que vous avez un handle de fonction, vous pouvez l'invoquer comme une fonction normale :

operation(10, 20); % returns 30

L'un des avantages des gestionnaires de fonctions est que vous pouvez les faire circuler comme n'importe quelle autre donnée, ce qui vous permet d'écrire des fonctions qui agissent sur d'autres fonctions. Cela vous permet souvent de séparer facilement la logique commerciale :

% prints hello
function sayHello 
    disp('hello world!');
end

% does something five times
function doFiveTimes(thingToDo) 
    for idx = 1 : 5 
        thingToDo();
    end
end

% now I can say hello five times easily:
doFiveTimes(@sayHello);

% if there's something else I want to do five times, I don't have to write
% the five times logic again, only the operation itself:
function sayCheese 
    disp('Cheese');
end
doFiveTimes(@sayCheese);

% I don't even need to explicitly declare a function - this is an 
% anonymous function:
doFiveTimes(@() disp('do something else'));

El Documentation Matlab contient une description plus complète de la syntaxe Matlab, et décrit d'autres utilisations des gestionnaires de fonctions, comme les rappels graphiques.

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