A faster and more straightforward approach is to use NDSolve
as follows. Begin by noting that the first segment of the solution can be computed by
xd[t_?NumericQ] := 1.5;
s1 = NDSolve[[{x'[t] == x[t] (1 - xd[t]), x[0] == 1.5}, x[t], {t, 0, t1] // Values;
where t1 - (2 + Sin[t1]) == 0
. With s1
determined, it becomes possible to compute the next section with
xd[t_?NumericQ] := s1[[0]][t - (2 + Sin[t])]
and integrating from t1
to t2
, where t2 - (2 + Sin[t2]) == t1
. In all, 109 steps are required to reach t = 200
, calculated by
step = Rest@NestList[t /. FindRoot[t - (2 + Sin[t]) == #, {t, Max[#, 2]}] &, 0, 109]
(* {2.5542, 3.88062, 4.89775, 7.89684, ..., 196.712, 198.321, 199.334, 202.268} *)
Of course, executing NDSolve
109 times is both slow and cumbersome, requiring that the 109 solution segments be spliced together. Using NDSolve Components, however, simplifies the computation greatly. It is initialized with
xd[t_?NumericQ] := 1.5;
ndss = First[NDSolve`ProcessEquations[{x'[t] == x[t] (1 - xd[t]), x[0] == 1.5}, x[t], t]];
NDSolve`Iterate[ndss, step[[1]]];
s = First@NDSolve`ProcessSolutions[ndss] // Values;
xd[t_?NumericQ] := s[[0]][t - (2 + Sin[t])]
and completed by iterating through the remaining values of step
Do[NDSolve`Iterate[ndss, step[[i]]];
s = First@NDSolve`ProcessSolutions[ndss] // Values;, {i, 2, 109}]
The iteration requires about 1/40 the time and 1/50 the memory of the approach used to obtain the second plot in my earlier answer. Plotting the final expression for s
in Red
and overlaying it on that second plot yields.
Agreement is excellent except at the tips of some of the highest peaks in the curve. Perhaps, this is due to the higher order interpolation used by NDSolve
. (The earlier answer employs linear interpolation.) The key observation is that the two solutions do not drift apart as t
increases.
The method described here should generalize to most ODEs with time-varying delays, provided that the minimum size of step
elements is not too small.
d[t]
$\endgroup$