4th order Runge - Kutta vs. 4th order Predictor - Corrector

4 vues (au cours des 30 derniers jours)
Left Terry
Left Terry le 2 Jan 2025
Commenté : Torsten le 3 Jan 2025
Hello once again. As we can see, the error of the 4th order predictor - corrector (assuminig my code for this is correct) is greater than that of 4th order Runge - Kutta. Shouldn't be the other way around ?
%--- 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, close all, format long
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];
LN = length(N0);
%---------- Analytical Solution ----------
for i = 1:LN
syms n(t)
Df = diff(n) == n - c*n^2;
nAnalytical = dsolve(Df,n(0) == N0(i));
nfun = matlabFunction(nAnalytical, 'vars', t);
%-------------------------------------------
t = 0:h:tmax;
L = length(t)-1;
%---------- Simple Euler's method ----------
EulerN = zeros(1,L);
for j = 1:L
EulerN(1) = N0(i);
EulerN(1,j+1) = EulerN(j) + h*f(':',EulerN(j));
end
% ---------- Improved Euler's method ----------
ImpN = zeros(1,L);
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
%---------- Runge - Kutta method ----------
RKN = zeros(1,L);
for j = 1:L
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/6*(K1 + K4 + 2*K2 + 2*K3);
end
%---------- 4th order Predictor - Corrector ----------
PredN = zeros(1,L);
CorN = zeros(1,L);
for k = 1:L+1
if k <= 4
PredN(k) = RKN(k);
CorN(k) = RKN(k);
else
PredN(k) = PredN(k-1) + h/24*( 55*f(t(k-1),RKN(k-1)) - 59*f(t(k-2),RKN(k-2)) + 37*f(t(k-3),RKN(k-3)) - 9*f(t(k-4),RKN(k-4)));
CorN(k) = PredN(k-1) + h/24*(9*f(t(k),PredN(k)) + 19*f(t(k-1),RKN(k-1)) - 5*f(t(k-2),RKN(k-2)) + f(t(k-3),RKN(k-3)));
end
end
PC4 = CorN;
%---------------------------------------------------
%---------- Plotting -------------------------------
figure(i)
subplot(3,1,1)
fplot(nAnalytical,[0 tmax],'k')
title({'Solution of N'' = N - 0.5N^2',sprintf('for the initial condition N_0 = %.1f', N0(i))})
xlabel('t'), ylabel('N(t)'), hold on, grid on
plot(t,EulerN,t,ImpN,t,RKN,t,PC4)
legend({'Analytical solution','Simple Euler','Improved Euler','RK4','PC4'},'Location','Southeast'), grid on
N = nfun(t);
subplot(3,1,2)
plot(t,abs(N - EulerN),t,abs(N - ImpN),t,abs(N - RKN),t,abs(N - PC4))
title(sprintf('Error of each method for N_0 = %.1f',N0(i)))
xlabel('t'), ylabel('Error')
legend({'Simple Euler','Improved Euler','RK4','PC4'}), grid on, hold on
subplot(3,1,3)
plot(t,abs(N - RKN),t,abs(N - PC4))
title(sprintf('Error of RK4 and PC4 for N_0 = %.1f',N0(i)))
xlabel('t'), ylabel('Error')
legend({'RK4','PC4'}), grid on, hold on
%----------------------------------------------------------
end

Réponse acceptée

