2013-02-19 15 views
5

È possibile utilizzare una funzione anonima come funzione evento in Matlab. Quello che voglio fare è fondamentalmenteÈ possibile utilizzare una funzione anonima come funzione evento quando si risolve un ODE in Matlab

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

Tuttavia, questo restituisce un errore lamentando che il numero di uscite a trattare deve corrispondere esattamente. C'è un altro modo per rendere la funzione anonima restituire più argomenti?

risposta

0

Inoltre (questo è molto tardi nel gioco da aggiungere a questo, ma questo mi frustra). Ecco una soluzione con funzioni annidate:

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 

Questa funzione è solo per essere scritta una sola volta (a portata di mano se si deve usare un sacco di diverse funzioni di eventi). Questo può essere usato per generare una funzione di evento anonima all'interno del codice come segue:

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

opts = odeset('Events', events); 

E poi ode45 come al solito.

1

No, non puoi farlo. Le funzioni anonime in Matlab restituiscono sempre un solo valore.

Invece, si potrebbe definire un sottile wrapper deal e superare il tuo involucro come una maniglia:

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

Il punto è che vorrei evitare una funzione wrapper. Usando deal, puoi effettivamente ottenere la funzione anonima per restituire tre valori (poiché deal restituisce solo i suoi argomenti). Tuttavia, il solutore ODE sembra aspettarsi un numero variabile di valori di ritorno mentre l'accordo deve essere esattamente uguale. –

+0

Hai perfettamente ragione. Avrò un'altra occhiata a questo quando avrò un cambiamento. Sospetto che possa essere correlato al fatto che 'ode45' passa un numero variabile di argomenti al gestore di eventi. –

+0

Sospetto che sia dovuto alla funzione valutata con un singolo output in 'odeevents' e con una tripletta di output in' odezero'. Il numero di argomenti di output di una funzione anonima, tuttavia, è uno * o * tre, ma non può gestire entrambi. – embert

2

ho notato questo post cercando la risposta alla stessa domanda. Ciò significa che per alcune persone la domanda potrebbe essere ancora valida. Dal momento che finalmente ho trovato la soluzione da sola, vorrei dare una risposta un po '"obsoleta".

In realtà, sì, è possibile ma non semplice. Prova questo:

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

Non riesco a verificare completamente la compatibilità con le versioni precedenti del codice. Tuttavia, funziona con versioni R2011 e successive di MATLAB.

Problemi correlati