runge kutta _matlab

Upload: ayesh-nayana-gunawardana

Post on 02-Jun-2018

227 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/10/2019 Runge Kutta _Matlab

    1/6

    Runge-Kutta method in MATLAB

    Jakob Kibsgaard

    Many physical problems can be thought of as a system of ordinary differentialequations y(x)=f(x,y) with an initial condition y(0)=y0, where y and f(x,y) aregenerally understood as column vectors. It is therefor of great importance to beable to solve such a system of equations.

    1 Runge-Kutta method

    The simplest method (and least accurate) for integrating such a problem is theEuler method. The derivative at the starting point of each interval is extrapolatedto find the next function value. The method only has first-order accuracy.

    yn+1=yn+hf(xn, yn) (1)

    1

    2

    x x x x1 2 3

    (x)

    h

    Figure 1: The Euler method which advances a solution from xn to xn+1 xn+ h.

    A better way of solving this kind of problem was devised by Runge and Kutta.The methods are one-step methods where the solution y is advanced by one step has y1= y0 + hk, where k is a cleverly chosen constant. The first order Runge-Kuttamethod is simply the Euler method i.e. k= f(x0, y0).

    The second order Runge-Kutta method advances the solution by the use of anauxiliary evaluation of the derivative (see figure 2).

    1

  • 8/10/2019 Runge Kutta _Matlab

    2/6

    1

    2

    x x x x1 2 3

    (x)

    h

    Auxiliary point

    Figure 2: The second order Runge-Kutta method. Second-order accuracy is obtained byusing the initial derivative at each step to find a point halfway across the interval, then

    using the midpoint derivative across the full width h of the interval.

    This gives the following set of equations:

    k0 = f(x0, y0)

    y1/2 = y0+h

    2 k0 (2)

    k1/2 = f(x1/2, y1/2)

    y1 = y0+h k1/2

    Another approach (also of second order) is first to take the full step with theEuler method then calculate the derivative of this point k1=f(x1, y0+hk0). Theaverage between k0 and k1 can now be chosen as the final k =

    1

    2(k0+ k1), which

    then can be used to take the step y1=y0+h k. The following set of equations istherefor obtained:

    k0 = f(x0, y0)

    k1 = f(x1, y0+hk0) (3)

    k = 1

    2(k0+k1)

    y1 = y0+h k

    The two second order methods can be combined to yield a third order method,where the k constant is given as:

    k=1

    6k0+

    4

    6k1/2+

    1

    6k1 (4)

    wherek0, k1/2 and k1 can be found in equation 2 and 3.

    2

  • 8/10/2019 Runge Kutta _Matlab

    3/6

    2 Adaptive Stepsize Control

    In principle one could now use the above equations with the same stepsize h untilthe end point of the given interval is reached. A better approach when computingtime is taken into consideration is to use adaptive stepsize control. By implementing

    this uninteresting parts of the function can be crossed in a few big steps, while theinteresting parts are crossed with small stepsizes. The program therefor tries tothe biggest step without exceeding a certain tolerance specified by the user. Thetolerance is given as:

    tol= (eps | y | +acc)

    h

    b a (5)

    whereepsis relative accuracy andacc is the absolute accuracy specified by the user.The error of a step can be estimated by comparing the solution for a full-step andthat of two half-steps:

    err =

    | y(h) y(2 h2

    ) |

    2k 1 (6)

    If the err > 2 tol the step should be rejected and a new stepsize with h = h2

    should be used. Iferr 2 hCurrent then new stepsize should only be hNext =2 hCurrent.

    3 Generalization

    A higher order ordinary differential equation can be replaced by at set of coupledfirst order differential equations e.g.:

    z = z

    y1=zy2=z

    y1

    =y2y2= y1

    It is very easy to generalize the source code in MATLAB. All there needs to bedone is to replace the ys (numbers) with Ys (vectors) where:

    Y =

    y1y2...

    yn

    and Y =F(x, Y) =

    f1(x, Y)f2(x, Y)

    ...fn(x, Y)

    The initial condition is now also a column vector Y(x0) = Y0. Notice that theks also becomes vectors. The only real (though small) adjustment in the sourcecode apart from changing to vectors is the estimate of the error. The error of a stepis simply the maximum value of the errors for the individual differential equations:

    err = max

    | Y(h) Y(2 h

    2) |

    2k 1

    (8)

    3

  • 8/10/2019 Runge Kutta _Matlab

    4/6

    4 Source Code

    4.1 Solving one first order differential equation

    4.1.1 RK.m

    function [res,err] = RK(a,ya,b,h_0,acc,eps);

    % The function RK.m solves a differential equation. This is done by the

    % Runge-Kutta method, which finds the value y(b) of a function there fulfils dy/dx=f(x,y)% and the initial condition y(a)=ya. All (x,y)-pairs are saved and used in a plot finally.

    % INPUT

    % a: The start-point for the interval we are considering.% ya: The y-value in x=a.

    % b: The end-point of the interval we are considering.

    % h_0: Initial step value.

    % acc: The demanded absolute accuracy.% eps: The demanded relative accuracy.

    % OUTPUT:% Res: The y-value of x=b.% err: The calculated (over all steps) total error.

    % Initialize variablesinc=1;

    err=0;

    x(inc)=a;

    y(inc)=ya;h=h_0;

    inc=2;

    % The first run of the function RKstep.m, which finds the next% (x,y)-pairs and the error for the step by the Runge-Kutta method.

    [x(inc),y(inc),y_old,err_step] = RKStep(x,y,h);

    % Loop to find the following points.while x(inc)2*tol % If the error for the step is too large -> The point (x(inc),Y(inc)) is% calculated again with h=h/2.

    h=h/2;

    if h > (b-x(inc-1)); % Makes sure that the interval end point is not exceeded

    h = b-x(inc-1);end

    inc=inc-1;

    [x(inc),y(inc),y_old,err_step] = RKStep(x(inc-1),y_old,h);else % The previous point is accepted and a new step is found.

    err=sqrt(err^2+err_step^2); % The total error for the entire interval is added up.

    h_old=h;

    h=0.95*(tol/err_step)^0.25*h; % A new step size is found.

    if h>2*h_old % If the increase in h is too large -> h=2*h.h=2*h_old;

    if h > (b-x(inc-1)); % Makes sure that the interval end-point is not exceeded.

    h = b-x(inc-1);end

    [x(inc),y(inc),y_old,err_step] = RKStep(x(inc-1),y(inc-1),h); % The new (x,y) point

    % and the error are found

    % with RKStep.melse

    if h > (b-x(inc-1)); % Makes sure that the interval end-point is not exceeded.

    h = b-x(inc-1);

    end[x(inc),y(inc),y_old,err_step] = RKStep(x(inc-1),y(inc-1),h); % The new (x,y) point

    % and the error are found

    % with RKStep.m

    endend

    end

    err=sqrt(err^2+err_step^2); % The error for the last step is included in the total error.plot(x,y) % The function y(x) is plotted.

    res=y(inc); % The value of y in x=b is written out.

    4

  • 8/10/2019 Runge Kutta _Matlab

    5/6

    4.1.2 RKStep.m

    function [x,y,y_old,err_step] = RKStep(x,y,h);

    % The current y-values are saved in y_old.y_old=y;

    % The y-value in x=x+h is found with a stepsize h:

    k_0=f(x,y);

    k_1=f(x+h,y+h*k_0);k_half=f(x+h/2,y+h/2*k_0);

    k=1/6*k_0+4/6*k_half+1/6*k_1;

    y_h=y+k*h;

    % The y-value in x=x+h is found in two turns, each with a stepsize h/2:

    % First call:

    k_0=f(x,y);k_1=f(x+h/2,y+h/2*k_0);

    k_half=f(x+h/4,y+h/4*k_0);

    k=1/6*k_0+4/6*k_half+1/6*k_1;

    y=y+k*h/2;x=x+h/2;

    % Second call:

    k_0=f(x,y);

    k_1=f(x+h/2,y+h/2*k_0);k_half=f(x+h/4,y+h/4*k_0);

    k=1/6*k_0+4/6*k_half+1/6*k_1;

    y=y+k*h/2;

    x=x+h/2;

    % The error estimate:

    err_step=abs(y_h-y)/7;

    4.2 Solving a set of first order differential equations

    4.2.1 RK2.m

    function [res,err] = RK2(a,ya,ya_diff,b,h_0,acc,eps);

    % The function RK2.m solves a system of differential equations. This is done by the% Runge-Kutta method, which finds the value y(b) of a function there fulfils dy/dx=f(x,y)

    % and the initial condition y(a)=ya. The program saves y-values in the vector Y, Y=[y,y]

    % All (x,y)-pairs are saved and used in a plot finally.

    % INPUT

    % a: The start-point for the interval we are considering.

    % ya: The y-value in x=a.

    % ya_diff: The y-value in x=a.% b: The end-point of the interval we are considering.

    % h_0: Initial step value.

    % acc: The demanded absolute accuracy.

    % eps: The demanded relative accuracy.

    %OUTPUT:

    %Res: The y-value of x=b.

    %err: The calculated (over all steps) total error.

    % Initialize variables

    inc=1;

    err=0;x(inc)=a;

    Y(:,inc)=[ya ; ya_diff];

    h=h_0;

    inc=2;

    % The first run of the function RK2step.m, which finds the next

    % (x,Y)-pairs and the error for the step by the Runge-Kutta method.[x(inc),Y(:,inc),Y_old,err_step] = RK2Step(x,Y,h);

    5

  • 8/10/2019 Runge Kutta _Matlab

    6/6

    % Loop to find the following points.while x(inc)2*tol % If the error for the step is too large -> The point (x(inc),Y(inc)) is

    % calculated again with h=h/2.

    h=h/2;if h > (b-x(inc-1)); % Makes sure that the interval end point is not exceeded

    h = b-x(inc-1);

    end

    inc=inc-1;

    [x(inc),Y(:,inc),Y_old,err_step] = RK2Step(x(inc-1),Y_old,h);else % The previous point is accepted and a new step is found.

    err=sqrt(err^2+err_step^2); % The total error for the entire interval is added up.

    h_old=h;

    h=0.95*(tol/err_step)^0.25*h; % A new step size is found.if h>2*h_old % If the increase in h is too large -> h=2*h.

    h=2*h_old;

    if h > (b-x(inc-1)); % Makes sure that the interval end-point is not exceeded.

    h = b-x(inc-1);end

    [x(inc),Y(:,inc),Y_old,err_step] = RK2Step(x(inc-1),Y(:,inc-1),h); % The new (x,Y) points and the error

    % are found with RK2Step.melse

    if h > (b-x(inc-1)); % Makes sure that the interval end-point is not exceeded.

    h = b-x(inc-1);

    end[x(inc),Y(:,inc),Y_old,err_step] = RK2Step(x(inc-1),Y(:,inc-1),h); % The new (x,Y) points and the error

    % are found with RK2Step.m

    end

    endend

    err=sqrt(err^2+err_step^2); % The error for the last step is included in the total error.

    plot(x,Y(1,:)) % The function y(x) is plotted.

    res=Y(1,inc); % The value of y in x=b is written out.

    4.2.2 RK2Step.mfunction [x,Y,Y_old,err_step] = RK2Step(x,Y,h);

    % The current Y-values are saved in Y_old.Y_old=Y;

    % The y-value in x=x+h is found with a stepsize h:

    k_0=f(x,Y);k_1=f(x+h,Y+h*k_0);

    k_half=f(x+h/2,Y+h/2*k_0);

    k=1/6*k_0+4/6*k_half+1/6*k_1;

    Y_h=Y+k*h;

    % The y-value in x=x+h is found in two turns, each with a stepsize h/2:

    % First call:

    k_0=f(x,Y);k_1=f(x+h/2,Y+h/2*k_0);

    k_half=f(x+h/4,Y+h/4*k_0);

    k=1/6*k_0+4/6*k_half+1/6*k_1;Y=Y+k*h/2;

    x=x+h/2;

    % Second call:

    k_0=f(x,Y);k_1=f(x+h/2,Y+h/2*k_0);

    k_half=f(x+h/4,Y+h/4*k_0);

    k=1/6*k_0+4/6*k_half+1/6*k_1;

    Y=Y+k*h/2;x=x+h/2;

    % The error estimate:

    err_step=max(abs(Y_h-Y)/7);

    6