Torsten
Torsten le 2 Jan 2025
Modifié(e) : Torsten le 2 Jan 2025
%--- 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, format long
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];
LN = length(N0);
%---------- Analytical Solution ----------
for i = 1:LN
syms n(t)
Df = diff(n) == n - c*n^2;
nAnalytical = dsolve(Df,n(0) == N0(i));
nfun = matlabFunction(nAnalytical, 'vars', t);
% %-------------------------------------------
t = 0:h:tmax;
L = length(t)-1;
%---------- Simple Euler's method ----------
EulerN = zeros(1,L);
for j = 1:L
EulerN(1) = N0(i);
EulerN(1,j+1) = EulerN(j) + h*f(':',EulerN(j));
end
% ---------- Improved Euler's method ----------
ImpN = zeros(1,L);
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
%---------- Runge - Kutta method ----------
RKN = zeros(1,L);
RKN(1) = N0(i);
for j = 1:L
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/6*(K1 + K4 + 2*K2 + 2*K3);
end
%---------- 4th order Predictor - Corrector ----------
PC4 = zeros(1,L+1);
PC4(1:4) = RKN(1:4);
for j = 4:L
PC40 = PC4(j)+h*(55.0*f(t(j),PC4(j))-59.0*f(t(j-1),PC4(j-1))+37.0*f(t(j-2),PC4(j-2))-9.0*f(t(j-3),PC4(j-3)))/24.0;
% correct PC4(j+1)
PC4(j+1) = PC4(j)+h*(9.0*f(t(j+1),PC40)+19.0*f(t(j),PC4(j))-5.0*f(t(j-1),PC4(j-1))+f(t(j-2),PC4(j-2)))/24.0;
end
%---------- Plotting -------------------------------
figure(i)
subplot(3,1,1)
fplot(nAnalytical,[0 tmax],'k')
title({'Solution of N'' = N - 0.5N^2',sprintf('N_0 = %.1f', N0(i))})
xlabel('t'), ylabel('N(t)'), hold on, grid on
plot(t,EulerN,t,ImpN,t,RKN,t,PC4)
legend({'Analytical solution','Simple Euler','Improved Euler','RK4','PC4'},'Location','Southeast'), grid on
N = nfun(t);
subplot(3,1,2)
plot(t,abs(N - EulerN),t,abs(N - ImpN),t,abs(N - RKN),t,abs(N - PC4))
title(sprintf('Error of each method for N_0 = %.1f',N0(i)))
xlabel('t'), ylabel('Error')
legend({'Simple Euler','Improved Euler','RK4','PC4'}), grid on, hold on
subplot(3,1,3)
plot(t,abs(N - RKN),t,abs(N - PC4))
title(sprintf('Error of RK4 and PC4 for N_0 = %.1f',N0(i)))
xlabel('t'), ylabel('Error')
legend({'RK4','PC4'}), grid on, hold on
%----------------------------------------------------------
end
  3 commentaires
Torsten
Torsten le 2 Jan 2025
So, PC4 it's still worst than RK4, but is this true in general ?
Not in all regions for t. And both have order 4 - so why do you think PC4 should be more precise than RK4 ?
Torsten
Torsten le 3 Jan 2025
In order to avoid unnecessary evaluations of the derivative function, I suggest using the following code for the predictor-corrector scheme:
%---------- 4th order Predictor - Corrector ----------
PC4 = zeros(1,L+1);
PC4(1:4) = RKN(1:4);
fm1 = f(t(3),PC4(3));
fm2 = f(t(2),PC4(2));
fm3 = f(t(1),PC4(1));
for j = 4:L
fm0 = f(t(j),PC4(j));
PC40 = PC4(j)+h*(55.0*fm0-59.0*fm1+37.0*fm2-9.0*fm3)/24.0;
% correct PC4(j+1)
fPC40 = f(t(j+1),PC40);
PC4(j+1) = PC4(j)+h*(9.0*fPC40+19.0*fm0-5.0*fm1+fm2)/24.0;
fm3 = fm2;
fm2 = fm1;
fm1 = fm0;
end

Connectez-vous pour commenter.

Plus de réponses (1)

Torsten
Torsten le 2 Jan 2025
For k>4, the variable RKN should no longer appear in the equations
PredN(k) = PredN(k-1) + h/24*( 55*f(t(k-1),RKN(k-1)) - 59*f(t(k-2),RKN(k-2)) + 37*f(t(k-3),RKN(k-3)) - 9*f(t(k-4),RKN(k-4)));
CorN(k) = PredN(k-1) + h/24*(9*f(t(k),PredN(k)) + 19*f(t(k-1),RKN(k-1)) - 5*f(t(k-2),RKN(k-2)) + f(t(k-3),RKN(k-3)));
  2 commentaires
