2013-02-19 4 views
5

Kann eine anonyme Funktion als Ereignisfunktion in Matlab verwendet werden? Was ich tun möchte, ist im GrundeIst es möglich, eine anonyme Funktion als Event-Funktion beim Lösen einer ODE in Matlab zu verwenden?

opt = odeset('Events', @(t,y) (deal(y(end)-t^2,1,0))); 
[T,Y] = ode45(@odefun,[tstart tend],y0,opt); 

Dies ist jedoch ein Fehler zurückgegeben beschweren, dass die Anzahl der Ausgänge müssen befassen genau angepasst werden. Gibt es eine andere Möglichkeit, die anonyme Funktion mehrere Argumente zurückzugeben?

Antwort

0

Auch (das ist sehr spät im Spiel zu diesem hinzuzufügen, aber das frustriert mich). Hier ist eine Lösung mit verschachtelten Funktionen:

function [ dealfunchandle ] = dealwithit(arrayfunc) 
% Takes as input an event function of (t,z) that returns a 3 array (in same order as event syntax). 

    function [a, b, c] = dealfunc(t,z) 
     output = arrayfunc(t,z); 
     a = output(:,1); 
     b = output(:,2); 
     c = output(:,3); 
    end 

dealfunchandle = @dealfunc; 
end 

Diese Funktion hat nur einmal geschrieben werden (praktisch, wenn Sie viele verschiedene Event-Funktionen verwenden). Dies kann dazu verwendet werden, um eine anonyme Event-Funktion innerhalb des Codes zu erzeugen, wie folgt:

arrayfunc = @(t,y) [y(1), 0, 1]; 
events = dealwithit(arrayfunc); 

opts = odeset('Events', events); 

Und dann ode45 wie pro normal.

1

Nein, Sie können es nicht tun. Anonyme Funktionen in Matlab geben immer nur einen Wert zurück.

Stattdessen könnte man eine dünne Hülle um deal und übergeben Sie Ihren Wrapper als Griff definieren:

function [a b c] = wrapper(t,y) 
    [a b c] = deal('some stop condition', 1, 0); 
end 

opt = odeset('Events', @wrapper); 

[T, Y] = ode45(@odefun, [tstart tend], y0, opt); 
+1

Der Punkt ist, dass ich eine Wrapper-Funktion vermeiden möchte. Mit Deal können Sie tatsächlich die anonyme Funktion erhalten, um drei Werte zurückzugeben (da deal nur seine Argumente zurückgibt). Der ODE-Solver scheint jedoch eine unterschiedliche Anzahl von Rückgabewerten zu erwarten, während der Deal genau abgeglichen werden muss. –

+0

Du hast vollkommen recht. Ich werde mir das nochmal ansehen, wenn ich eine Veränderung bekomme. Ich vermute, dass dies mit der Tatsache zusammenhängen könnte, dass "ode45" eine variable Anzahl von Argumenten an den Event-Handler übergibt. –

+0

Ich vermute, dass es daran liegt, dass die Funktion mit einer einzigen Ausgabe in 'odeevents' und mit einem Ausgabetriplet in' odezero' ausgewertet wird. Die Anzahl der Ausgabeargumente einer anonymen Funktion ist jedoch entweder eins * oder * drei, aber beides kann nicht behandelt werden. – embert

2

ich diesen Beitrag bemerkte für die Antwort auf die gleiche Frage suchen. Dies bedeutet, dass die Frage für einige Leute immer noch gültig ist. Da ich die Lösung schließlich selbst gefunden habe, möchte ich ein bisschen "veraltete" Antwort geben.

Eigentlich ja - es ist möglich, aber nicht einfach. Versuchen Sie dies:

evnt_fun = @ (t, f) subsref ({'einige stop condition', 1, 0}, struct ('type', '{}', 'subs', {{':'} }));

Ich bin nicht in der Lage, die Abwärtskompatibilität des Codes vollständig zu überprüfen. Es funktioniert jedoch mit R2011 und späteren MATLAB-Versionen.