goMatlab - Mein MATLAB Forum

Mein MATLAB Forum

 
Login  | Registrieren
Bücher:


Fachkräfte:
Testingenieur (w/m) Testframework für Simulink-basierte Echtzeitanwendungen
Pflege des MATLAB/Simulink-Testframeworks, Spezifizieren von Testkriterien, Testfällen und Testszenarien
dSPACE GmbH - Paderborn

Softwareentwickler MATLAB/Simulink (w/m)
Erarbeitung von Lösungen im Bereich der Schnittstelle zum Simulink-Modell und der Benutzeroberfläche von TargetLink
dSPACE GmbH - Paderborn

Testingenieur (w/m) Konfigurationswerkzeuge für Echtzeitsysteme
Einbinden von Simulink®-Simulationsmodellen, Verteilung der Simulationsmodelle auf Multicore- und Multiprozessorsysteme
dSPACE GmbH - Paderborn

Projektleiter/in im Bereich Embedded Software-Entwicklung Automotive
Entwicklung von Funktionen im Bereich der Embedded Antriebssteuergeräte-Entwicklung
ESG Elektroniksystem- und Logistik-GmbH - München

Senior Systemingenieur/in
Entwicklung von Funktionen im Bereich Antrieb Automotive
ESG Elektroniksystem- und Logistik-GmbH - München

weitere Angebote

Partner:




Vermarktungspartner


Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Tutorial: Keine Angst vor dem function handle

 

Bijick
Moderator
Moderator


Beiträge: 914
Anmeldedatum: 18.06.07
Wohnort: Nürnberg
Version: R2006b, R2008b
     Beitrag Verfasst am: 14.12.2007, 17:01     Titel: Tutorial: Keine Angst vor dem function handle
  Antworten mit Zitat      
Dieses Tutorial möchte zwei Fragen zu einem sehr nützlichen Instrument beantworten, das Matlab-Neuling zunächst leider nur verwirrt:

    1. Was ist ein function handle?
    2. Wofür braucht man das und wie programmiert man das?


Los geht's.

Was also ist ein function handle?
Das englische Wort "handle" bedeutet zunächst mal Griff, "to handle" steht für handhaben, verarbeiten oder beherrschen. Folgerichtig dient ein function handle dazu, eine Funktion in den Griff zu bekommen, sie handhaben und verarbeiten zu können. Diese Funktionen können gleichermaßen Matlab-Funktionen (exp, sin, polyval,...) und eigene Funktionen (mit Schlüsselwort function oder anonyme) sein. Hier die Syntax und einige Beispiele:
Code:
% Syntax
handle = @functionname
handle = @(arglist) anonymous_function

% Beispiele
h1 = @sin;
h2 = @myfun;     % dazu beispielsweise function f = myfun(x), f = prod(cos(x))+sum(x.^2);
h3 = @(x,y) 3*x.*y+2*x-y+4;


h1, h2 und h3 sind damit "ganz normale Variablen", deren Einträge function handles sind. Man kann sie zwar nicht addieren etc. aber beispielsweise an andere Funktionen übergeben. Und damit kommen wir zur zweiten Frage.

Wann und wie verwendet man function handles?
Man braucht sie überall dort, wo die Funktion selbst variabel sein soll, also mal die eine, mal eine andere Funktion verwendet werden soll. Ein einfaches Beispiel ist die Nullstellensuche. Von was soll nämlich eine Nullstelle gefunden werden? Von einer Funktion. Um Matlab nun "mitzuteilen", von welcher Funktion eine Nullstelle gesucht ist, übergibt man an fzero ihr function handle. (fzero ist die in Matlab implementierte Nullstellensuche.) Das geht so:

Code:
h1=@sin;
x_start = 3;
x0 = fzero(h1,x_start)

% oder x0 = fzero(@sin,3)
 

So übergibt man auch die Zielfunktionen an alle Matlab-Optimierungsalgorithmen.

Ein weiterer Anwendungsfall tritt auf, wenn ein unbekannter Benutzer (oder man selbst in der Zukunft) die Funktion bestimmt, mit der etwas geschehen soll. Angenommen, wir sollen eine Graphikfunktion schreiben, die zu einer (univariaten) Funktion den Graphen über einem angegebenen Intervall zeichnet. Dann könnten wir erst mal versuchen, mit switch alle Fälle abzufangen:
Code:
function graph(fstring, range)
t = linspace(range(1),range(2),100);
switch fstring
case 'sin'
plot(t,sin(t));
case 'cos'
plot(t,cos(t));
case 'exp'
plot(t,exp(t))
end
 

Aufgerufen würde graph beispielsweise so:
Code:
Intervall=[-pi,pi];
fstring='sin';
graph(fstring,Intervall)
 

Aber der Benutzer könnte ja auch eine ganz andere Funktion eingeben. Wie können wir unsere Funktion für beliebige Graphen erweitern? Mit dem function handle natürlich.
Code:
function graph(fhandle,range)
t = linspace(range(1),range(2),100);
plot(t,fhandle(t))


Aufgerufen würde graph dann so:
Code:
Intervall=[-pi,pi];
fh=@(x) exp(x.^2);
graph(fh,Intervall)


Man sieht an "fhandle(t)", dass man für Funktionsauswertungen den "Griff" fhandle genauso verwenden kann wie den Funktionsnamen selbst.

War doch gar nicht so schwer, oder?


