我正在使用以下代码,但无法找到错误:
xx = 0:1/50:1;
v = 3.*exp(-xx)-0.4*xx;
xq = xx;
vq = @(xq) interp1(xx,v,xq);
tspan = 0:1/50:1;
x0 = 3;
[~, y2] = ode45(@(t,x)vq(x), tspan, x0);
我得到y2 = [3;NAN;NAN;NAN,.....]
。然而,当我在调用ode45
之前绘制两个方程时,我得到它们是平等的,这并不奇怪。
当我计算:
f = @(t,r) 3.*exp(-r)-0.4*r;
[~, y] = ode45(f,tspan,x0);
它工作正常。但我需要证明,如果我进行插值,我可以得到相同的结果。为什么这不起作用?
答案 0 :(得分:1)
您获得NaN
,因为这是interp1
针对xx
所跨越区间之外的值返回的默认值。在您的情况下,xx
仅从0
到1
不等。但是你的初始条件是3
。如果您要使用插值,则需要在数据定义的时间间隔内开始,并确保保持在那里。例如,如果您只是更改初始条件:
xx = 0:1/50:1;
v = 3.*exp(-xx)-0.4*xx;
xq = xx;
vq = @(xq) interp1(xx,v,xq);
tspan = 0:1/50:1;
x0 = 0.1;
[t, y2] = ode45(@(t,x)vq(x), tspan, x0);
f = @(t,r) 3.*exp(-r)-0.4*r;
[t, y] = ode45(f,tspan,x0);
figure;
subplot(211)
plot(t,y,'b',t,y2,'r--')
subplot(212)
plot(t,abs(y-y2))
xlabel('t')
ylabel('Absolute Error')
即使有了这个初始条件,由于指数增长,在某个时刻系统状态会离开[0,1]区间,y2
将变为NaN
。如果您愿意,可以告诉interp1
使用actual extrapolation。