Matlab ODE45 function debugging

1 次查看(过去 30 天)
Zhukun Wang
Zhukun Wang 2021-3-20
%Math462 HW3 Q5b
fake_data_vals = [86; 86; 117; 120; 130; 135; 169; 179; 224; 230; 242; 234; 244; 245;
270; 271; 309; 354; 438; 476; 508; 528; 599; 759; 779; 844; 888; 964;
1048; 1093; 1201; 1322; 1437; 1617; 1766; 1835; 1963; 2115; 2225; 2458;
2599; 3052; 3944; 4269; 4366; 4963; 5325; 5843; 6242; 6553; 7157; 7470; 8011;
8376; 8973; 9191; 9911; 10114; 13676; 13540; 13015; 13241; 14068; 14383; 15113;
15319; 15901; 16899; 17111; 17908; 18569; 19463; 20171; 20712; 21261; 21689; 22057;
22460; 22859; 23218; 23694; 23934; 24247; 24666; 24872; 25178; 25515; 25791; 26044;
26277; 26593; 26724; 26933; 27013; 27145; 27237; 27305; 27443; 27514; 27573; 27642;
27705; 27748; 27862; 27929; 27952; 28005; 28073; 28147; 28220; 28295; 28388; 28421;
28454; 28476; 28539; 28571; 28599; 28598; 28601; 28601; 28601; 28604; 28601; 28601;
28601; 28601];
fake_data_times = [1:1:127]';
fake_data = [fake_data_times, fake_data_vals];
%Now we need to run a simulation to compare to the data.
%Initial guesses for the parameters.
%x is our t in the homework problem
alpha0 =0.05;
beta0=0.2;
gamma0=0.125;
N0=50000;
I0=86/N0;
E0=2*I0;
S0=1-I0-E0;
R0=0;
y0=N0*alpha0*E0;
x0=0.2;
%x0 = 0.5;
p0 = [alpha0;beta0;gamma0;I0;E0;S0;R0;y0];
m=[alpha0;beta0;gamma0;N0;I0;E0;S0;R0;y0];
x=[S0,E0,I0,R0,y0];
%do an inital run of the model with the initial values to see how it
%compares to the data
tspan=[1:1:127];
options = odeset('AbsTol',1e-8,'RelTol',1e-8);
df = @(t,x) model_ode(t,x,alpha0,beta0,gamma0);
[~, xsol] = ode45(df, tspan, x0,options);
%plot
clf();
subplot(1,2,1);
plot(tspan,xsol);
hold on;
plot(data_times,data_vals,'o');
title('Initial guess of the model');
xlabel('Time');
ylabel('x(t)');
%now run fminsearch -- maximize the likelihood
minimize_me = @(p) cost_fcn(p,fake_data);
%set some options for fminsearch
options = optimset('Display','iter','MaxFunEvals',5000,'MaxIter',5000);
%run fminsearch
[parvals, NLL] = fminsearch(minimize_me, p0, options);
%spit out the values that best match the data
alphanew = parvals(1);
betanew=parvals(2);
gammanew=parvals(3);
I0new=parvals(4);
E0new=parvals(5);
S0new=parvals(6);
R0new=parvals(7);
y0new=parvals(8);
%display the output of the minimization
disp(parvals);
%re-run the system with the new parameter values
options = odeset('AbsTol',1e-8,'RelTol',1e-8);
df = @(t,x) model_ode(t,x,alphanew,betanew,gammanew);
[~, xsol_new] = ode45(df, tspan, x0_new,options);
%plot the new fit and compare to data
subplot(1,2,2);
plot(tspan,xsol_new);
hold on;
plot(data_times,data_vals,'o');
title('Least Squares Fit');
xlabel('Time');
ylabel('x(t)');
%Below we define two functions that we'll need to do this estimation.
%First, define the differential equation we want to solve, letting it take
%a vector of parameters as an input argument.
function system = model_ode(~,x,params)
alpha = params(1);
beta=params(2);
gamma=params(3);
N=50000;
Sdot=-beta*x(1)*x(2);
Edot=beta*x(1)*x(2)-alpha*x(3);
Idot=alpha*x(3)-gamma*x(2);
Rdot=gamma*x(2);
ydot=N*alpha*x(3);
system=[Sdot;Idot;Rdot;Edot;ydot];
end
function NLL = cost_fcn(params, data)
%define some values
alpha = params(1);
beta=params(2);
gamma=params(3);
N=50000;
I=params(4);
E=params(5);
S=params(6);
R=params(7);
y=params(8);
%interpret the data
times = data(:,1);
vals = data(:,2);
m1=[alpha,beta,gamma];
%find the model values
options = odeset('AbsTol',1e-8,'RelTol',1e-8);
df = @(t,x) model_ode(t,x,alpha,beta,gamma);
[~, xsol] = ode45(df, times, x0,options);
%compare the model to the data
%if we aren't using the sum of squares as the log likelihood, we would
%change the two lower lines to represent whatever likelihood function
%we want to use
res = (xsol - vals).^2;
%compute the square of the differences
NLL = sum(res);
%compute the sum of the squares
end
Could someone help me figure out where are the bugs? I think matlab just does not run. I am not sure about how to use ODE45. I might have defined something wrong but I cannot figure it out.

回答(1 个)

Cris LaPierre
Cris LaPierre 2021-3-20
There are a couple issues with how you've set up your odefunc. You may find this example from the ode45 documentation page helpful.
  1. Your initial conditions need to be the same length as your output (5). Your x0 is a single value.
  2. Your function declaration has to match your function call. Your odefunc expects params to be a vector, but you pass in the values as separate inputs (separated by commas). Perhaps you meant to use varargin? It's not necessary, though.
Here's how I would modify just the ode45 relevant code
alpha0 =0.05;
beta0=0.2;
gamma0=0.125;
x=[0.9948, 0.0034, 0.0017, 0, 8.6000];
tspan=[1 127];
options = odeset('AbsTol',1e-8,'RelTol',1e-8);
df = @(t,x) model_ode(t,x,alpha0,beta0,gamma0);
[t, xsol] = ode45(df, tspan, x,options);
plot(t,xsol)
legend
function system = model_ode(~,x,alpha,beta,gamma)
N=50000;
Sdot=-beta*x(1)*x(2);
Edot=beta*x(1)*x(2)-alpha*x(3);
Idot=alpha*x(3)-gamma*x(2);
Rdot=gamma*x(2);
ydot=N*alpha*x(3);
system=[Sdot;Idot;Rdot;Edot;ydot];
end
  5 个评论
Zhukun Wang
Zhukun Wang 2021-3-20
function or variable 'x0' can't be recognized.
error Math462HW3Q5b>cost_fcn (line 124)
[~, xsol] = ode45(df, times, x0,options);
error Math462HW3Q5b>@(p)cost_fcn(p,fake_data) (line 55)
minimize_me = @(p) cost_fcn(p,fake_data);
error fminsearch (line 200)
fv(:,1) = funfcn(x,varargin{:});
error Math462HW3Q5b (line 59 )
[parvals, NLL] = fminsearch(minimize_me, p0, options);
These are my errors.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Solver Outputs and Iterative Display 的更多信息

标签

Community Treasure Hunt

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

Start Hunting!

Translated by