MATLAB ode45的三种传参方式

MATLAB ode45的三种传参方式

使用ode45函数时,需要自定义函数。而有的时候自定义函数会有一些内参,如何传参便成为了问题。

在以下例子中,我们想要通过ode45求解以下微分方程
{ d y 1 d t = − b y 1 y 1 + y 2 + 1 G a d y 2 d t 1 G a d y 2 d t d 2 y 2 d t 2 = b y 1 y 1 + y 2 + 1 G a d y 2 d t d y 2 d t − G a d y 2 d t \left\{ \begin{array}{c} \frac{dy_1}{dt}=\frac{-by_1}{y_1+y_2+\frac{1}{Ga}\frac{dy_2}{dt}}\frac{1}{Ga}\frac{dy_2}{dt}\\ \\ \frac{d^2y_2}{dt^2}=\frac{by_1}{y_1+y_2+\frac{1}{Ga}\frac{dy_2}{dt}}\frac{dy_2}{dt}-Ga\frac{dy_2}{dt}\\ \end{array} \right. dtdy1=y1+y2+Ga1dtdy2by1Ga1dtdy2dt2d2y2=y1+y2+Ga1dtdy2by1dtdy2Gadtdy2
而使用ode45求解则需要把上式转换为一阶微分方程组,因而我们作以下换元
令 G a ∗ y 3 = d y 2 d t 令Ga*y_3=\frac{dy_2}{dt} Gay3=dtdy2
因而上述微分方程组可化为
{ d y 1 d t = − b y 1 y 1 + y 3 + 1 G a d y 2 d t 1 G a d y 2 d t d y 3 d t = b y 1 y 3 y 1 + y 2 + y 3 − G a ∗ y 3 d y 2 d t = G a ∗ y 3 \left\{ \begin{array}{c} \frac{dy_1}{dt}=\frac{-by_1}{y_1+y_3+\frac{1}{Ga}\frac{dy_2}{dt}}\frac{1}{Ga}\frac{dy_2}{dt}\\ \\ \frac{dy_3}{dt}=\frac{by_1y_3}{y_1+y_2+y_3}-Ga*y_3\\ \\ \frac{dy_2}{dt}=Ga*y_3\\ \end{array} \right. dtdy1=y1+y3+Ga1dtdy2by1Ga1dtdy2dtdy3=y1+y2+y3by1y3Gay3dtdy2=Gay3

可以看到上述微分方程组中有两个常数b和Ga,因而我们想求解不同的b和Ga下的y值,但是传统的ode45中规定我们方程传入参数只能有t和y,那我们便可以采用以下三种方式把常量作为参数传入其中

方法一

首先便是可以直接利用ode45给的传参输入变量来输入传参
ode45(函数句柄,起止时间(两个数)/指定时间(向量),初始值,flag(置空即可),传参)

c=jet(5);
b=0.1;
hold off
for i = 1:5
    ga=0.01*i;
    [t,y]=ode45(@df1,[0 300],[1000 1 0],[],b,ga);
    plot(t,y(:,2),'Color',c(i,:) ...
        ,'DisplayName',['ga=',num2str(0.1*i)] ...
        ,'LineWidth',2)
    hold on
end
legend show

function dy=df1(t,y,b,ga)
    dy=zeros(3,1);
    dy(1)=-b*y(1)*y(2)/sum(y);
    dy(2)=b*y(1)*y(2)/sum(y)-ga*y(2);
    dy(3)=ga*y(2);
end

方法二(推荐)

其次便是可以利用函数句柄进行传参
这种传参方式可以扩展到其他需要输入自定义函数的MATLAB函数(比如fmincon,其规定自定义函数传入参数只能有y),而且比起方法三来说,这种方法不会因为使用全局变量而产生一些难以发现的错误

c=jet(5);
b=0.1;
hold off
for i = 1:5
    ga=0.01*i;
    [t,y]=ode45(@(t,y) df1(t,y,b,ga),[0 300],[1000 1 0]);
    plot(t,y(:,2),'Color',c(i,:) ...
        ,'DisplayName',['ga=',num2str(0.1*i)] ...
        ,'LineWidth',2)
    hold on
end
legend show

function dy=df1(t,y,b,ga)
    dy=zeros(3,1);
    dy(1)=-b*y(1)*y(2)/sum(y);
    dy(2)=b*y(1)*y(2)/sum(y)-ga*y(2);
    dy(3)=ga*y(2);
end

方法三

最后便是可以利用全局变量进行传参
注意:本方法不能在实时脚本中使用

c=jet(5);
global b ga
b=0.1;
hold off
for i = 1:5
    ga=0.01*i;
    [t,y]=ode45(@df2,[0 300],[1000 1 0]);
    plot(t,y(:,2),'Color',c(i,:) ...
        ,'DisplayName',['ga=',num2str(0.1*i)] ...
        ,'LineWidth',2)
    hold on
end
legend show

function dy=df2(t,y)
    dy=zeros(3,1);
    dy(1)=-b*y(1)*y(2)/sum(y);
    dy(2)=b*y(1)*y(2)/sum(y)-ga*y(2);
    dy(3)=ga*y(2);
end
  • 25
    点赞
  • 104
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值