四阶龙格-库塔方法matlab程序与误差对比

四阶龙格-库塔方法matlab程序与误差对比

简介

本例子函数参考了【1】中的函数,增加了解析方法的函数与四阶龙格-库塔方法对比,并计算了百分比误差,最大误差在0.3%左右。

参考

【1】Matlab代码分享-龙格库塔(Runge-Kutta)法

code

四阶龙格-库塔函数

参考自【1】链接

function [t,y]=Runge_Kutta4(fun,tb,te,y0,N,varargin)

%四阶龙格-库塔方法求解一阶微分方程数值解

%fun 微分方程

%tb t的取值范围的左端点

%te t的取值范围的左端点

%y0 y的迭代初始值

%N 步长

%如果函数的输入参数没有N时,步长数N取默认值200

if nargin<4

N = 200;

end

h = (te-tb)/N;%步长

t = tb+(0:N)'*h;

y = zeros(size(t));

y(1) = y0;

for k=1:N

K1 = feval(fun,t(k),y(k));

K2 = feval(fun,t(k)+h/2,y(k)+h/2*K1);

K3 = feval(fun,t(k)+h/2,y(k)+h/2*K2);

K4 = feval(fun,t(k)+h,y(k)+h*K3); %已更正,但未验证,欢迎验证指出是否更正正确

y(k+1) = y(k) + h/6*(K1+2*K2+2*K3+K4);

end

end

微分方程函数

function f=RK4_fun(t,y)
f=-y+t.^2+3;
end

一阶微分方程
d y d t = − y + t 2 + 3 \frac{dy}{dt} =-y+t^2+3 dtdy=y+t2+3
解析解
y = − 4 e − t + t 2 − 2 t + 5 y=-4e^{-t} +t^2-2t+5 y=4et+t22t+5

主程序

clc,clear,close all

%四阶龙格-库塔方法求解一阶微分方程数值解
tb=0;
te=3;
y0=1;
[t,soly]=Runge_Kutta4('RK4_fun',tb,te,y0,100);
disp([t,soly])
%解析法结果对比
tb=0;
te=3;
N=100;
h1=(te-tb)/N;
t1=tb+(0:N)'*h1;
ytrue=-4*exp(-t1)+t1.^2-2*t1+5;%解析法算的解
subplot(2,1,1);
plot(t,soly,'+',t1,ytrue,'*');

y_err=abs(soly-ytrue)./ytrue;
subplot(2,1,2);

plot(t,y_err,'*');
title('误差曲线');

结果

在这里插入图片描述

分析

从结果图中我们可以看到,绝对值误差在整个区间逐渐增大,最大有0.3%的误差,还是有相当的精度。

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是使用5阶龙格-库塔法(RK5)求解微分方程组,并估计未知参数的 MATLAB 代码示例: ```matlab function [t, y, theta_hat] = rk5_param_est(f, t0, y0, h, T, theta0, u, y_meas) % f为微分方程组的函数,t0为初始时间,y0为初始状态向量,h为步长,T为终止时间 % theta0为未知参数的初始值,u为输入信号,y_meas为测量数据 t = t0; y = y0; theta_hat = theta0; while t < T k1 = h * f(t, y, u, theta_hat); k2 = h * f(t + h / 4, y + k1 / 4, u, theta_hat); k3 = h * f(t + 3 * h / 8, y + 3 * k1 / 32 + 9 * k2 / 32, u, theta_hat); k4 = h * f(t + 12 * h / 13, y + 1932 * k1 / 2197 - 7200 * k2 / 2197 + 7296 * k3 / 2197, u, theta_hat); k5 = h * f(t + h, y + 439 * k1 / 216 - 8 * k2 + 3680 * k3 / 513 - 845 * k4 / 4104, u, theta_hat); k6 = h * f(t + h / 2, y - 8 * k1 / 27 + 2 * k2 - 3544 * k3 / 2565 + 1859 * k4 / 4104 - 11 * k5 / 40, u, theta_hat); y_new = y + 25 * k1 / 216 + 1408 * k3 / 2565 + 2197 * k4 / 4104 - k5 / 5; y_hat = y + 16 * k1 / 135 + 6656 * k3 / 12825 + 28561 * k4 / 56430 - 9 * k5 / 50 + 2 * k6 / 55; % 计算误差 delta = norm(y_new - y_hat); % 判断误差是否小于容许误差 if delta < 1e-6 t = t + h; y = y_new; % 估计未知参数 y_pred = y_meas - y; J = zeros(length(y_pred), length(theta_hat)); for i = 1:length(theta_hat) theta_tmp = theta_hat; theta_tmp(i) = theta_tmp(i) + 1e-6; J(:, i) = (f(t, y, u, theta_tmp) - f(t, y, u, theta_hat)) / 1e-6; end theta_hat = theta_hat + pinv(J) * y_pred; end % 调整步长 rho = 0.84 * (1 / delta) ^ 0.25; h = min(h * rho, T - t); end end ``` 其中,函数 f 输入参数为时间 t、状态向量 y、输入信号 u 和未知参数向量 theta,输出为状态向量 y 的变化率。其余参数含义请见注释。在每个步长内,先计算状态向量的预测值和估计值,并判断误差是否小于容许误差。若满足条件,则使用测量数据和预测值计算残差,并通过残差计算雅可比矩阵并更新未知参数的估计值。最后,根据误差大小调整步长,并继续迭代直到达到终止时间 T。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值