Passing extra output arguments from ode

37 ビュー (過去 30 日間)
Deepa Maheshvare
Deepa Maheshvare 2020 年 3 月 25 日
編集済み: Stephen 2020 年 3 月 28 日
I've the following code to obtain [t,x] after simulating odes . In addition to the solution, I also want to obtain the functiion values F(x,t) in the below equation.
% obtains the dynamics from a system of odes
x0 = initial values;
tspan = 0:0.0001:0.5;
options = odeset('abstol', 1e-10, 'reltol', 1e-9);
% generate solution
[t, x] = ode15s(@(t,x) fun(t,x), tspan , x0 ,options);
% obtain function values ,f, from ode
[dy f] = fun([ ], [ ])
function [dy f] = fun(t,x)
persistent f
f = []
A = % Matrix
dy = A*x
if nargout >1
f = horzcat(f, A*x)
end
end
In the code, I've defined a persistent variable, f, that stores F for each time step that I solver takes. And I receive f using `[dy f] = fun([ ], [ ])``
But the size of f and x are not equl because from what I understand the output of x is given (after interpolation I guess) only at the time points defined in tspan. Whereas, f is saved for very time instant t that the solver takes internally.
In summary my question is, how do I obtain f for the same time instants at which x is obtained.

採用された回答

Stephen
Stephen 2020 年 3 月 25 日
編集済み: Stephen 2020 年 3 月 25 日
"In summary my question is, how do I obtain f for the same time instants at which x is obtained."
Using a persistent variable or OutputFcn is a red-herring. The simple solution is to call the function after calling the ODE solver, using exactly the values that the ODE solver returns. Here is a complete working example simply based on the first example from the ode15s documentation:
tspan = [0,2];
x0 = 1;
fun = @(t,x) -10*t;
[t,x] = ode15s(fun, tspan, x0)
Then you just need this:
dy = arrayfun(fun,t,x)
  15 件のコメント
Stephen
Stephen 2020 年 3 月 28 日
D is not an input to cellfun or ode15s.
The array D is passed to fun solely via the anonymous function definition, which access D directly from the workspace where the anonymous function is defined. You do NOT need pass D as an input to cellfun.
What you did:
f = cellfun(afun,num2cell(t),num2cell(y,2),num2cell(D),'UniformOutput',false);
% ^^^^^^^^^^^^ does not belong here
What you need to do:
dydt = cellfun(afun,num2cell(t),num2cell(y,2),'UniformOutput',false);
% ^^^^ D is already in this function definition!!!!!!!
I suggest that you read the link I gave you earlier on how to parameterize functions. Then you would get it working in 20 seconds. Making code changes randomly, without understanding how the anonymous function is used, is not an efficient use of your time:

サインインしてコメントする。

その他の回答 (1 件)

Ameer Hamza
Ameer Hamza 2020 年 3 月 25 日
You need to use OutputFcn to get the value of a variable at the same time instant as the value in the output vector: https://www.mathworks.com/help/matlab/ref/odeset.html#d120e857290. Following code shows an example
clear global
global x_vector;
opts = odeset('OutputFcn', @outfcn);
[t,x] = ode45(@(t,x) [x(2); -x(1)], [0, 2*pi], [0; 1], opts);
plot(t, x_vector)
function s = outfcn(t,x,f)
if strcmp(f, 'done')
return
end
global x_vector;
x_vector = [x_vector x(1, :).^2];
s = 0;
end
Note that in this code, I used the global variable to get value out of outfcn, to show a general idea. In practice, global variables are not recommended. I suggest you look at John D'Errico's answer here: https://www.mathworks.com/matlabcentral/answers/510713-is-it-possible-to-store-the-intermediate-values-of-fmincon to see a more efficient way to get value out of the outfcn.

タグ

製品


リリース

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by