MATLAB Answers


Saving all the variables from an ode45 Function

Asked by Daniel Bell on 20 Mar 2019
Latest activity Commented on by Jan
on 20 Mar 2019
Hi all,
I am writing a code using the ode 45 function which draws information from a seperate file. I want to save all the values of one of the variables (w) in the function however I can only see the last value. I have put my relevent code for the main file below:
options = odeset('RelTol',ac1,'AbsTol',ac2);
[tw1,yw1] = ode45('Newscript_VectorField',Timet1,Ic1,options)
And the code from my function below this:
function [dy] = Newscript_VectorField(t,y)
global Yi11 Yi12 k_1 c_1 Mass_Matrix c m Stiffness_Matrix A wex Yi21 Yi22 m2 w
w = (y(1)*Yi11)+(y(2)*Yi12);
dw= (y(4)*Yi11)+(y(5)*Yi12);
F_TMD =k_1*(w-y(3))+c_1*(dw-y(6));
%First Natural Frequency
dy(1) = y(4);
dy(2) = y(5);
dy(3) = y(6);
dy(4:5) = Mass_Matrix\(-(c/m)*[y(4);y(5)]-Stiffness_Matrix*[y(1);y(2)]+[Yi21;Yi22]*(Fwxc)-[Yi11;Yi12]*F_TMD);
dy(6) =F_TMD/m2;
Thank you in advance!

  1 Comment

"save all the values of one of the variables (w) in the function" - what does this exactly mean? Remember that ODE45 can reject some steps. Then "saving all" is not useful, when the values are not used for the computations.
Using globals to define parameters is a bad idea. See Answers: Anonymous functions for params

Sign in to comment.





2 Answers

Answer by Torsten
on 20 Mar 2019

[tw1,yw1] = ode45('Newscript_VectorField',Timet1,Ic1,options)
w = yw(:,1)*Yi11 + yw(:,2)*Yi12

  1 Comment

Providing the function to be integrated as char vector is outdated for over 15 years now and still supported for backward compatibility. Prefer a function handle.
+1. The solution is fast and easy.

Sign in to comment.

Answer by Bjorn Gustavsson on 20 Mar 2019

It seems your w is a scalar, and you've defined Yi11 and Yi12 as global constants (warnings should come but I'll assume you have good reasons, strange as those might be). If that's the case, why not just declare Yi11 and Yi12 as globals in the base workspace/calling function where you make the ode45 call, then your array of w ought to be as simple as:
w_all = y(:,1)*Yi11)+(y(:,2)*Yi12;
If your case is more complicated then you might get something useful from changing your Newscript_VectorField to give an additional output when that's called for (I think this will be OK, but havent tested, I don't remember if tests if the odefunction returns jacobians and such if called with multiple outputs, then this idea is broken, if so just write another function for calculating w):
function [dy,W] = Newscript_VectorField(t,y)
% code as above
if nargout 2
W = w;
Then you can first call ode45 to get the trajectory, then call the function time-step by time-step along the trajectory:
for i_t = 1:numel(t)
[dy,w(i_t)] = Newscript_VectorField(t(i_t),yw1(i_t));


Sign in to comment.