The Runge-Kutta methods
Compared with all previous discussed methods for solving a first
order DE
, the Runge-Kutta (RK) methods
can achieve higher accuracies, i.e., the order of error term for
is higher than all previous discussed methods, due to the much
improved approximation of the slope of the secant
between the two end points
and
.
The general iteration of the RK methods takes the following form:
![$\displaystyle y(t+h)=y(t)+\Delta y_t=y(t)+h y'(t+ch)
\approx y(t)+h \sum_{i=1}^s b_i k_i$](img601.svg) |
(226) |
where the slope of the secant
is approximated as the
average of
estimations
of the slope weighted
respectively by
:
![$\displaystyle y'(t+ch)\approx \sum_{i=1}^s b_i k_i$](img605.svg) |
(227) |
These
estimated slopes are obtained recursively, i.e., the ith
estimate
is based on all previous estimates
:
![$\displaystyle k_i=f\left(t+c_ih,\;y+h\;\sum_{j=1}^{i-1} a_{ij} k_j \right),
\;\;\;\;\;\;(i=1,\cdots,s)$](img608.svg) |
(228) |
where
,
and
is the slope of the tangent at
.
This iteration can be expressed in terms of
,
,
, and
:
![$\displaystyle y_{n+1}=y_n+h \sum_{i=1}^s b_i k_i$](img615.svg) |
(229) |
where
Specially when
, we have the forward Euler method:
![$\displaystyle y_{n+1}=y_n+h b_1 k_1=y_n+h f_n$](img626.svg) |
(231) |
The problem of iteratively solving the DE
can also
be viewed as an integral problem which can be solved by certain
quadrature rules:
![$\displaystyle y(t+h)=y(t)+\int_t^{t+h} y'(t)\,dt
=y(t)+\int_t^{t+h} f(t)\,dt\approx y(t)+\sum_{i=1}^s A_i f(t_i)$](img627.svg) |
(232) |
where
is the estimated function value
at
some point inside the interval
, and
is the
corresponding weight.
In general, an s-stage RK method with free parameters
,
and
can be arranged in
the form of a Butcher tableau:
![$\displaystyle \begin{tabular}{c\vert ccccc}
$c_1=0$\ &&&&& \\
$c_2$\ & $a_{21}...
...line
$1$\ & $b_1$\ & $b_2$\ & $\cdots$\ & $b_{s-1}$\ & $b_s$\ \\
\end{tabular}$](img635.svg) |
(233) |
The total number of parameters is
.
We need to find the specific values for these parameters so that the
error term of an s-stage RK method can achieve the highest possible
order in terms of the step size
. This is done by matching the
coefficients of different orders of the
terms in the RK iteration
with those of the corresponding
Taylor expansion
of the function:
![$\displaystyle y(t+h)=y(t)+hy'(t)+\frac{h^2}{2}y''(t)+\frac{h^3}{3!}y'''(t)
+\frac{h^4}{4!}y^{(4)}(t)+O(h^5)$](img637.svg) |
(234) |
where the derivatives of
can be found as:
where
![$\displaystyle f_t=\frac{\partial f}{\partial t},\;\;
f_y=\frac{\partial f}{\par...
...tial t\partial y},\;\;\;
f_{yy}=\frac{\partial^2 f}{\partial y^2},\cdots \cdots$](img652.svg) |
(236) |
Substituting these into the Taylor expansion of
in
Eq. (234), we get different approximations of the
function with truncation errors of progressively higher orders:
These Taylor expansions are then compared with the iterations
of RK methods of different
number of stages
to determine the parameters
required to achieve the highest possible order for the error term.
:
![$\displaystyle y(t+h)=y(t)+h b_1k_1=y(t)+h k_1=y(t)+h\,f(t,\,f)$](img659.svg) |
(241) |
Comparing this with the Taylor expansion in Eq. (238),
we see that if
. This RK1 is simply Euler's forward method
in Eq. (189) with a 2nd order error.
:
Given
, we express
as the Taylor expansion of
the 2-variable function
:
![$\displaystyle k_2=f(t+c_2h,\,y+ha_{21}k_1)=f(t,\,y)+h(c_2f_t+a_{21}f_yf)+O(h^2)$](img664.svg) |
(242) |
and the iterative step of the RK2 method becomes
For the RK2 method to have the third (highest possible) order error,
its coefficients have to match those of the Taylor expansion in Eq.
(239), and we get the following three necessary and sufficient
conditions for the parameters:
![$\displaystyle b_1+b_2=1,\;\;\;\;a_{21}=c_2,\;\;\;\;b_2c_2=b_2a_{21}=\frac{1}{2}$](img668.svg) |
(244) |
There exist multiple solutions for this equation system of three
equations but four unknowns. By introducing a free variable
,
the remaining three variables can be determined as shown in the Butcher's
tableau of the RK2:
![$\displaystyle \begin{tabular}{l\vert lll}
$c_1=0$\ && \\
$c_2=x$\ & $a_{21}=x$\ & \\ \hline
& $b_1=1-1/2x$\ & $b_2=1/2x$\ \\
\end{tabular}$](img670.svg) |
(245) |
Listed below are three of such solutions corresponding to
:
-
, we have
This is the trapezoidal Euler (Heun's) method in
Eq. (199), which can also be obtained
by the trapezoidal rule of
Newton-Cotes quadrature
applied to approximate the integral in the iteration:
![$\displaystyle y(t_{n+1})=y(t_n)+\int_{t_n}^{t_{n+1}} f(t)\,dt
\approx y(t_n)+\frac{h}{2}[f(t_n)+f(t_n+h)]$](img676.svg) |
(247) |
-
, we have
This is the midpoint method in Eq. (218).
-
, we have
This is called Ralston's method.
Given
, we express
and
by their corresponding
Taylor expansions:
Here all terms of
of order higher than two are collected in the
error term
. The iterative step for this RK3 method can now
be written as:
For the RK3 method to have the forth (highest possible) order error, its
coefficients have to match those of the Taylor expansion expansion in
Eq. (240), which can also be written as
![$\displaystyle y(t+h)=y+hf+\frac{h^2}{2}(f_t+f_yf)
+\frac{h^3}{3}f_{ty}f+\frac{h^3}{6}(f_{tt}+f_{yy}f^2+f_yf_t+f_y^2f)+O(h^4)$](img697.svg) |
(252) |
we get the following necessary and sufficient conditions for the
parameters:
Simplifying we get the following 6 independent equations:
There exist multiple solutions for this system of 6 equations but 8
variables, such as the two shown below, known as Kutta's method (left)
and Heun's third order method (right):
![$\displaystyle \begin{tabular}{c\vert cccc}
$c_2=1/2$\ & $1/2$\ && \\
$c_3=1$\ ...
..._3=2/3$\ & $0$\ & $2/3$\ & \\ \hline
& $1/4$\ & $0$\ & $3/4$\ \\
\end{tabular}$](img706.svg) |
(253) |
The RK3 iterations corresponding to the two sets of parameters are
respectively:
![$\displaystyle \left\{ \begin{array}{l}
k_1=f_n\\
k_2=f(t_n+h/2,\;y_n+hk_1/2)\\...
...
k_3=f(t_n+2h/3,\;y_n+2hk_2/3)\\
y_{n+1}=y_n+h(k_1+3k_3)/4
\end{array}\right.$](img707.svg) |
(254) |
We recognize that the first method is simply the Simpson's rule
of Newton-Cotes quadrature
for approximating the integral in the iteration:
![$\displaystyle y(t_{n+1})=y(t_n)+\int_{t_n}^{t_{n+1}} f(t)\,dt
\approx y(t_n)+\frac{h}{6}[f(t_n)+4f(t_n+h/2)+f(t_n+h)]$](img708.svg) |
(255) |
In a similar manner, we can derive (see the next section) the
following eight necessary and sufficient conditions for the
parameters of RK4 method for it to have a 5th order error term:
There exist multiple solutions for this system of eight equations
of 13 variables, such as the classical RK4 and the 3/8 rule
methods listed respectively on the left and right below.
![$\displaystyle \begin{tabular}{c\vert cccc}
$c_2=1/2$\ & $1/2$\ &&& \\
$c_3=1/2...
... $-1$\ & $1$\ & \\ \hline
& $1/8$\ & $3/8$\ & $3/8$\ & $1/8$\ \\
\end{tabular}$](img718.svg) |
(257) |
The RK4 iterations corresponding to the two sets of parameters are
respectively:
![$\displaystyle \left\{ \begin{array}{l}
k_1=f_n\\
k_2=f(t_n+h/2,\;y+hk_1/2)\\
...
...+h,\;y+hk_1-hk_2+hk_3)\\
y_{n+1}=y_n+h(k_1+3k_2+3k_3+k_4)/8
\end{array}\right.$](img719.svg) |
(258) |
We recognize that the second method is simply the application
of the Simpson's 3/8 rule of the
Newton-Cotes quadrature
for approximating the integral in the iteration:
![$\displaystyle y(t_{n+1})=y(t_n)+\int_{t_n}^{t_{n+1}} f(t)\,dt
\approx y(t_n)+\frac{h}{8}[f(t_n)+3f(t_n+h/3)+3f(t_n+2h/3)+f(t_n+h)]$](img720.svg) |
(259) |
From the above we see that up to
, the order of accuracy is
the same as the number of stages of the RK method, e.g., for RK4,
the order of its accuracy is the same as its stage
(with a
5th order error term
) . However, this is not the case for
, as shown in the table below:
![$\displaystyle \begin{tabular}{l\vert ccccccc}\hline
Order of accuracy & 1 & 2 &...
...hline
Number of stages & 1 & 2 & 3 & 4 & 6 & 7 & 9 .... \\ \hline
\end{tabular}$](img723.svg) |
(260) |
The Matlab code for RK4 is shown below as a function which
takes three arguments, the step size
, time moment
and
, and generates the approximation of the next value
with
estimated
by one of the several versions of the RK4 method, based on
another function that calculate
:
function y = RungeKutta4(h, t, y, k)
k1 = f(t, y);
switch k
case 1
k2 = f(t+h/2, y + h*k1/2);
k3 = f(t+h/2, y + h*k2/2);
k4 = f(t+h, y + h*k3);
y = y + h*(k1 + 2*k2 + 2*k3 + k4)/6;
case 2
k2 = f(t+h/3, y + h*k1/3);
k3 = f(t+2*h/3, y -h*k1/3 +h*k2);
k4 = f(t+h, y + h*k1 -h*k2 +h*k3);
y = y + h*(k1 + 3*k2 + 3*k3 + k4)/8;
case 3
k2 = f(t+2*h/3, y + 2*h*k1/3);
k3 = f(t+h/3, y + h*k1/12 +h*k2/4);
k4 = f(t+h, y - 5*h*k1/4 +h*k2/4 +2*h*k3);
y = y + h*(k1 + 3*k2 + 3*k3 + k4)/8;
case 4
k2 = f(t+h/2, y + h*k1/2);
k3 = f(t+h/2, y + h*k1/6 +h*k2/3);
k4 = f(t+h, y -h*k2/2 +3*h*k3/2);
y = y + h*(k1 + k2 + 3*k3 + k4)/6;
case 5
k2 = f(t+h/2, y + h*k1/2);
k3 = f(t+h/2, y - h*k1/2 +h*k2);
k4 = f(t+h, y + h*k2/2 + h*k3/2);
y = y + h*(k1 + 3*k2 + k3 + k4)/6;
end
end
Example 1: Consider a simple equation
with a closed form solution
.
- RK1, same as forward Euler's method,
![$\displaystyle y_{n+1}=(1+h\lambda)y_n$](img728.svg) |
(261) |
- RK2, we choose to use
and
:
Substituting these into the RK2 iteration, we get
![$\displaystyle y_{n+1}=y_n+\frac{h}{2}(k_1+k_2)=y_n+\frac{h}{2}\lambda y_n
+\frac{h}{2}\lambda(1+h\lambda)y_n=\left(1+h\lambda+\frac{(h\lambda)^2}{2}\right)y_n$](img733.svg) |
(264) |
- RK3, we choose to use
,
,
,
, and
:
Substituting these into the RK3 iteration, we get
![$\displaystyle y_{n+1}=y_n+\frac{h}{4}(k_1+3k_3)
=\left(1+h\lambda+\frac{1}{2}(h\lambda)^2+\frac{1}{6}(h\lambda)^3\right)y_n$](img742.svg) |
(269) |
- RK4, we choose to use
,
and
,
:
Substituting these into the RK4 iteration, we get
![$\displaystyle y_{n+1}=y_n+\frac{h}{6}(k_1+2k_2+2k_3+k_4)
=\left(1+h\lambda+\frac{1}{2}(h\lambda)^2+\frac{1}{6}(h\lambda)^3
+\frac{1}{24}(h\lambda)^4\right)y_n$](img753.svg) |
(273) |
We realize that the expressions inside the brackets of the iterations of
the RK methods are simply the first few terms of the Taylor expansion of
, i.e., the iterations above are the approximations of the
closed form solution
with truncation errors of
different orders.
The RK4 method considered above is in scalar form, however, it
can be easily generalized to the following vector form:
At each step, all
,
,
, and
in vector form are computed based on
found in previous step, and then all components of
are obtained by the last equation above.
Exanple 2:
Previously we considered solving the second order LCCODE
analytically. We now resolve this equation but numerically
by the RK4 method. Specifically, consider a spring-damper-mass
mechanical system:
![$\displaystyle m y''(t)+c y'(t)+k y(t)=x(t)$](img772.svg) |
(275) |
with initial condition
and
. First, we
convert the DE into the canonic form
![$\displaystyle y''(t)+\frac{c}{m} y'(t)+\frac{k}{m} y(t)
=y''(t)+2\zeta\omega_n y'(t)+\omega_n^2 y(t)=\frac{1}{m}x(t)$](img774.svg) |
(276) |
where
![$\displaystyle \omega_n=\sqrt{\frac{k}{m}},\;\;\;\;\;\;
\zeta=\frac{c}{2\sqrt{mk}}$](img775.svg) |
(277) |
This 2nd-order LCCODE can also be solved numerically. We let
![$\displaystyle \left\{ \begin{array}{l}
y'_1=y'=y_2 \\
y'_2=y''=-c/m\;y_2-k/m\;y_1+x/m
\end{array}\right.$](img776.svg) |
(278) |
and then solve it iteratively to get
in the
interval
, by each of the six methods: forward and backward
Euler's methods with
, trapezoidal method with
, RK2
with
, RK3 with
, and RK4 with
.
Here we consider four different sets of parameters:
In the first case
and
are a complex conjugate pair, the
system is underdamped. But in all other cases, both
and
are real, the system is overdamped, its solution contains two
exponentially decaying terms
and
, one
decaying more quickly than the other.
The numerical solutions are plotted together with the closed-form
solution as the ground truth as show below.
Summarizing the above, we can make the following observations:
- A smaller step size always produces a more accurate soluton.
- Methods with higher order error terms are more accurate,
if they are stable.
- When the ratio
increases, a method may
become unstable, the step size needs to be reduced to avoid a
divergent solution.
- When the step size is not small enough, an explicit method
may become not only inaccurate, but also unstable. A method of
lower error order (forward Euler with
, RK2 with
)
requires a smaller step size to remain stable than a method of
higher error order (RK4 with
).
- Small step size may be needed not necessarily for more
accurate solution, but for preventing instability.
- The implicit backward Euler and trapezoidal methods are
always stable even when the step size is large, although the
orders of their error terms are not as high as other methods
such as RK3 and RK4.
- A method with higher order error may produce more
accurate solution only if it is stable, an implicit method
with low error order may not be as accurate, but it is
always stable.
- Accuracy and stability are two related but different
properties of a method.
The Matlab code for the RK methods is listed below:
function RungeKutta
global M C K
M=10; C=1; K=10;
figure(1)
% M=1; C=101; K=100; %stiff!
% M=1; C=1001; K=1000; %stiff!
t0=0; % initial time
y_int=[1; 1]; % initial values
tfinal = 50;
fprintf('Initial and final time: %.2f to %.2f\n',t0,tfinal);
% nsteps=input('Number of steps for numerical integral: ');
for l=1:3
switch l
case 1
nsteps=40;
case 2
nsteps=60;
case 3
nsteps=80;
end
tout=zeros(nsteps,1);
h = (tfinal - t0)/ nsteps; % step size
y1=ones(nsteps,1);
y2=ones(nsteps,1);
y3=ones(nsteps,1);
y4=ones(nsteps,1);
y5=ones(nsteps,1);
fprintf('\n# of steps: %4d\th=%0.3f\n',nsteps,h);
for k=0:4
t = t0; % set the variable t.
y = y_int; % initial conditions
for j= 1 : nsteps % go through the steps.
switch k
case 0
y = EulerForward(h, t, y);
y1(j)=y(1); % save only the first component of y.
case 1
%y=modifiedEuler(h, t, y);
y=EulerBackward(h, t, y);
y2(j)=y(1);
case 2
y=RungeKutta2(h, t, y);
y3(j)=y(1);
case 3
y=RungeKutta3(h, t, y);
y4(j)=y(1);
case 4
y=RungeKutta4(h, t, y, 3);
y5(j)=y(1);
end
t = t + h;
tout(j) = t;
end
end
y0=SecondOrder(y_int,tout);
subaxis(5,3,l, 'Spacing', 0.04, 'Padding', 0, 'Margin', 0.05);
plot(tout,y0,tout,y1)
xlim([t0,tfinal])
% ylim([-10 100])
legend('ground truth','EulerForward')
fprintf('\tEulerForward:\terror=%e\n',norm((y0-y1)./y0)/nsteps)
str = sprintf('h=%.2f',h);
title(str);
subaxis(5,3,l+3, 'Spacing', 0.04, 'Padding', 0, 'Margin', 0.05);
plot(tout,y0,tout,y2)
xlim([t0,tfinal])
% ylim([-10 100])
legend('ground truth','EulerBackward')
fprintf('\tEulerBackward:\terror=%e\n',norm((y0-y2)./y0)/nsteps)
subaxis(5,3,l+6, 'Spacing', 0.04, 'Padding', 0, 'Margin', 0.05);
plot(tout,y0,tout,y3)
xlim([t0,tfinal])
% ylim([-10 100])
legend('ground truth','RK2')
fprintf('\tRK2:\terror=%e\n',norm((y0-y3)./y0)/nsteps)
subaxis(5,3,l+9, 'Spacing', 0.04, 'Padding', 0, 'Margin', 0.05);
plot(tout,y0,tout,y4)
xlim([t0,tfinal])
% ylim([-10 100])
legend('ground truth','RK3')
fprintf('\tRK3:\terror=%e\n',norm((y0-y4)./y0)/nsteps)
subaxis(5,3,l+12, 'Spacing', 0.04, 'Padding', 0, 'Margin', 0.05);
plot(tout,y0,tout,y5)
xlim([t0,tfinal])
% ylim([-10 100])
legend('ground truth','RK4')
fprintf('\tRK4:\terror=%e\n',norm((y0-y5)./y0)/nsteps)
end
end
function e=rr(x,y)
e=0;
for i=1:length(x)
e=e+abs(x(i)-y(i))/abs(y(i));
end
% e=sqrt(e)
% norm(x-y)
% pause
end
function y = SecondOrder(y_int,t)
global M C K
zt=C/2/sqrt(M*K);
wn=sqrt(K/M);
s=sqrt(zt^2-1);
s1=(-zt-s)*wn;
s2=(-zt+s)*wn;
c1=(s2*y_int(1)-y_int(2))/(s2-s1);
c2=(s1*y_int(1)-y_int(2))/(s1-s2);
y=c1*exp(s1*t)+c2*exp(s2*t); % homogeneous solution
y=y+1/(M*wn^2); % particular solution
end
function dy = f(t, y) % 2nd order linear constant-coefficient DE
global M C K
dy = zeros(2,1);
dy(1) = y(2);
dy(2) = (-C*y(2)-K*y(1))/M; % homogeneous solution
dy(2) = dy(2)+1/M; % particular solution
end
function y = EulerForward(h, t, y)
y = y + h* f(t, y);
end
function y1 = EulerBackward(h, t0, y0)
global M C K
Jf=zeros(2);
Jf(1,1)=0;
Jf(1,2)=1;
Jf(2,1)=-K/M;
Jf(2,2)=-C/M;
y1=y0;
f(t0,y1);
F=y0+h*f(t0,y1)-y1;
norm(F);
i=0;
while norm(F)>0.0001
Jy=h*Jf;
Jy(1,1)=Jy(1,1)-1;
Jy(2,2)=Jy(2,2)-1;
y1=y1-inv(Jy)*F;
F=y0+h*f(t0,y1)-y1;
norm(F);
end
end
function y = modifiedEuler(h, t, y)
k1 = f(t, y);
k2 = f(t+h, y + h*k1);
y = y + h*(k1 + k2)/2;
end
function y = RungeKutta2(h, t, y)
k1 = f(t, y);
k2 = f(t+h/2, y + h*k1/2);
y = y + h*k2;
end
function y = RungeKutta3(h, t, y)
k1 = f(t, y);
k2 = f(t+h/2, y + h*k1/2);
k3 = f(t+h, y -h*k1 + 2*h*k2);
y = y + h*(k1 + 4*k2 + k3)/6;
% k1 = f(t0, y0);
% k2 = f(t0+h/3, y0 + h*k1/3);
% k3 = f(t0+2*h/3, y0 +2*h*k2/3);
% y1 = y0 + h*(k1 + 3*k3)/4;
end
function y1 = RungeKutta2a(h, t0, y0)
a=0.5;
k1 = f(t0, y0);
k2 = f(t0+a*h, y0 + a*h*k1);
y1 = y0 + h*((1-1/2/a)*k1+ k2/2/a)/2;
end
function y = RungeKutta4(h, t, y, k)
k1 = f(t, y);
switch k
case 1
k2 = f(t+h/2, y + h*k1/2);
k3 = f(t+h/2, y + h*k2/2);
k4 = f(t+h, y + h*k3);
y = y + h*(k1 + 2*k2 + 2*k3 + k4)/6;
case 2
k2 = f(t+h/3, y + h*k1/3);
k3 = f(t+2*h/3, y -h*k1/3 +h*k2);
k4 = f(t+h, y + h*k1 -h*k2 +h*k3);
y = y + h*(k1 + 3*k2 + 3*k3 + k4)/8;
case 3
k2 = f(t+2*h/3, y + 2*h*k1/3);
k3 = f(t+h/3, y + h*k1/12 +h*k2/4);
k4 = f(t+h, y - 5*h*k1/4 +h*k2/4 +2*h*k3);
y = y + h*(k1 + 3*k2 + 3*k3 + k4)/8;
case 4
k2 = f(t+h/2, y + h*k1/2);
k3 = f(t+h/2, y + h*k1/6 +h*k2/3);
k4 = f(t+h, y -h*k2/2 +3*h*k3/2);
y = y + h*(k1 + k2 + 3*k3 + k4)/6;
case 5
k2 = f(t+h/2, y + h*k1/2);
k3 = f(t+h/2, y - h*k1/2 +h*k2);
k4 = f(t+h, y + h*k2/2 + h*k3/2);
y = y + h*(k1 + 3*k2 + k3 + k4)/6;
end
end