Matlab ODE解算器中的已知函数
我是Matlab新手,很抱歉问了一个平庸的问题,可能已经回答了这个问题,但我没能解决它 我有一首颂歌要解 g'(x)+f(x)g'(x) g(0)=0和g'(0)=0.5 f(x)是一个已知的向量,所以我试着Matlab ODE解算器中的已知函数,matlab,ode,Matlab,Ode,我是Matlab新手,很抱歉问了一个平庸的问题,可能已经回答了这个问题,但我没能解决它 我有一首颂歌要解 g'(x)+f(x)g'(x) g(0)=0和g'(0)=0.5 f(x)是一个已知的向量,所以我试着 xspan = linspace(0,10,100); y0 = [0,0.5]; %f=f(xspan), known function, for example f=1./xspan; [x,y] = ode45('odefun',xspan,y0); 对于odefun functi
xspan = linspace(0,10,100);
y0 = [0,0.5];
%f=f(xspan), known function, for example f=1./xspan;
[x,y] = ode45('odefun',xspan,y0);
对于odefun
function dy=odefun(x,y)
global f
dy(1) = y(2);
dy(2) = -f.*y(2);
dy = dy(:);
end
当然不行了。如何将向量f
的值传递给解算器
编辑
谢谢你的帮助,但这对我不起作用。也许我有一个旧的Matlab版本(7.11.0(R2010B))?我试着按照你说的做,但这是我在命令窗口中得到的
??? In an assignment A(I) = B, the number of elements in B and
I must be the same.
Error in ==> odefun at 3
dy(2) = -f.*y(2);
Error in ==> @(x,y)odefun(x,y,f)
Error in ==> odearguments at 109
f0 = feval(ode,t0,y0,args{:}); % ODE15I sets args{1} to yp0.
Error in ==> ode45 at 173
[neq, tspan, ntspan, next, t0, tfinal, tdir, y0, f0, odeArgs, odeFcn, ...
Error in ==> trying at 7
[x,y] = ode45(fun,xspan,y0);
这是正在尝试的代码
xspan=linspace(0,10,100);
y0=[0 0.5];
f=1./xspan;
[x,y] = ode45(@(x,y)odefun(x,y,f),xspan,y0);
还有奥迪的乐趣
function dy=odefun(x,y,f)
dy(1) = y(2);
dy(2) = -f.*y(2);
dy = dy(:);
end
看起来您使用的变量不正确(
f
也需要在主函数中声明global
),但您不应该一开始就使用globals。在现代Matlab中,还应将积分函数odefun指定为一个字符串,而不是一个字符串。以下是如何修改代码以解决这些问题:
...
f = ...
[x,y] = ode45(@(x,y)odefun(x,y,f),xspan,y0);
您的积分函数可以是一个或在一个单独的文件中,只需要为参数f
获取一个额外的参数:
function dy=odefun(x,y,f)
dy(1) = y(2);
dy(2) = -f.*y(2);
dy = dy(:);
这些方法也应该比使用字符串和全局变量更快。代码@(x,y)odefun(x,y,f)
创建一个x
和y
的匿名函数(ode45
需要一个只接受两个输入的函数),该函数从当前范围捕获f
的值。这在计算机科学中也被称为是一个问题。您可以等效地创建函数句柄并将其传入:
...
f = ...
fun = @(x,y)odefun(x,y,f)
[x,y] = ode45(fun,xspan,y0);
关于这项通用技术的更多信息,请参见MathWorks。我解决了它,它并没有那么困难,我只需要在自变量x的每个值处插入f。代码就是这样工作的
function dy=odefun(x,y,f,xspan)
f=interp1(xspan,f,x);
dy(1) = y(2);
dy(2) = -f.*y(2);
dy = dy(:);
end
谢谢你的关心,但我还是有问题。我编辑了这个问题,如果你可以的话,我将非常感谢你的帮助。你的编辑(一个新问题):你仍然必须满足所有编写ODE函数的常规规则。看起来您正在为
f
传递一个向量,然后试图将其设置为等于dy
的单个元素:dy(2)=-f.*y(2)代码><代码>dy(2)=-f(1)。*y(2)代码>或dy(2)=-f(结束)。*y(2)代码>将起作用。您是否可能试图提取ode45
在每个时间步长上使用的步长,dt
,以便在odefun
中使用它?如果是这样的话,这种方法就行不通了。我没有想到,f是一个向量,当然我不能这么做。对不起,弄错了。顺便说一下,我不想做f(1)*y(2)或f(end),我需要在ode45解算器中使用的每一步计算f。那么,我应该按照建议找到步长,然后在这些步长处插值f吗?我怎么能这么做?非常感谢你的帮助!无法获得ode45
运行时内部使用的步长(xspan
只是一组输出点,不一定是解算器执行的真正步长,可能会有帮助)。您可以得到自变量x
,但不能得到步长。ODE一开始不应该是步长的函数,只应该是当前的自变量和因变量以及任何参数。你可能在数值上和数学上做了一些不可取的尝试。事实上,我不需要知道ode45的步长,我需要解微分方程g'(x)+f(x)g'(x)=0,我不知道如何传递f(x)的值(我以前计算过)。我知道xspan向量并不代表ode45使用的真正步骤,但我需要在这些步骤中计算f(x)来解上面的方程,为此我考虑了插值。那么,我没有办法做到这一点吗?如果我可以得到自变量x,那么我可以使用插值来得到ode每个“x”的f(x)值吗?如果没有,是否没有办法解决?您的odefun
的第一个输入是x
。