ddesd giving NaN for all state variables beyond time step 1.
61 次查看(过去 30 天)
显示 更早的评论
The following is my code for a state-dependent delay equation I am working on.
% Parameter set and intialization
%(Q=20, a=5, k=1, ell=10)
tstar = 60.2762; %tstar for b=.03
tspan = [tstar 5000];
options = ddeset(RelTol=1e-12); %Without this extreme tolerance, ddesd never runs at all
sol = ddesd(@ddefun, @dely, @history, tspan, options); %call ddesd
% Print graph
axes
hold on
plot(sol.x,sol.y);
legend('C','n1','m1','n2','m2','tau')
hold off
xlim([0 400])
xlabel('Time (s)')
ylabel('Total Fission Rate (nM/s)')
%ODE which defines behavior before critical time tstar
function dydt = odefun(t,y)
b = .03;
k = 1;
dydt = [-k*y(1)^2 - k*y(1)*y(2) + b*y(3);
k*y(1)^2 - b*y(2);
k*y(1)*(y(1) + y(2)) - b*y(3);
];
end
function dydt = ddefun(t,y,Z) % DDE being solved
b = .03;
k = 1;
a = 5;
ell = 10;
dydt = [a*y(5) - k*y(1) - k*y(1)*(y(2) + y(4)) + b*(y(3) + y(4));
-k*y(1)*(Z(1,1)*exp(-b*y(6)) - y(1)) - b*y(2);
-k*y(1)*(ell*Z(1,1)*exp(-b*y(6)) - y(1) - y(2)) - b*y(3);
k*y(1)*Z(1,1)*exp(-b*y(6)) - a*y(4);
k*y(1)*(ell*Z(1,1)*exp(-b*y(6)) + y(4)) - a*y(5);
1 - y(1)/Z(1,1)
];
end
%-------------------------------------------
function d = dely(t,y) % delay for y
d = t - y(6);
end
%-------------------------------------------
function v = history(t) % history function for t < t0
tstar = 60.2762; %tstar for b=.03
preTstarSol = ode45(@odefun, [0 tstar], [20 0 0]); %Here the ODE is called to create the history of C, n1, and m1
IC1 = @(t) interp1(preTstarSol.x, preTstarSol.y(1,:), t, 'linear');
IC2 = @(t) interp1(preTstarSol.x, preTstarSol.y(2,:), t, 'linear');
IC3 = @(t) interp1(preTstarSol.x, preTstarSol.y(3,:), t, 'linear');
v = [IC1(t);
IC2(t);
IC3(t);
0;
0;
tstar]; %The delay is initialized as "tstar" meaning in the first time step the delay looks back to time 0
end
%-------------------------------------------
As it is written, the solver finds all the state variables to be NaN after time step 1, and prints an empty graph. You may note the rather extreme RelTol=1e-12. However, without a change to the tolerance, nothing happens at all. That is, if you delete "options" from inside ddesd, the code will never finish running and even when you click "STOP" there is no "sol" initialized at all, which implies the code never even runs the first time step of ddesd.
What I can't understand is that a tiny tweak to parameter b and the corresponding tweak to tstar: tstar1 = 37.8275; %tstar for b = .05, it runs just fine and produces the damped oscillations I expect from the system.
Any ideas what could be causing the issue?
0 个评论
采纳的回答
Torsten
2025-11-6,2:07
编辑:Torsten
2025-11-6,10:09
The history function has to cover values for t that are negative (because y6 becomes large and you have to supply y1(t-y6)). But you only supply history data for y1(t), y2(t) and y3(t) between 0 and tstar for t. This means that IC1(t), IC2(t) and IC3(t) will return NaN. Something like
t = 0:0.1:1;
y = t.^2;
interp1(t,y,-2,'linear')
4 个评论
Torsten
about 19 hours 前
编辑:Torsten
about 18 hours 前
Resetting the "ddeset" option of "RelTol=1e-12" makes negative time values in "history" disappear. I nonetheless used an if-statement to avoid possible NaN values returned from "interp1" for the case that parameters might be changed.
Thus your original code would have worked (at least up to t = 800) if you hadn't requested such a stringent precision.
%(Q=20, a=5, k=1, ell=10)
tstar = 60.2762; %tstar for b=.03
tspan = [tstar 800];
preTstarSol = ode45(@odefun, [0 tstar], [20 0 0]);
options = [];%ddeset(RelTol=1e-12);
sol = ddesd(@ddefun, @dely, @history, tspan, options);
axes
hold on
plot(sol.x,sol.y);
legend('C','n1','m1','n2','m2','tau')
hold off
%xlim([0 400])
xlabel('Time (s)')
ylabel('Total Fission Rate (nM/s)')
plot(preTstarSol.x,preTstarSol.y);
legend('C','n1','m1');
function dydt = odefun(t,y)
b = .03;
k = 1;
dydt = [-k*y(1)^2 - k*y(1)*y(2) + b*y(3);
k*y(1)^2 - b*y(2);
k*y(1)*(y(1) + y(2)) - b*y(3);
];
end
function dydt = ddefun(t,y,Z) % equation being solved
b = .03;
k = 1;
a = 5;
ell = 10;
dydt = [a*y(5) - k*y(1) - k*y(1)*(y(2) + y(4)) + b*(y(3) + y(4));
-k*y(1)*(Z(1,1)*exp(-b*y(6)) - y(1)) - b*y(2);
-k*y(1)*(ell*Z(1,1)*exp(-b*y(6)) - y(1) - y(2)) - b*y(3);
k*y(1)*Z(1,1)*exp(-b*y(6)) - a*y(4);
k*y(1)*(ell*Z(1,1)*exp(-b*y(6)) + y(4)) - a*y(5);
1 - y(1)/Z(1,1)
];
end
%-------------------------------------------
function d = dely(t,y) % delay for y
d = t - y(6);
end
%-------------------------------------------
function v = history(t) % history function for t < t0
tstar = 60.2762; %tstar for b=.03
if t < 0
v = [20;
0;
0;
0;
0;
tstar];
return
end
preTstarSol = ode45(@odefun, [0 tstar], [20 0 0]);
% Here is the change I made, having each initial condition function be
% constant at it's time=0 value for all time between -10 and 0.
IC1 = interp1(preTstarSol.x, preTstarSol.y(1,:), t, 'linear');
IC2 = interp1(preTstarSol.x, preTstarSol.y(2,:), t, 'linear');
IC3 = interp1(preTstarSol.x, preTstarSol.y(3,:), t, 'linear');
v = [IC1;
IC2;
IC3;
0;
0;
tstar];
end
%-------------------------------------------
更多回答(0 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