Fragen und Bemerkungen sind natürlich erwünscht. Ich versuche dann, das Tutorial dementsprechend zu verbessern.
_________________

>> why
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden


Dory
Gast

Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.11.2009, 12:35     Titel: Welchen Vorteil
  Antworten mit Zitat      
Hallo,

erstmal super, dass es deinen Beitrag gibt, hat mir immerhin schon mal ein bisschen weitergeholfen.
Aber ich verstehe leider immernoch nicht, was jetzt der letztendliche Vorteil eines function handles ist.
Könntest mir da vielleicht noch auf die Sprünge helfen? Dass es letztendlich doch noch klick macht?

Danke!
 
Titus
Forum-Meister
Forum-Meister

Beiträge: 853
Anmeldedatum: 19.07.07
Wohnort: Aachen
Version: ---
     Beitrag Verfasst am: 04.11.2009, 17:22     Titel:
  Antworten mit Zitat      
Hallo,

meine Lieblingsanwendung ist die Kombination von anonymen Funktionen und den sogenannten Functionfunctions, also Funktionen, die eine Funktion als Argument brauchen (fzero, fminsearch, ode45 etc.).
Nehme an, ich habe eine Datei geschrieben, die so aussieht:
Code:
function y = myComplicatedFunction(x, a)
y = a * exp(x);
 

Diese möchte ich integrieren von 0 bis 2. Aber: quad will eine Funktion übergeben haben, die nur von x abhängt. Wenn ich also probiere:
Code:
a = 2;
val = quad(@myComplicatedFunction, 0, 2);
 

oder (wie früher, einfach nur den Funktionsnamen übergeben):
Code:
a = 2;
val = quad('myComplicatedFunction', 0, 2);
 

gibt es einen Fehler. Der Ausweg: entweder noch ein M-File schreiben, oder eine anonyme Funktion on the fly generieren:
Code:
a = 2;
val = quad(@(x) myComplicatedFunction(x, a), 0, 2);
 


Der zweite Vorteil gegenüber dem String als Funktionsnamen ist der scope (hier wirds etwas komplizierter): wenn ich obiges in einer M-Function mache, wobei myComplicatedFunction eine Unterfunktion ist, dann funktioniert das nur mit dem function handle, selbst wenn wir die Problematik mit dem extra Parameter mal weglassen:
Code:
function callMySimpleFunction

% folgendes funktioniert
val = quad(@mySimpleFunction, 0, 2);

% folgendes funktioniert nicht:
val = quad('mySimpleFunction', 0, 2);

function y = mySimpleFunction(x)
a = 2;
y = a * exp(x);
 


Warum? Der Functionhandle schaut nach, was "mySimpleFunction" ist, in dem Moment, wo er erzeugt wird. Zu dem Zeitpunkt ist die Unterfunktion bekannt. Der String wird erst aufgelöst beim Funktionsaufruf. Aber innerhalb von quad ist die Unterfunktion aus einer anderen Datei nicht bekannt und es gibt einen Fehler.

Titus
Private Nachricht senden Benutzer-Profile anzeigen
 
maecky
Gast

Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 07.12.2009, 12:17     Titel:
  Antworten mit Zitat      
Hi, ich weiss, der Thread ist schon aelter aber meine Frage passt hier super rein Wink.

Ich verwende die Matlab Funktion colfilt und diese nimmt ja auch ein function handle.

Code:

Img(:,:,1) = uint8(colfilt(Img(:,:,1),[25 25],'sliding', @myFilter));
 


und dann habe ich eine Implementation von myFilter, die eine Matrix SubImg uebernimmt (die er von colfilt bekommt).
Code:

function[rueck] = myFilter(SubImg)
 


Jetzt wuerde ich noch gerne extra Parameter uebergeben, die ich selbst bestimme.
Irgendwas in der Art:
Code:

function[rueck] = myFilter(SubImg, x, y)
 

Und diese Parameter (x und y) wuerde ich gerne beim Aufruf von colfilt mitgeben.
Geht das ueberhaupt?
Kann mir wer weiterhelfen?

Danke im Voraus
lG maecky
 
Fragewurm
Forum-Century
Forum-Century

Beiträge: 180
Anmeldedatum: 23.09.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 07.12.2009, 12:24     Titel:
  Antworten mit Zitat      
Hi
versuch mal das
Code:

...,{@myFilter,x,y})
 


Gruss Fragewurm
_________________

Fehler jeglicher Art Dienen zur allgemeinen Belustigung
Private Nachricht senden Benutzer-Profile anzeigen
 
maecky
Forum-Newbie
Forum-Newbie

Beiträge: 5
Anmeldedatum: 07.12.09
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 07.12.2009, 12:33     Titel:
  Antworten mit Zitat      
Hi,
danke fuer die rasche Antwort, wenn man die geschwungenen Klammern weglaesst funktioniert es, ansonsten nicht Wink

Aber dein Ansatz hat mich auf die richtige Loesung gebracht, thx Wink

Code:

I(:,:,1) = uint8(colfilt(I(:,:,1),[x y],'sliding', @myFilter, x, y));
 



Gruss, Maecky
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Options and Permissions
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.


goMatlab ist ein Teil des goForen-Labels
goForen.de goMATLAB.de goLaTeX.de goPCB.de


 Impressum  | Werbung/Mediadaten | Studentenversion | FAQ | goMatlab RSS Button RSS


Copyright © 2007 - 2012 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks
Partner: LabVIEWforum.de

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.