% Time points for plotting
% Numerical solution using Euler method with different time step sizes
results1 = Euler(@dX, 300, 80, 1, g, k);
results2 = Euler(@dX, 300, 80, 0.1, g, k);
plot(t_all, ode1(300, t_all, g, k), 'r', 'LineWidth', 1.5, 'DisplayName', 'Analytical');
plot(results1(:, 1), results1(:, 2), 'g', 'LineWidth', 1.5, 'DisplayName', 'Euler: dt=1');
plot(results2(:, 1), results2(:, 2), 'b', 'LineWidth', 1.5, 'DisplayName', 'Euler: dt=0.1');
legend('Location', 'southeast');
plot(t_all, ode1(300, t_all, g, k), 'r', 'LineWidth', 1.5, 'DisplayName', 'Analytical');
plot(results1(:, 1), results1(:, 2), 'g', 'LineWidth', 1.5, 'DisplayName', 'Euler: dt=1');
plot(results2(:, 1), results2(:, 2), 'b', 'LineWidth', 1.5, 'DisplayName', 'Euler: dt=0.1');
legend('Location', 'southeast');
% Comparison of methods using different time step sizes
errors_Euler = zeros(size(dt_all));
errors_Heun = zeros(size(dt_all));
errors_RK2 = zeros(size(dt_all));
errors_RK4 = zeros(size(dt_all));
t_all = 0:dt:t_total; % time points to compute
results_ode = ode1(X0, t_all, g, k); % exact solutions
results_Heun = Heun(@dX, X0, t_total, dt, g, k); % dX/dt = g - k * X
results_RK2 = RK2(@dX, X0, t_total, dt, g, k);
results_RK4 = RK4(@dX, X0, t_total, dt, g, k);
results_Euler = Euler(@dX, X0, t_total, dt, g, k);
errors_Heun(ind) = rmsd(results_ode', results_Heun(:, 2));
errors_RK2(ind) = rmsd(results_ode', results_RK2(:, 2));
errors_RK4(ind) = rmsd(results_ode', results_RK4(:, 2));
errors_Euler(ind) = rmsd(results_ode', results_Euler(:, 2));
plot(dt_all, errors_Heun, 'o-', 'Color', [1 0 0], 'LineWidth', 1.5, 'MarkerSize', 8, 'DisplayName', 'Heun');
plot(dt_all, errors_RK2, '+-', 'Color', [0 1 0], 'LineWidth', 1.5, 'MarkerSize', 8, 'DisplayName', 'RK2');
plot(dt_all, errors_RK4, 'o-', 'Color', [0 0 1], 'LineWidth', 1.5, 'MarkerSize', 8, 'DisplayName', 'RK4');
plot(dt_all, errors_Euler, 'o-', 'Color', [0 1 1], 'LineWidth', 1.5, 'MarkerSize', 8, 'DisplayName', 'Euler');
set(gca, 'XScale', 'linear', 'YScale', 'log');
legend('Location', 'southeast')
result_euler = Euler(@dX, 3, t_total, 0.2, g, k);
% Compute the analytical solution
result_exact = [t_all', ode1(3, t_all, g, k)'];
plot(result_euler(:, 1), result_euler(:, 2), 'r-', 'LineWidth', 1.5, 'DisplayName', 'Euler dt=0.2');
plot(result_exact(:, 1), result_exact(:, 2), 'g-', 'LineWidth', 1.5, 'DisplayName', 'Exact');
legend('Location', 'southeast');
% Run Euler backward simulation
t_total = 10; % Adjust the total simulation time accordingly
result_euler_backward = euler_backward_1g(0, 3, t_total, 0.2, g, k);
plot(result_euler_backward(:, 1), result_euler_backward(:, 2), 'r-', 'LineWidth', 1.5, 'DisplayName', 'Euler backward dt=0.2');
plot(result_exact(:, 1), result_exact(:, 2), 'g-', 'LineWidth', 1.5, 'DisplayName', 'Exact');
legend('Location', 'southeast');
function results = Heun(derivs, X0, t_total, dt, varargin)
% derivs: function of the derivatives
% t_total: total simulation time, assuming t starts from 0 at the beginning
k1 = dt * derivs(t_all(i), X_all(i), varargin{:});
k2 = dt * derivs(t_all(i + 1), xb, varargin{:});
X_all(i + 1) = X_all(i) + (k1 + k2) / 2;
results = [t_all', X_all']; % Output matrix of t & X(t) for all time steps
function results = RK2(derivs, X0, t_total, dt, varargin)
% derivs: function of the derivatives
% t_total: total simulation time
k1 = dt * derivs(t_all(i), X_all(i), varargin{:});
k2 = dt * derivs(t_all(i) + dt/2, X_all(i) + k1/2, varargin{:});
X_all(i + 1) = X_all(i) + k2;
results = [t_all', X_all']; % Output matrix of t & X(t) for all time steps
function results = RK4(derivs, X0, t_total, dt, varargin)
% derivs: function of the derivatives
% t_total: total simulation time, assuming t starts from 0 at the beginning
k1 = dt * derivs(t_0, X_all(i), varargin{:});
k2 = dt * derivs(t_0_5, X_all(i) + k1/2, varargin{:});
k3 = dt * derivs(t_0_5, X_all(i) + k2/2, varargin{:});
k4 = dt * derivs(t_1, X_all(i) + k3, varargin{:});
X_all(i + 1) = X_all(i) + (k1 + 2*k2 + 2*k3 + k4) / 6;
results = [t_all', X_all']; % Output matrix of t & X(t) for all time steps