在MATLAB中使用移位矩阵查找数值导数

时间:2015-06-21 23:53:30

标签: matlab matrix numerical-methods

我们获得了使用给定步骤找到数字一阶和二阶导数的赋值:

1)定义两个数组,x和y = f(x)(使用任何函数)

2)将微分算子定义为矩阵(例如对于f',定义矩阵D =(1 / 2h)(U-L),其中U是Uppershift矩阵,L是Lowershift矩阵。

3)通过将微分算子矩阵乘以函数数组来计算导数。

我写了这段代码:

%QUESTION 3- DIFFERENTIAL OPERATOR
h=2;
x = 2:h:8
y = x.^2 %the chosen function


n=length(x);
shift = 1; 
U = diag(ones(n-abs(shift),1),shift);
s = -1;
L= diag(ones(n-abs(shift),1),s);
% % the code above creates the upper and lower shift matrix
%
D= ((U-L))/(2*h) %differential operator 
d = y*D %approximates the first derivative of each element in vector -x
d2 = d*D %approximates the second derivative of each element in vector -x

用于创建使用this post

的移位矩阵

现在我把它作为一个解决方案:

>> mat2q3

x =

     2     4     6     8


y =

     4    16    36    64


D =

         0    0.2500         0         0
   -0.2500         0    0.2500         0
         0   -0.2500         0    0.2500
         0         0   -0.2500         0


d =

    -4    -8   -12     9


d2 =

    2.0000    2.0000   -4.2500   -3.0000

请告诉我哪里出错了,或者我该如何改进它。

1 个答案:

答案 0 :(得分:2)

这段代码大部分都是按照它打算做的:计算导数的数值近似值。但是,您计算衍生产品的方式略有不正确。基本上,对于数组中的每个点,您希望用右边的点减去左边的点并除以2*h。如果你想这样做,你需要发布 - 向量y - 并将其转换为列向量。

转置y然后转移D并将其与y相乘:

>> d = D*y.'

d =

     4
     8
    12
    -9

但是,我想指出,由于您的D矩阵,第一个和最后一个条目没有任何意义:

D =

         0    0.2500         0         0
   -0.2500         0    0.2500         0
         0   -0.2500         0    0.2500
         0         0   -0.2500         0

你在这里计算的是数值导数的中心差异,它需要一个指向左边的点和一个你在数组中评估的点的右边的点。基本上,对于第一点,当你越界时,你只有右边的点,左边的点是未定义的。类似地,对于最后一点,您只有一个指向左侧,而指向右侧的点也是不受约束的,因为它不存在。

此处的数值导数矩阵假设超出界限的点为0.事实证明,此时得到的导数是正确的,这是一个侥幸(即2*xx = 1是2)。原因是因为x = 0处的点确实使x.^2的输出等于0,所以在数组中省略这一点就好像它在你的点数组中一样。

二阶导数需要同样的事情:

>> d2 = D*d

d2 =

    2.0000
    2.0000
   -4.2500
   -3.0000

但是,请记住,对于您之前的一阶导数结果d,最后一个条目是垃圾,所以如果您计算了此结果的导数,那么当您查看时,您将使用不正确的最右项d的第三个条目,因此最后两个以及d2的前两个条目都是垃圾。恰好,d2的第二个条目是正确的。这归因于前一个结果中实际不存在的x = 0,但假设点数组中的值超出范围的值为0,我们确实得到了正确的结果。

你应该在更长的序列上尝试这个。例如,尝试这样做:

h = 2;
x = 2:h:20;
y = x.^2;

这定义了一个序列,从{2}开始,步长为h = 2。这是xd

的结果
x =

    2     4     6     8    10    12    14    16    18    20

d =

     4
     8
    12
    16
    20
    24
    28
    32
    36
   -81

正如您所看到的,第一个和最后一个条目毫无意义,因为我们没有第一个条目的最左侧点和第二个条目要考虑的最右侧点。然而,侥幸的第一点为我们提供了正确的结果,正如我们之前所说的那样。一般来说,第一个和最后一个条目不应该给你正确的结果,因为我们没有左或右点来计算导数。对于其余的点,您可以看到我们正确计算了导数,或2*x

让我们来看看二阶导数d2

d2 =

    2.0000
    2.0000
    2.0000
    2.0000
    2.0000
    2.0000
    2.0000
    2.0000
  -28.2500
   -9.0000

恰好前两个元素是正确的,即使它们理论上不应该,但我们是通过侥幸得到的。但是,最后两个要素是不正确的。

你需要记住的是要记住一件事。请记住,当使用具有中心差异的数值导数时,您必须删除第一个n元素和最后n元素,其中n是您正在考虑的导数的顺序。