Matlab:如何在dsolve函数中使用数组?

时间:2013-03-25 18:22:37

标签: arrays matlab ode dsolve

我有一个由两个方程组成的ODE系统,但是想用一个方程与另一个方程的结果来最小化它。

1)

t=linspace(0,2,3);
syms x(t) y(t);
inits='x(0)=2,y(0)=0';
[x,y]=dsolve('Dx=y','Dy=(y*2)-x', inits)

x = 2 * exp(t) - 2 * t * exp(t);
    y = -2 * t * exp(t)

xx=eval(vectorize(x));

xx = 2.0000; 0; -14.7781

yy=eval(vectorize(y));

yy = 0; -5.4366; -29.5562

在得到结果后,我尝试用一​​个方程求解它并在Dy方程中使用xx数组。

2)

inits='y(0)=0';
[y]=dsolve('Dy=(y*2)-xx', inits);

y = xx / 2 - (xx * exp(2 * t))/ 2

yy=eval(vectorize(y));

yy = 0; 0; 396.0397

这些值与第一个示例中的值不同。如何使用数组获得相同的结果?

1 个答案:

答案 0 :(得分:1)

一个问题似乎是变量xx不是符号,因此符号求解器似乎将其视为常数。

一个更大的问题是,你真的没有确定你希望matlab如何将xx值视为一个连续函数,当它只是一个三点向量时!事实上你甚至期望第二种情况的输出是相同的,这表明我有些误解。

但为了明确这一点,我们假设你希望它将xx视为ZOH(零阶保持)连续信号。为了象征性地处理这个问题,我相信你需要使用Heaviside函数明确地构造ZOH信号。

替代方案,你可以使用ode45以数字方式解决它,例如

t  = [0,1,2];
xx = [2, 0, -14.7781];
dydy = @(t,y) 2*y - xx(1+trunc(t));
y = ode45(dydt, [0,2], 0);

这将分别在 [0,1,2] 的t值处返回 [0,-6.39,-47.21] 的yy值。

这与ZOH系统的 [0,1-e ^ 2,e ^ 2-e ^ 4] 的理论值(手工计算)很好地对应。

正如您所看到的,上述答案更符合您原来的yy = [0,-5.4366,-29.5562] 的解决方案。然而,两个系统当然不同,因为第一个系统用连续时间指数信号馈电,而第二个系统用非常粗略的采样近似信号馈电!

通过以更快的速率(更精细的时间间隔)进行采样,并通过使用比ZOH更好的内插点插入采样点,使两者更相似。

更新: 谢谢。也许你可以帮我创建ZOH连续信号吗?怎么做?

在上面的例子中,我通过使用xx向量中的三个给定点并使用“xx(1 + trunc(t))”访问它们,在我的导数函数(dydx)中创建了一个ZOH。这使用trunc(truncate)在样本间(非整数)时间显式保持输入常量。

看到你的ODE是线性的,你也可以使用matlab函数“lsim()”,它允许你直接指定时间向量和输入向量,还可以直接指定输入插值的类型(包括ZOH,其中实际上是默认的。)

例如:

t=[0,1,2]
x=[2,0,-2*e^2]
num=-1
den=[1,-2]
mytf = tf(num,den)
y = lsim(mytf,x,t,0,'zoh');

与我以前的ode45数值解决方案一样,这给出了相同的解决方案,

y = [0.00000; -6.38906; -47.20909]

更新(再次) 谢谢。也许你可以帮我创建ZOH连续信号吗?怎么做?

重新使用符号解算器。我无法访问Matlab符号库,但是如果你真的想使用符号解算器,那么正如我之前解释的那样,你可以使用heavyiside(单位步长)函数构造连续时间ZOH信号。像下面这样的东西应该这样做:

syms xzoh(t)
xzoh = xx(1)*heaviside(t) + (xx(2)-xx(1))*heaviside(t-1) + (xx(3)-xx(2))*heaviside(t-2)