Delay Differential Equations Part I: Constant Lags L.F. Shampine Department of Mathematics Southern Methodist University Dallas, Texas 75275 shampine@smu.edu www.faculty.smu.edu/shampine
Delay Differential Equations Delay differential equations (DDEs) with constant lags τ j > 0 for j = 1,...,k have the form y (t) = f(t,y(t),y(t τ 1 ),...,y(t τ k )) An early model of the El Niño/Southern Oscillation phenomenon with a physical parameter α > 0 is T (t) = T(t) αt(t τ) A nonlinear ENSO model with periodic forcing is h (t) = a tanh[κh(t τ)] + b cos(2π ω t)
Analytical Solutions and Stability Linear, homogeneous, constant-coefficient ODEs have solutions of the form y(t) = e λt. Any root λ of the characteristic equation provides a solution. This polynomial equation has a finite number of roots. The characteristic equation for linear, homogeneous, constant-coefficient DDEs is transcendental. Generally there are infinitely many roots λ. El sgol ts and Norkin give asymptotic expressions for these roots. The differential equation is stable if all roots of the characteristic equation satisfy Re(λ) β < 0. It is unstable if for some root, Re(λ) > 0.
Example Substituting y(t) = e λt into the neutral DDE leads first to y (t) = y (t 1) + y(t) y(t 1) λe λt = λe λt λ + e λt e λt λ and then to the characteristic equation ( (λ 1) 1 e λ) = 0 The roots are 1 and 2πin for integer n. cos(2πnt) and sin(2πnt) are solutions for any integer n.
History An initial value y(a) = φ(a) is not enough to define a unique solution of y (t) = f(t,y(t),y(t τ 1 ),...,y(t τ k )) on an interval a t b. We must specify y(t) = φ(t) for t a so that y(t τ j ) is defined when a t a + τ j. The function φ(t) is called the history of the solution. The Fortran 90 program dde_solver and the two MATLAB programs allow the history argument to be provided as either a constant vector or a function.
Solving DDEs in MATLAB dde23 solves DDEs with constant lags on [a,b]. This is much like solving ODEs with ode23, but You must input the lags and the history. The end points must satisfy a < b. Output is always in the form of a solution structure. Solution values are available at mesh points as fields in the structure and anywhere in a t b using deval.
T (t) = T(t) 2T(t 1) function Ex1 lags = 1; tspan = [0 6]; sol1 = dde23(@dde,lags,@history,tspan); sol2 = dde23(@dde,lags,1,tspan); tplot = linspace(0,6,100); T1 = deval(sol1,tplot); T2 = deval(sol2,tplot); tplot = [-1 tplot]; T1 = [1 T1]; T2 = [2 T2]; plot(tplot,t1,tplot,t2,0,1, o ) %--Subfunctions--------------------- function dydt = dde(t,t,z) dydt = T - 2*Z; function s = history(t) s = 1 - t;
Output of Program 25 20 15 10 5 0 5 10 1 0 1 2 3 4 5 6
Coding the DDEs The lag τ j in f(t,y(t),y(t τ 1 ),...,y(t τ k )) is defined as component j of an input vector lags. f is to be evaluated in a function of the form function dydt = ddes(t,y,z) If there are d equations, y is a d 1 vector that approximates y(t). Z is a d k array. Z(:,j) approximates y(t τ j ). ezdde23 is a variant of dde23 with a different syntax for evaluation of the equations: function dydt = ddes(t,y,ylag1,...,ylagk) The d 1 vector ylagj approximates y(t τ j ).
Method of Steps For simplicity we discuss the first-order system y (t) = f(t,y(t),y(t τ)), y(t) = φ(t) for t a On [a,a + τ], this is the ODE y (t) = f(t,y(t),φ(t τ)), y(a) = φ(a) With mild assumptions on f there is a unique solution. On [a + τ,a + 2τ], the term y(t τ) in f is known and the initial value y(a + τ) is known. Repetition shows the existence, uniqueness, and continuous dependence on the data of a solution for all of [a,b].
Propagation of Discontinuities Generally the solution y(t) of y (t) = f(t,y(t),y(t τ)), y(t) = φ(t) for t 0 has a jump discontinuity in y (t) at the initial point lim t 0 y (t) = φ (0) lim t 0+ y (t) = f(0,φ(0),φ(0 τ)) The initial discontinuity propagates. The second derivative has a jump at τ, the third derivative has a jump at 2τ, etc. Discontinuities increase in order for retarded DDEs, but generally they do not if there are delayed terms involving derivatives, neutral DDEs.
Discontinuity Tree Because discontinuities in y (m) (t) affect numerical methods greatly, it is important to track them. Multiple lags interact. 0 {τ 1,τ 2 } {2τ 1,τ 1 + τ 2, 2τ 2 } {3τ 1, 2τ 1 + τ 2,τ 1 + 2τ 2, 3τ 2 }... Numerical methods do not see discontinuities with m sufficiently big, so when solving retarded DDEs, we can cut off branches in the tree of discontinuities. On entry, dde23 works out the tree for its low order RK formulas. It merges values that are close, e.g., lags 2/3 and 2 lead to discontinuities at 2/3 + 2/3 + 2/3 and 2 that are not quite the same.
Special Discontinuities Hairer, Nørsett, Wanner discuss Marchuk s immunology model with φ(t) = max(0, 10 6 + t) for t 0 They ignore the discontinuity in φ (t), but dde23 provides for discontinuities in φ(t). It tracks them into [a, b]. dde23 assumes that y(a) = φ(a), but sometimes we need a different value for y(a). An example will be discussed later. dde23 provides for y(a) φ(a). The jump in y(a) takes longer to smooth out than the usual jump in y (a).
Runge Kutta (RK) Formulas To solve y (t) = f(t,y(t)), start with t 0 = a, y 0 = φ(a). Step from y n y(t n ) to y n+1 y(t n+1 ) at t n+1 = t n + h n. Explicit RK starts with y n,1 = y n, f n,1 = f(t n,y n,1 ) (= y n). Then for j = 2, 3,...,s it forms j 1 y n,j = y n + h n k=1 Finally, y n+1 = y n + h n s j=1 γ jf n,j. β j,k f n,k, f n,j = f(t n + α j h n,y n,j ) If f is smooth enough on [t n,t n+1 ], a formula of order p has y(t n+1 ) = y n+1 + O(h p+1 n ). Step to discontinuities so that f is smooth.
Continuous Extensions Apply a method for ODEs to y (t) = f(t,y(t),y(t τ)). Explicit RK deals well with discontinuities, but how do we approximate the solution at arguments that are not mesh points in terms like y(t n + α m h n τ)? Continuous extensions provide values on t n t t n+1. Cubic Hermite interpolation to y n, y n, y n+1, y n+1 in ode23 is C 1 [a,b] and preserves order of accuracy. dde_solver uses y n+θ = y n + θh s n j=1 γ j (θ)f n,j to approximate y(t n + θh n ). The stages f n,j are reused, but a few more are needed to preserve the accuracy of higher order formulas. Its continuous extension is C 1 [a,b].
Short Lags For efficiency, we want to use the biggest step size h n that will provide an accurate result. If h n is bigger than a lag τ j, one of the arguments of y(t n + α m h n τ j ) may be bigger than t n. The term is then not defined and the explicit RK formula is implicit. Some codes limit h n to make the formula explicit, but this can be very inefficient. Predict values for the delayed terms using the continuous extension of the last step. Use them to evaluate the formula and form the continuous extension for the current step. Use it to correct the delayed terms. Iterate as needed.
Solution Structure A structure (MATLAB) or derived type (Fortran 90) is used to hold all the information needed to evaluate y(t) anywhere from the initial point a to the current point. In dde23, this is just {t n,y n,y n}. This is used for delayed terms during the integration and on return, for evaluating y(t) with deval. Saaty discusses a model of biological reaction to x-rays that has the form y (t) = ay(t) + b[c y(t τ)] for 0 t T and the form y (t) = b[c y(t τ)] for T t. A good way to deal with this is to restart the integration at t = T. By saving the history function (vector), a solution structure can be used as the history argument of dde23. The matter is handled with an auxiliary function in dde_solver.
Rocking Suitcase A two wheeled suitcase often starts to rock from side to side as it is pulled. You try to return it to the vertical by twisting the handle, but your response is delayed. This is modeled as a second order equation in the angle θ(t) of the suitcase to the vertical. Write as a first order system with y 1 (t) = θ(t) and y 2 (t) = θ (t), y 1(t) = y 2 (t) y 2(t) = sin(y 1 (t)) sign(y 1 (t))γ cos(y 1 (t)) β y 1 (t τ) + A sin(ωt + η) The initial history is the constant vector zero.
Nested Function for DDEs The DDEs are coded in a straightforward way using a global variable state which is sign(y 1 (t)). Parameters would be defined in the main program for parameter studies. We could write Z(1) here instead of Z(1,1). function yp = ddes(t,y,z) gamma = 0.248; beta = 1; A = 0.75; omega = 1.37; yp = [y(2); 0]; yp(2) = sin(y(1)) -... state*gamma*cos(y(1))- beta*z(1,1) +... A*sin(omega*t + asin(gamma/a)); end % ddes
Event Location A wheel hits the ground (the suitcase is vertical) when y 1 (t) = 0. The integration is then to be restarted with y 1 (t) = 0 and y 2 (t) multiplied by a coefficient of restitution, here 0.913. The suitcase is considered to have fallen over when y 1 (t) = π/2. Like the ODE solvers, dde23 has event location. This means that during an integration, you can locate solutions of a collection of algebraic equations 0 = g i (t,y,z) by testing for a change of sign and calculating roots with y(t),y(t τ 1 ),...,y(t τ k ) evaluated using continuous extensions.
Nested Function for Events The event function is coded in a straightforward way using the global variable state. When y 1 (t) = 0 we change the sign of state and start another integration. Specifying direction allows us to start from this value. isterminal indicates whether the event is to terminate the integration. function [value,isterminal,direction] =... events(t,y,z) value = [y(1); abs(y(1))-pi/2]; isterminal = [1; 1]; direction = [-state; 0]; end % events
Program, Part I Just like odeset, the function ddeset is used to set options, here events and a more stringent relative error tolerance. function suitcase state = +1; opts = ddeset( Events,@events,... RelTol,1e-5); sol = dde23(@ddes,0.1,[0; 0],[0 12],opts); fprintf([ Kind of Event:,... time\n ]);
Program, Part II while sol.x(end) < 12 if sol.ie(end) == 1 fprintf([ A wheel hit the ground.,... %10.4f\n ],sol.x(end)); state = - state; opts = ddeset(opts, InitialY,... [ 0; 0.913*sol.y(2,end)]); sol = dde23(@ddes,0.1,sol,... [sol.x(end) 12],opts); else fprintf([ The suitcase fell over.,... %10.4f\n ],sol.x(end)); break end end
Program, Part III Note the field for y(t n ). With default tolerances a phase plane plot using just mesh points is a little rough. Nested functions must appear in the body of the main function which must end with end. They make it easy to pass global variables like state and parameters. plot(sol.y(1,:),sol.y(2,:)) xlabel( \theta(t) ) ylabel( \theta (t) ) axis([-1 2-1.5 1.2]) % THE NESTED FUNCTIONS APPEAR HERE. end % suitcase
Output Kind of Event: time A wheel hit the ground. 4.5168 A wheel hit the ground. 9.7511 The suitcase fell over. 11.6704 1 0.5 θ (t) 0 0.5 1 1.5 1 0.5 0 0.5 1 1.5 2 θ(t)