Left Terry
Left Terry le 2 Jan 2025
@Torsten Correct. I think then that the correct formulae is the following
PredN(k) = CorN(k-1) + h/24*( 55*f(t(k-1),CorN(k-1)) - 59*f(t(k-2),CorN(k-2)) + 37*f(t(k-3),CorN(k-3)) - 9*f(t(k-4),CorN(k-4)));
CorN(k) = PredN(k-1) + h/24*(9*f(t(k),PredN(k)) + 19*f(t(k-1),PredN(k-1)) - 5*f(t(k-2),PredN(k-2)) + f(t(k-3),PredN(k-3)));
Left Terry
Left Terry le 2 Jan 2025
@Torsten No, the above formulas doesn't fix the problem.
%--- 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, format long
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];
LN = length(N0);
%---------- Analytical Solution ----------
for i = 1:LN
syms n(t)
Df = diff(n) == n - c*n^2;
nAnalytical = dsolve(Df,n(0) == N0(i));
nfun = matlabFunction(nAnalytical, 'vars', t);
% %-------------------------------------------
t = 0:h:tmax;
L = length(t)-1;
%---------- Simple Euler's method ----------
EulerN = zeros(1,L);
for j = 1:L
EulerN(1) = N0(i);
EulerN(1,j+1) = EulerN(j) + h*f(':',EulerN(j));
end
% ---------- Improved Euler's method ----------
ImpN = zeros(1,L);
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
%---------- Runge - Kutta method ----------
RKN = zeros(1,L);
for j = 1:L
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/6*(K1 + K4 + 2*K2 + 2*K3);
end
%---------- 4th order Predictor - Corrector ----------
PredN = zeros(1,L);
CorN = zeros(1,L);
for k = 1:L+1
if k <= 4
PredN(k) = RKN(k);
CorN(k) = RKN(k);
else
PredN(k) = CorN(k-1) + h/24*( 55*f(t(k-1),CorN(k-1)) - 59*f(t(k-2),CorN(k-2)) + 37*f(t(k-3),CorN(k-3)) - 9*f(t(k-4),CorN(k-4)));
CorN(k) = PredN(k-1) + h/24*(9*f(t(k),PredN(k)) + 19*f(t(k-1),PredN(k-1)) - 5*f(t(k-2),PredN(k-2)) + f(t(k-3),PredN(k-3)));
end
% fprintf('\n%3d)\tRunge - Kutta\t\tPrediction\t\tCorrection\n',k);
% fprintf('\t\t%.8f\t\t\t%.8f\t\t%.8f\n',RKN(k),PredN(k),CorN(k));
end
PC4 = CorN;
%---------------------------------------------------
%---------- Plotting -------------------------------
figure(i)
subplot(3,1,1)
fplot(nAnalytical,[0 tmax],'k')
title({'Solution of N'' = N - 0.5N^2',sprintf('N_0 = %.1f', N0(i))})
xlabel('t'), ylabel('N(t)'), hold on, grid on
plot(t,EulerN,t,ImpN,t,RKN,t,PC4)
legend({'Analytical solution','Simple Euler','Improved Euler','RK4','PC4'},'Location','Southeast'), grid on
N = nfun(t);
subplot(3,1,2)
plot(t,abs(N - EulerN),t,abs(N - ImpN),t,abs(N - RKN),t,abs(N - PC4))
title(sprintf('Error of each method for N_0 = %.1f',N0(i)))
xlabel('t'), ylabel('Error')
legend({'Simple Euler','Improved Euler','RK4','PC4'}), grid on, hold on
subplot(3,1,3)
plot(t,abs(N - RKN),t,abs(N - PC4))
title(sprintf('Error of RK4 and PC4 for N_0 = %.1f',N0(i)))
xlabel('t'), ylabel('Error')
legend({'RK4','PC4'}), grid on, hold on
%----------------------------------------------------------
end
%--- Exercise 1 - B
%--- Solving the diff. eqn. y'(t) = y(t) - c*y^2(t) with initial condition
%--- various values for c using Runge - Kutta method
% clc
% c = [0.1 0.2 0.5 1.0 2.0 5.0];
% Nmax = 1./c;
%
% % t(1) = 0;
% L = length(t);
% N = zeros(1,L);
% N(1) = 0.1;
%
% for i = 1:length(c)
%
% f = @(t,N) N - c(i)*N^2;
%
% for j = 1:L-1
%
% K1 = f(t(j),N(j));
% K2 = f(t(j) + h*0.5, N(j) + h*K1*0.5);
% K3 = f(t(j) + h*0.5, N(j) + h*K2*0.5);
% K4 = f(t(j) + h, N(j) + h*K3);
%
% N(j+1) = N(j) + h/6*(K1 + K4 + 2*K2 + 2*K3);
% end
% figure(LN+1)
% subplot(2,1,1)
% plot(t,N), hold on, grid on
% title('Solutions of N'' = N - cN^2 for different values of c'), xlabel('t'), ylabel('N(t)')
% end
% legend({'c = 0.1','c = 0.2','c = 0.5','c = 1','c = 2','c = 5'},'Location','Best')
% subplot(2,1,2)
% plot(c,Nmax), title('N_{max} vs. c'), xlabel('c'), ylabel('N_{max}'), grid on, text(0.5,4,'N_{max} = 1/c')

Connectez-vous pour commenter.

Catégories

En savoir plus sur Numerical Integration and Differential Equations dans Help Center et File Exchange

Produits


Version

R2016a

Community Treasure Hunt

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

Start Hunting!

Translated by