2012-11-21 5 views
8

sagen, dass ich eine Funktion foo definiert alsMatlab: Definieren eines Funktionsgriff zurück zweiten Wert einer Funktion zu kontrollieren

[a b] = foo(c). 

Wenn ich eine Funktion hand betrachten

f = @(c)foo(c) 

z.B. verwendet werden in einem cellfun Anruf, was ich bekommen ist ein f äquivalent zu einem foo wie

a = foo(c) 

heißt definiert verhalten, wird der zurückgegebene Wert b verloren.

Wenn daher eine solche f in einem cellfun Anruf gesetzt wird, wird die Ausgangszelle nur die a s und verpassen die b s (über die ich zur Zeit kümmern). Visuell

cellfun(f,input) 

    [a(input{1})]   ? 
    [a(input{2})]   ? 
    ....   b gets killed along the way 

Frage: wie Sie einen Funktionsgriff foo welche Fänge definieren nur die b s? d.h. gibt ein Verhalten analog zu einer Definition von foo wie

b = foo(c) 

d^2, verschwenden die a s.

Darüber hinaus ist es möglich (effizient) sowohl a und b in einem einzigartigencellfun Anruf fangen?

Antwort

4

Von der documentation of cellfun:

[A1, ..., Am] = cellfun (func, C1, ..., Cn) ruft die Funktion von Funktionsgriff func angegeben und gibt Elemente von Zellenanordnungen C1, ..., Cn, wobei n die Anzahl der Eingänge für die Funktion func ist. Ausgangsarrays A1, ..., Am, wobei m die Anzahl der Ausgänge der Funktion func ist, enthält die kombinierten Ausgänge der Funktionsaufrufe.

Also ja, cellfun kann eine Multi-Output-Funktion verwenden und in diesem Fall gibt es einfach eine Anzahl von Ausgängen zurück. Wenn Sie nur den zweiten verwenden möchten, können Sie ~ verwenden, um den ersten zu ignorieren. Das Gleiche gilt für mehrere Ausgaben von anonymen Funktionen - sie werden zurückgegeben, wenn Sie specify multiple output arguments. Hier ist ein einfacher Code:

function test 
    x{1} = 1; 
    x{2} = 2; 
    [~, B] = cellfun(@foo, x); 
    [email protected](c)foo(c); 
    [A, B] = f(1); 

    function [a b] = foo(x) 
     a = x+1; 
     b = x+2; 
    end 
end 
+0

Nizza, es funktionierte, was betrifft die 'cellfun' Anruf; In meinem Fall habe ich '[A, B]' und nicht '[~, B]', meine Matlab-Version unterstützt es nicht. So wird der zweite Punkt erfolgreich beantwortet! Soweit ich sehen kann, gilt das generelle Problem, das zweite zurückgegebene Argument in einer Lambda-Definition zu erhalten. Ist es nicht? – Acorbe

+0

@Acorbe Siehe die aktualisierte Antwort. Es ist genau das gleiche - Sie können die Deklaration einer Funktion nicht ändern, aber Sie können mehrere Ausgaben für Ihren anonymen Funktionsaufruf angeben. – angainor

+0

Nun, das sehe ich .. Ich suche immer noch nach etwas, das nicht das '[A, B] = foo' Zeug machen muss. Hauptsächlich für Retrokompatibilitätsprobleme. In der Tat kann man die Funktion 'foo' in eine andere Funktion (Nicht-Funktions-Handle) einbinden, wobei jedoch der Lambda-Geschmack verloren geht. Danke, dass Sie den Teil des Handbuchs hervorheben, den ich nicht sorgfältig genug gelesen habe. – Acorbe

0

Dies kann durch die Verwendung einer Zellenanordnung, wie die einzelne Ausgabe der Funktion, anstelle eine Funktion mit mehreren Ausgängen durchgeführt werden.

Definieren Sie Ihre Funktion ein Zellenfeld zurückzukehren (oder eine Hilfsfunktion erstellen, die die ursprüngliche Multiple-Output-Funktion aufruft):

function F = foo2(x) 
    [a,b,c] = foo(x); 
    F = {a, b, c}; 
end 

Und dann können Sie einen Griff erstellen, die Ihre Funktion aufruft und bekommt nur eine der Zellen aus dem Zellen-Array.

f = @(x) cell(foo2(x)){2} % This selects the second output 
g = @(x) cell(foo2(x)){3} % This selects the third output 

Das ist fast genau das, wonach Sie gefragt haben. Man könnte sogar einen Griff erstellen, die die n-te Ausgang liefert

f = @(x,n) cell(foo2(x)){n}