常用的仿真算法总结

对于每种数值积分法,在应用中最关心的一是计算精度,二是其稳定性。

设一阶微分方程组为:
Y ˙ = F ( t , Y ) \mathbf{\dot{Y}=F}(t,\mathbf{Y}) Y˙=F(t,Y)
式中, Y = ( y 1 , y 2 , . . y n ) T \mathbf{Y}=(y_1,y_2,..y_n)^T Y=(y1,y2,..yn)T, F = ( f 1 ( t , Y ) , f 2 ( t , Y ) , . . . f n ( t , Y ) ) T \mathbf{F}=(f_1(t,\mathbf{Y}),f_2(t,\mathbf{Y}),...f_n(t,\mathbf{Y}))^T F=(f1(t,Y),f2(t,Y),...fn(t,Y))T,初值为 Y ( t 0 ) = Y 0 \mathbf{Y}(t_0)=Y_0 Y(t0)=Y0

1.四阶龙格-库塔法

基本原理

h h h为固定步长,此时的4阶龙格库塔法的向量形式为:
Y n + 1 = Y n + h 6 ( K 1 + 2 K 2 + 2 K 3 + K 4 ) K 1 = F ( t n , Y n ) K 2 = F ( t n + h 2 , Y n + h 2 K 1 ) K 3 = F ( t n + h 2 , Y n + h 2 K 2 ) K 4 = F ( t n + h , Y n + h K 3 ) \mathbf{Y_{n+1}} = \mathbf{Y_n}+\frac{h}{6}(\mathbf{K_1+2K_2+2K_3+K_4})\\ \mathbf{K_1}=\mathbf{F}(t_n,\mathbf{Y_n})\\\mathbf{K_2}=\mathbf{F}(t_n+\frac{h}{2},\mathbf{Y_n}+\frac{h}{2}\mathbf{K_1})\\\mathbf{K_3}=\mathbf{F}(t_n+\frac{h}{2},\mathbf{Y_n}+\frac{h}{2}\mathbf{K_2})\\\mathbf{K_4}=\mathbf{F}(t_n+h,\mathbf{Y_n}+h\mathbf{K_3}) Yn+1=Yn+6h(K1+2K2+2K3+K4)K1=F(tn,Yn)K2=F(tn+2h,Yn+2hK1)K3=F(tn+2h,Yn+2hK2)K4=F(tn+h,Yn+hK3)

