Improved Euler's method compared to 4th order Runge - Kutta's method

5 Ansichten (letzte 30 Tage)
Is the improved Euler's method as good as the 4th order Runge - Kutta's method ? Or is it the step h that makes it almost not distinguishable ?
%--- Exercise 1 - A
%--- Solving the diff. eqn. N'(t) = N(t) - c*N^2(t) with c = 0.5 using
%--- Euler's method, Runge - Kutta method, and predictor-corrector method, and comparing in graph.
%--- I have four initial values for N0.
clc, clear all, close all
tmax = 50; % input('Enter tmax = ');
t = [0:tmax];
c = 0.5;
h = 0.1;
f = @(t,N) N - c*N.^2;
N0 = [0.1 0.5 1.0 2.0];
L = length(t)-1;
N = zeros(1,L);
for i = 1:length(N0)
figure(1)
subplot(2,2,i), hold on
title({'N'' = N - 0.5N^2',sprintf('N_0 = %.1f', N0(i))}),xlabel('t'), ylabel('N(t)'), hold on
%---------- Euler's method ----------
for j = 1:L
EulerN(1) = N0(i);
EulerN(1,j+1) = EulerN(j) + h*f(':',EulerN(j));
end
plot(t,EulerN), hold on
%---------- Improved Euler's method ----------
for j = 1:L
ImpN(1) = N0(i);
ImpN(1,j+1) = ImpN(j) + 0.5*h*( f ( t(j), ImpN(j) ) + f ( t(j+1), ImpN(j) + h * f ( t(j), ImpN(j) ) ) );
end
plot(t,ImpN,'r.'), hold on
%---------- Runge - Kutta method ----------
for j = 1:tmax
RKN(1) = N0(i);
K1 = f(t(j),RKN(j));
K2 = f(t(j) + h*0.5, RKN(j) + h*K1*0.5);
K3 = f(t(j) + h*0.5, RKN(j) + h*K2*0.5);
K4 = f(t(j) + h, RKN(j) + h*K3);
RKN(j+1) = RKN(j) + h*((K1 + K4)/6 + (K2 + K3)/3);
end
plot(t,RKN,'k-.')
legend({'Simple Euler','Improved Euler','Runge - Kutta'},'Location','Southeast')
end
  1 Kommentar
Torsten
Torsten am 31 Dez. 2024
Bearbeitet: Torsten am 31 Dez. 2024
If the equation is non-stiff and you use fixed time stepping, usually the order of the method indicates which one is "best".
If the solutions are almost identical, you are correct: probably the stepsize is already small enough that the solutions lie one upon the other.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

John D'Errico
John D'Errico am 31 Dez. 2024
Bearbeitet: John D'Errico am 1 Jan. 2025
Is it as good? COMPARE IT TO THE ANALYTICAL SOLUTION! We have gone through exactly this before.
A big problem however, is you are using the WRONG step size. That is, if you have
t = [0:tmax];
then your step size is 1. ONE. Do you see that? If you do that, then h must be 1. NOT 0.1. I'll use a step size of 0.1 though, which means I need to set t properly.
Next, you set the loop for Runge-Kutta to go from 1 to tmax. But the other loops went from 1 to L.
c = 0.5;
h = 0.1;
syms n(t);
n_t = dsolve(diff(n,1) == n - c*n^2,n(0) == 0.1)
n_t = 
nfun = matlabFunction(n_t)
nfun = function_handle with value:
@(t)(exp(t).*2.0)./(exp(t)+1.9e+1)
That is the analytical solution. I'll strip out some of what you have written and solve lt for one initial value.
tmax = 10;
t = [0:h:tmax];
f = @(t,N) N - c*N.^2;
N0 = 0.1;
L = length(t)-1;
for j = 1:L
EulerN(1) = N0;
EulerN(1,j+1) = EulerN(j) + h*f(':',EulerN(j));
end
%---------- Improved Euler's method ----------
for j = 1:L
ImpN(1) = N0;
ImpN(1,j+1) = ImpN(j) + 0.5*h*( f ( t(j), ImpN(j) ) + f ( t(j+1), ImpN(j) + h * f ( t(j), ImpN(j) ) ) );
end
%---------- Runge - Kutta method ----------
for j = 1:L
RKN(1) = N0;
K1 = f(t(j),RKN(j));
K2 = f(t(j) + h*0.5, RKN(j) + h*K1*0.5);
K3 = f(t(j) + h*0.5, RKN(j) + h*K2*0.5);
K4 = f(t(j) + h, RKN(j) + h*K3);
RKN(j+1) = RKN(j) + h*((K1 + K4)/6 + (K2 + K3)/3);
end
N = nfun(t);
plot(t,N,'k-',t,EulerN,'g-',t,ImpN,'b-',t,RKN,'r-')
title 'Predictions'
grid on
legend({'True solution','Simple Euler','Improved Euler','Runge - Kutta'},'Location','Southeast')
plot(t,N - EulerN,'g-',t,N - ImpN,'b-',t,N - RKN,'r-')
title('Errors')
grid on
legend({'Simple Euler','Improved Euler','Runge - Kutta'},'Location','Northeast')
You should see that now, in the first plot, ALL of the curves pretty much lie on top of each other, now that I used comparable step sizes, etc. The problem is, you can't really see the difference. BUT in the error plot, how do they compare?
You should then see that simple Euler is ok, but it is way worse than improved Euler, and Runge-Kutta pretty much nails it, and does so far better than did either version of Euler. You really need to compare the methods using the same step sizes though. Else you will get meaningless, uninterpretable garbage.
You really need to learn to be more careful in your code. Otherwise, how can you trust the results you get?
  5 Kommentare
Walter Roberson
Walter Roberson am 1 Jan. 2025
tmax = 10; % input('Enter tmax = ');
c = 0.5;
h = 0.1;
f = @(t,N) N - c*N.^2;
N0 = [0.1 0.5 1.0 2.0];
for i = 1:length(N0)
N0(i)
syms n(t)
Df = diff(n) == n - c*n^2;
nAnalytical = dsolve(Df,n(0) == N0(i))
end
ans = 0.1000
nAnalytical = 
ans = 0.5000
nAnalytical = 
ans = 1
nAnalytical = 
ans = 2
nAnalytical = 
2
we can see that when N0 becomes 2, the analytic solution is the constant function n(t) = 2. But that constant function does not involve any symbolic variables, so when you
nfun = matlabFunction(nAnalytical)
you get out @() 2 as the function. That anonymous function does not accept any input parameters.
To get this to work, you need to use
nfun = matlabFunction(nAnalytical, 'vars', t)

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Programming finden Sie in Help Center und File Exchange

Produkte


Version

R2016a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by