2016-07-05 9 views
1

Ich finde es unmöglich, MATLAB-Code zu schreiben, ohne eine große Anzahl überflüssiger Variablen für den einmaligen Gebrauch zu erzeugen.Wie erzwingt MATLAB, alle Werte in einem geschachtelten Funktionsaufruf zurückzugeben?

Angenommen, die Funktion foo gibt drei Spaltenvektoren mit exakt derselben Größe zurück. Sprich:

function [a, b, c] = foo(n) 
    a = rand(n, 1); 
    b = rand(n, 1); 
    c = rand(n, 1); 
end 

Nun sei angenommen, dass bar eine Funktion, die (1, 3) als imput eine Zelle Array der Größe erwarten.

function result = bar(triplet) 
    [x, y, z] = triplet{:}; 
    result = x + y + z; 
end 

Wenn ich die Ergebnisse foo(5) übergeben will, kann ich es tun, indem sie drei sonst nutzlose Variablen zu erstellen:

[x, y, z] = foo(5); 
result = bar({x, y, z}); 

Gibt es eine Funktion baz, die mir erlauben würde, die beiden Linien zu ersetzen oben mit

result = bar(baz(foo(5))); 

?

Hinweis: Die obigen Funktionen foo und bar sind nur als Beispiele gedacht. Sie sollen Funktionen darstellen, über die ich keine Kontrolle habe. IOW, sie zu ändern, ist keine Option.

+0

Sind schreiben können diese Funktionen über die Sie keine Kontrolle MATLAB haben oder die Ihre Kollegen ? – excaza

+0

Sind Sie sicher, dass die Funktionen eine konstante Anzahl von Ausgängen zurückgeben, oder kann es auch "Varargout" sein? –

+0

@ Dev-iL: Was würdest du tun, wenn 'foo'' varargout' wäre? – kjo

Antwort

2

Nicht möglich. baz in baz(foo(5)) nimmt nur die erste Ausgabe von foo, die anderen beiden würden ignoriert werden. Die einfache zweizeilige Variante ist nicht so peinlich. Und das ist keine übliche Situation. Normalerweise arbeiten Sie nicht mit Zellenarrays, bei denen normale numerische Arrays ausreichen würden.

Sie könnten natürlich nur Ihre eigenen Wrapper für foo schreiben, die zurückgibt, was Sie brauchen (das heißt ähnlich zwei Zeilen enthält), falls Sie es häufig verwenden müssen.

0

Das Problem besteht darin, dass Sie das Zelltriplet {} in ein Array [] konvertieren, sodass eine Konvertierung die gewünschte Methode ist. Obwohl this method die inverse Transformation durchführt, weiß ich keine Methode, die die gewünschte Transformation ausführen wird, wahrscheinlich aufgrund der relativen Komplexität der Zellendatenstruktur. Vielleicht haben Sie etwas Glück, wenn Sie weiter in die API eintauchen.

EDIT: EBH wies freundlich darauf hin this method, die das tut, was Sie suchen.

EDIT2: Die obige Methode führt die angeforderte Aktion OP nicht aus. Lassen Sie dies, weil die API oft großartige Lösungen bietet, die von schlechten Namen verborgen sind.

+0

Das Problem besteht nicht darin, Zellengruppen in mehrere Variablen zu konvertieren. Das Problem besteht darin, mehrere Ausgaben ohne Zwischenvariablen zu erfassen. –

+0

@ b-bush für die umgekehrte Konvertierung gibt es ['cell2mat'] (http://www.mathworks.com/help/matlab/ref/cell2mat.html) – EBH

+0

Das Problem ist Bar wird nicht akzeptieren, die Ausgabe von foo- -ein Array - also muss diese Ausgabe in eine Zelle konvertiert werden. Die Methode, nach der er fragt, würde genau das tun, hoffentlich ohne Trash-Variablen zu verwenden, wie Sie gesagt haben. Vielleicht hätte ich das in meiner Antwort betonen sollen, aber es ist Thema. –

3

Sie können die drei Variablen durch ein Zellenfeld ersetzen ein comma-separated list mit:

vars = cell(1,3);  % initiallize cell array with as many elements as outputs of foo 
[vars{:}] = foo(5); % comma-separated list: each cell acts as a variable that 
         % receives an output of foo 
result = bar(vars); 
+1

Das ist nicht wirklich was gefragt wurde .. die Frage war, ob es inline, ohne temporäre Variablen getan werden kann. Die Antwort ist einfach, ** nein **. –

+0

@ Nirvana-msu aber er führte eine dritte Funktion 'baz' – EBH

+1

@ebh genau ein. Die Frage war wörtlich, ob es wie 'bar (baz (foo (5))') gemacht werden kann. Auch hier ist die Antwort einfach nein. Was ist der Punkt, der versucht, die Frage zu verdrehen? Es gibt viele andere Fragen, die fragen, wie man mehrere Ausgaben sammelt. –

1

Als nirvana-msu said, es nicht möglich ist, die Aufgabe zu tun, ohne temporäre Variablen zu schaffen. Aber es ist möglich, es innerhalb einer Funktion und sogar mit varargin und varargout zu handhaben.Inspiriert von this answer auf my question können Sie festlegen, und die folgende Funktion verwenden:

function varargout = redirect(F1, F2, count, list, varargin) 
    output = cell(1, count); 
    [output{:}] = F2(varargin{:}); 
    varargout = cell(1, max(nargout, 1)); 
    [varargout{:}] = F1(output(list)); 
end 

Zum Beispiel in Ihrem Beispiel Sie result = redirect(@bar, @foo, 3, [1:3], 5);

Verwandte Themen