Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab ODE解算器中的已知函数_Matlab_Ode - Fatal编程技术网

Matlab ODE解算器中的已知函数

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

我是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

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