%下面是4阶龙格库塔法模块
function [t_,y] = RK_4(f,tspan,x0,h)
    t_ = [tspan(1):h:tspan(2)]';
    t = tspan(1);x = x0;
    y = [];
    while(t<=tspan(2))
        y = [y;x'];
        K1 = h*f(t,x);
        K2 = h*f(t + h/2,x + 1/2*K1);
        K3 = h*f(t + h/2,x + 1/2*K2);
        K4 = h*f(t + h,x + K3);
        x = x + (K1 + 2*K2 + 2*K3 + K4)/6;
        t = t + h;
    end
    if size(y,1) < size(t_,1)
       t_ = t_(1:size(y,1)); 
    end
end

稳定区域

​ 将 y n + 1 y_{n+1} yn+1 t n t_n tn点进行泰勒级数展开:
y n + 1 = y n + ∑ i = 1 r h i i ! y n ( i ) + O ( h r + 1 ) y_{n+1}=y_{n}+\sum_{i=1}^r\frac{h^i}{i!}y_n^{(i)}+O(h^{r+1}) yn+1=yn+i=1ri!hiyn(i)+O(hr+1)
对于 y ˙ = λ y \dot{y}=\lambda y y˙=λy y ( i ) = λ i y y^{(i)}=\lambda^iy y(i)=λiy,代入到上面的式子有:
y n + 1 = y n ∑ i = 0 r ( λ h ) i i ! + O ( h r + 1 ) y_{n+1}=y_{n}\sum_{i=0}^r\frac{(\lambda h)^i}{i!}+O(h^{r+1}) yn+1=yni=0ri!(λh)i+O(hr+1)
该式的稳定条件为迭代系数的绝对值小于1:
∣ ∑ i = 0 r ( λ h ) i i ! ∣ < 1 |\sum_{i=0}^r\frac{(\lambda h)^i}{i!}|<1 i=0ri!(λh)i<1
得到以下表格

r r r h λ h\lambda hλ所在的实稳定区域
1 ( − 2 , 0 ) (-2,0) 2,0
2 ( − 2 , 0 ) (-2,0) 2,0
3 ( − 2.51 , 0 ) (-2.51,0) 2.51,0
4 ( − 2.78 , 0 ) (-2.78,0) 2.78,0

代码实现

​ 在步长取0.1和0.2时,用RK-4计算如下两个微分方程组的数值解,并与解析解比较:
S 1 : y ˙ = − 20 y , y ( 0 ) = 1 , y ∗ = e − 20 t S 2 : y ˙ = − 10 y , y ( 0 ) = 1 , y ∗ = e − 10 t S_1:\dot{y}=-20y,y(0)=1,y^*=e^{-20t}\\ S_2:\dot{y}=-10y,y(0)=1,y^*=e^{-10t} S1:y˙=20y,y(0)=1,y=e20tS2:y˙=10y,y(0)=1,y=e10t
分析:对于 S 1 S_1 S1,当 h = 0.2 h=0.2 h=0.2时,很明显, λ h = − 4 ∉ ( − 2.78 , 0 ) \lambda h=-4\notin(-2.78,0) λh=4/(2.78,0),故在 h = 0.2 h=0.2 h=0.2时应该是不稳定的。

代码:

clc,clear;
%下面是计算
f1 = @(t,x)(-20*x);
f2 = @(t,x)(-10*x);
[t1,y1] = RK_4(f1,[0 2],1,0.1);
[t2,y2] = RK_4(f1,[0 2],1,0.2);
[t3,y3] = RK_4(f2,[0 2],1,0.1);
[t4,y4] = RK_4(f2,[0 2],1,0.2);
%下面是画图
subplot(221)
hold on;grid on;box on;xlabel('t/s');ylabel('y(t)');title('dot y=-20y,h=0.1');
plot(t1,exp(-20*t1),'r-',t1,y1,'b.-');legend('真实值','计算值');
subplot(222)
hold on;grid on;box on;xlabel('t/s');ylabel('y(t)');title('dot y=-20y,h=0.2');
plot(t2,exp(-20*t2),'r-',t2,y2,'b.-');legend('真实值','计算值');
subplot(223)
hold on;grid on;box on;xlabel('t/s');ylabel('y(t)');title('dot y=-10y,h=0.1');
plot(t3,exp(-10*t3),'r-',t3,y3,'b.-');legend('真实值','计算值');
subplot(224)
hold on;grid on;box on;xlabel('t/s');ylabel('y(t)');title('dot y=-10y,h=0.2');
plot(t4,exp(-10*t4),'r-',t4,y4,'b.-');legend('真实值','计算值');

结果:

在这里插入图片描述

2.实时龙格-库塔公式

​ 实时仿真要求模型运行速度与实际系统运行速度保持一致。一般的数值积分方法很难满足实时仿真的要求。常用的原因有:

  • 常用的仿真方法递推公式执行速度较慢

  • 算法机理不符合实时仿真的要求

    对一般的龙格-库塔法进行改进得到实时仿真用的数值积分公式。

实时2阶龙格库塔法

Y n + 1 = Y n + h K 2 K 1 = F ( t n , Y n ) K 2 = F ( t n + h 2 , Y n + h 2 K 1 ) \mathbf{Y_{n+1}} = \mathbf{Y_n}+h\mathbf{K_2}\\ \mathbf{K_1}=\mathbf{F}(t_n,\mathbf{Y_n})\\\mathbf{K_2}=\mathbf{F}(t_n+\frac{h}{2},\mathbf{Y_n}+\frac{h}{2}\mathbf{K_1}) Yn+1=Yn+hK2K1=F(tn,Yn)K2=F(tn+2h,Yn+2hK1)

function [t_,y] = rt_RK_2(f,tspan,x0,h)
    t_ = [tspan(1):h:tspan(2)]';
    t = tspan(1);x = x0;
    y = [];
    while(t<=tspan(2))
       y = [y;x'];
       K1 = f(t,x);
       K2 = f(t + h/2,x + h/2*K1);
       x = x + h*K2;
       t = t + h;
    end
    if size(y,1) < size(t_,1)
       t_ = t_(1:size(y,1)); 
    end
end

实时4阶龙格库塔法

Y n + 1 = Y n + h 24 ( − K 1 + 15 K 2 − 5 K 3 + 5 K 4 + 10 K 5 ) K 1 = F ( t n , Y n ) K 2 = F ( t n + h 5 , Y n + h 5 K 1 ) K 3 = F ( t n + 2 h 5 , Y n + 2 h 5 K 1 ) K 4 = F ( t n + 3 h 5 , Y n − 2 h 5 K 1 + h K 2 ) K 5 = F ( t n + 4 h 5 , Y n + 3 h 10 K 1 + h 2 K 4 \mathbf{Y_{n+1}} = \mathbf{Y_n}+\frac{h}{24}(\mathbf{-K_1+15K_2-5K_3+5K_4+10K_5})\\ \mathbf{K_1}=\mathbf{F}(t_n,\mathbf{Y_n})\\\mathbf{K_2}=\mathbf{F}(t_n+\frac{h}{5},\mathbf{Y_n}+\frac{h}{5}\mathbf{K_1})\\\mathbf{K_3}=\mathbf{F}(t_n+\frac{2h}{5},\mathbf{Y_n}+\frac{2h}{5}\mathbf{K_1})\\\mathbf{K_4}=\mathbf{F}(t_n+\frac{3h}{5},\mathbf{Y_n}-\frac{2h}{5}\mathbf{K_1}+h\mathbf{K_2})\\\mathbf{K_5}=\mathbf{F}(t_n+\frac{4h}{5},\mathbf{Y_n}+\frac{3h}{10}\mathbf{K_1}+\frac{h}{2}\mathbf{K_4} Yn+1=Yn+24h(K1+15K25K3+5K4+10K5)K1=F(tn,Yn)K2=F(tn+5h,Yn+5hK1)K3=F(tn+52h,Yn+52hK1)K4=F(tn+53h,Yn52hK1+hK2)K5=F(tn+54h,Yn+103hK1+2hK4

%下面是4阶实时龙格库塔法
function [t_,y] = rt_RK_4(f,tspan,x0,h)
    t_ = [tspan(1):h:tspan(2)]';
    t = tspan(1);x = x0;
    y = [];
    while(t<=tspan(2))
       y = [y;x'];
       K1 = f(t,x);
       K2 = f(t + h/5,x + h/5*K1);
       K3 = f(t + 2*h/5,x + 2/5*h*K1);
       K4 = f(t + 3*h/5,x - 2/5*h*K1 +h*K2);
       K5 = f(t + 4*h/5,x + 3/10*h*K1 +h/2*K4);
       x = x +(-K1 + 15*K2 - 5*K3 +5*K4 + 10*K5)*h/24;
       t = t + h;
    end
    if size(y,1) < size(t_,1)
       t_ = t_(1:size(y,1)); 
    end
end

代码实现:

clc,clear;close all;
f1 = @(t,x)(-20*x);
[t1,y1] = rt_RK_2(f1,[0 2],1,0.05);
[t2,y2] = rt_RK_4(f1,[0 2],1,0.05);
subplot(121)
hold on;grid on;box on;
xlabel('t/s');ylabel('y(t)');
plot(t1,y1,'b.-',t1,exp(-20*t1),'r-');
title('dot y=-20y,h=0.05,二阶实时龙格库塔法');
legend('计算值','真实值');
subplot(122)
hold on;grid on;box on;
xlabel('t/s');ylabel('y(t)');
plot(t2,y2,'b.-',t2,exp(-20*t2),'r-');
title('dot y=-20y,h=0.05,四阶实时龙格库塔法');
legend('计算值','真实值');

在这里插入图片描述

3.变步长龙格库塔法

​ 当求解步长太大时不能达到精度要求,当求解步长太小时,会增加不必要的计算量,比较好的方法是对步长进行自动调整。其前提是要有一个局部误差估计公式,为了得到每一步的局部误差估计值。通过巧妙选取龙格库塔法公式的系数,可以使得两个公式中的 k i k_i ki相同,从而使得一些中间结果对龙格库塔法都适用,减少计算量,使得误差估计值可以利用 k i k_i ki进行计算。

龙格-库塔-默森法

在这里插入图片描述

%下面是4阶变步长龙格库塔默森法
function [t_,y] = RKM3_4(f,tspan,x0,hspan,espan)
    t = tspan(1);x = x0;
    h_min = hspan(1);h_max = hspan(2);
    e_min = espan(1);e_max = espan(2);
    y = [];h = h_min;t_ = [];
    while(t<=tspan(2))
        y = [y;x'];
        t_ = [t_;t];
        K1 = f(t,x);
        K2 = f(t+h/3,x + h/3*K1);
        K3 = f(t+h/3,x + h/6*(K1 + K2));
        K4 = f(t+h/2,x + h/8*(K1 + 3*K2));
        K5 = f(t + h,x + h/2*(K1 - 3*K3 + 4*K4));
        xn = x;
        x = xn + h/6*(K1 + 4*K4 + K5);
        x_ = xn + h/6*(3*K1 -9*K3 + 12*K4);
        E = (x-x_)./x;
        e = norm(E);
        if (e>e_max)&&(h > h_min)
            h = h/2;
        elseif(e<e_min)&&(h < h_max)
            h = 2*h;
        else
            h = h;
        end
        t = t + h;
    end
end

当执行以下代码时:

clc,clear;close all;
f1 = @(t,x)(-20*x);
%设置相对误差在0-0.15,步长在0.01-1之间
[t3,y3] = RKM3_4(f1,[0 2],1,[0.01 0.1],[0 0.15]);
hold on;grid on;box on;
xlabel('t/s');ylabel('y(t)');
title('dot y=-20y,变步长4阶龙格库塔法');
plot(t3,y3,'b.-',t3,exp(-20*t3),'r-');
legend('计算值','真实值');

得到:
在这里插入图片描述

龙格-库塔-菲尔别格法和步长折半法略

4.亚当姆斯法

下面是显示法


%下面是4阶亚当姆斯显式法
function [t_,y] = Adams_4(f,tspan,x0,h)
    t_min = tspan(1);x = x0;t = t_min;
    y = [];t_ = [];t_max = tspan(2);
    t_f = [t_min,t_min+h,t_min+2*h,t_min+3*h];
    %下面是用RK-4初始化
    while(t<t_f(end))
        y = [y;x'];
        t_ = [t_;t];
        K1 = h*f(t,x);
        K2 = h*f(t + h/2,x + 1/2*K1);
        K3 = h*f(t + h/2,x + 1/2*K2);
        K4 = h*f(t + h,x + K3);
        x = x + (K1 + 2*K2 + 2*K3 + K4)/6;
        t = t + h;
    end
    fn = zeros(1,4);t = t_f(end);
    coffient = [-9/24 37/24 -59/24 55/24];
    for i = 1:4
        fn(i) = f(t_f(i),x);
    end
    while(t < t_max)
        y = [y;x'];
        t_ = [t_;t];
        x = x + h*coffient*fn';
        t = t + h;
        t_f = [t_f(2:end) t];
        for i = 1:4
           fn(i) = f(t_f(i),x); 
        end
    end
end

下面是预估校正法

%下面是4阶亚当姆斯预估-校正法
function [t_,y] = Adams_4v(f,tspan,x0,h)
    t_min = tspan(1);t_max = tspan(2);
    t_f1 = [t_min,t_min+h,t_min+2*h,t_min+3*h];
    t_f2 = [t_min+h,t_min+2*h,t_min+3*h,t_min+4*h];
    fn1 = zeros(1,4);fn2 = zeros(1,4);
    y = [];t_ = [];x = x0;t = t_min;
    %下面是用RK-4初始化提供初值
    while(t<t_f1(end))
        y = [y;x'];
        t_ = [t_;t];
        K1 = h*f(t,x);
        K2 = h*f(t + h/2,x + 1/2*K1);
        K3 = h*f(t + h/2,x + 1/2*K2);
        K4 = h*f(t + h,x + K3);
        x = x + (K1 + 2*K2 + 2*K3 + K4)/6;
        t = t + h;
    end
    for t = (t_min+3*h):h:t_max
        y = [y;x'];t_ = [t_;t];
        x_ = x + h/24*(55*f(t,x)-59*f(t-h,x)+37*f(t-2*h,x)-9*f(t-3*h,x));
        f_ = f(t+h,x_);
        x = x + h/24*(9*f_ + 19*f(t,x) - 5*f(t-h,x) + f(t-2*h,x));
    end
end

在这里插入图片描述

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: MMSE(最小均方误差)信道估计算法是一种常用的信道估计算法,旨在从接收信号中准确估计信道的状态。在仿真实验中,可以通过以下步骤来进行MMSE信道估计算法仿真: 1. 设定仿真参数:确定信道模型、信号传输方式、信噪比等仿真参数。 2. 生成发送信号:根据设定的信号模型和信道模型,生成发送信号。可以使用随机序列或者预设信号作为发送信号。 3. 信号传输:通过信道将发送信号传输到接收端。考虑到信道噪声,可以在传输中加入高斯白噪声。 4. 信号接收:接收端接收到经过信道传输后的接收信号。 5. MMSE信道估计算法:根据接收信号和已知的发送信号,使用MMSE信道估计算法进行信道估计。该算法基于最小均方误差准则,通过优化参数估计信道状态。 6. 评估性能:通过比较估计的信道状态与真实信道状态之间的误差,评估MMSE信道估计算法的性能。可以使用均方误差(MSE)或误码率等指标进行评估。 7. 优化算法:针对性能不佳的情况,可以尝试调整算法参数或采用其他信道估计算法进行优化。 8. 分析结果:根据仿真结果,分析MMSE信道估计算法的性能及其适用范围。结合实际应用需求,对仿真结果进行解释和总结。 通过进行MMSE信道估计算法仿真,可以评估该算法在给定条件下的性能及可行性。这对于信道估计算法的选择和优化具有重要意义,并可以为通信系统设计和性能改进提供参考。 ### 回答2: MMSE(最小均方误差)信道估计算法是一种用于估计通信系统中的信道参数的方法。该算法基于最小均方误差准则,通过最小化接收信号与估计信号之间的均方误差来估计信道参数。 在进行MMSE信道估计算法仿真时,我们可以按照以下步骤进行: 1. 初始化参数:首先,我们需要初始化信号发射机和接收机的相关参数,如信号功率、噪声方差等。 2. 生成发送信号:根据设置好的信道模型,我们可以生成发送信号。发送信号可以是任意信号,如高斯信号或者是具有特定调制方式的信号。 3. 传输信号:将生成的发送信号经过信道传输,考虑信道的损耗、频率衰落等因素。 4. 接收信号:接收信号由接收机接收,并考虑到噪声的存在,得到接收信号。 5. 估计信道参数:根据MMSE准则,我们可以用接收信号和已知参数来估计信道参数。具体的估计方法可以是使用统计方法,如最小二乘法或者最大似然估计等。 6. 输出结果:根据估计得到的信道参数,我们可以评估信道估计算法的性能。可以使用误差率或者均方误差等指标来评估算法的性能。 通过进行仿真,我们可以得到信道估计算法的性能表现,了解算法在不同信道条件下的性能特点。这可以帮助我们优化算法的设计,提高通信系统的性能和可靠性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值