MATLAB:错误使用*内部矩阵尺寸必须与5x5矩阵一致

时间:2018-01-20 22:42:12

标签: matlab matrix

我是Matlab的新手,如果这个问题很简单,请提前道歉。我有以下MatLab代码

function fdstencil(k,j)

% Compute stencil coefficients for finite difference approximation 
% of k'th order derivative on a uniform grid.  Print the stencil and
% dominant terms in the truncation error.
%
% j should be a vector of indices of grid points, values u(x0 + j*h)
% are used, where x0 is an arbitrary grid point and h the mesh spacing.
% This routine returns a vector c of length n=length(j) and the
% k'th derivative is approximated by
%   1/h^k * [c(1)*u(x0 + j(1)*h) + ... + c(n)*u(x0 + j(n)*h)].
% Typically j(1) <= 0 <= j(n) and the values in j are monotonically
% increasing, but neither of these conditions is required.
% The routine fdcoeffF is used to compute the coefficients.
%
% Example:   fdstencil(2,-1:1);
%   determines the 2nd order centered approximation of the 2nd derivative.
%
% From  http://www.amath.washington.edu/~rjl/fdmbook/  (2007)

n = length(j);
if k>=n 
   error('***  length(j) must be larger than k')
   end

c = fdcoeffF(k,0,j);      % coefficients for k'th derivative 

% print out stencil:

disp(' ')
disp(sprintf('The derivative u^(%i) of u at x0 is approximated by',k))
disp(' ')
disp(sprintf('          1/h^%i * [',k))
for i=1:n-1
  if j(i) < 0
    disp(sprintf('                     %22.15e * u(x0%i*h) + ',c(i),j(i)))
  elseif j(i) == 0
    disp(sprintf('                     %22.15e * u(x0) + ',c(i)))
  else
    disp(sprintf('                     %22.15e * u(x0+%i*h) + ',c(i),j(i)))
  end
end

disp(sprintf('                     %22.15e * u(x0+%i*h) ]   ',c(n),j(n)))


% determine dominant terms in truncation error and print out:

err0 = c*(j(:).^n) / factorial(n);
err1 = c*(j(:).^(n+1)) / factorial(n+1);
if (abs(err0)) < 1e-14,  err0 = 0; end   % for centered approximations, expect
if (abs(err1)) < 1e-14,  err1 = 0; end   % one of these to be exactly 0.
disp(' ')
disp('For smooth u,')
disp(sprintf('       Error = %g * h^%i*u^(%i) + %g * h^%i*u^(%i) + ...',err0,n-k,n,err1,n-k+1,n+1))

disp(' ')

其中fdcoeffF.m定义为

function c = fdcoeffF(k,xbar,x)

% Compute coefficients for finite difference approximation for the
% derivative of order k at xbar based on grid values at points in x.
%
% This function returns a row vector c of dimension 1 by n, where n=length(x),
% containing coefficients to approximate u^{(k)}(xbar), 
% the k'th derivative of u evaluated at xbar,  based on n values
% of u at x(1), x(2), ... x(n).  
%
% If U is a column vector containing u(x) at these n points, then 
% c*U will give the approximation to u^{(k)}(xbar).
%
% Note for k=0 this can be used to evaluate the interpolating polynomial 
% itself.
%
% Requires length(x) > k.  
% Usually the elements x(i) are monotonically increasing
% and x(1) <= xbar <= x(n), but neither condition is required.
% The x values need not be equally spaced but must be distinct.  
%
% This program should give the same results as fdcoeffV.m, but for large
% values of n is much more stable numerically.
%
% Based on the program "weights" in 
%   B. Fornberg, "Calculation of weights in finite difference formulas",
%   SIAM Review 40 (1998), pp. 685-691.
%
% Note: Forberg's algorithm can be used to simultaneously compute the
% coefficients for derivatives of order 0, 1, ..., m where m <= n-1.
% This gives a coefficient matrix C(1:n,1:m) whose k'th column gives
% the coefficients for the k'th derivative.
%
% In this version we set m=k and only compute the coefficients for
% derivatives of order up to order k, and then return only the k'th column
% of the resulting C matrix (converted to a row vector).  
% This routine is then compatible with fdcoeffV.   
% It can be easily modified to return the whole array if desired.
%
% From  http://www.amath.washington.edu/~rjl/fdmbook/  (2007)


n = length(x);
if k >= n
   error('*** length(x) must be larger than k')
   end

m = k;   % change to m=n-1 if you want to compute coefficients for all
         % possible derivatives.  Then modify to output all of C.
c1 = 1;
c4 = x(1) - xbar;
C = zeros(n-1,m+1);
C(1,1) = 1;
for i=1:n-1
  i1 = i+1;
  mn = min(i,m);
  c2 = 1;
  c5 = c4;
  c4 = x(i1) - xbar;
  for j=0:i-1
    j1 = j+1;
    c3 = x(i1) - x(j1);
    c2 = c2*c3;
    if j==i-1
      for s=mn:-1:1
        s1 = s+1;
        C(i1,s1) = c1*(s*C(i1-1,s1-1) - c5*C(i1-1,s1))/c2;
        end
      C(i1,1) = -c1*c5*C(i1-1,1)/c2;
      end
    for s=mn:-1:1
      s1 = s+1;
      C(j1,s1) = (c4*C(j1,s1) - s*C(j1,s1-1))/c3;
      end
    C(j1,1) = c4*C(j1,1)/c3;
    end
  c1 = c2;
  end

c = C(:,end)';            % last column of c gives desired row vector

在命令窗口中,我已经定义了

j = [1 1 1 1 1; -2 -1 0 1 2; -2 -1/2 0 1/2 2; -4/3 -1/6 0 1/6 4/3; -2/3 -1/24 0 1/24 2/3]

当我参考时,

fdstencil(2,j)

(对矩阵j的二阶导数)

我收到以下错误消息 -

Error using  * 
Inner matrix dimensions must agree.

我不明白为什么5x5矩阵会返回此错误。我需要阅读更多教程吗?

1 个答案:

答案 0 :(得分:1)

问题是j以5x5开头,但它不用作此行err0 = c*(j(:).^n) / factorial(n);中乘法的输入。术语j(:)会将j转换为大小为25 1的列向量。同样,它下方的行err1 = c*(j(:).^(n+1)) / factorial(n+1);包含相同的错误。

正确的命令是err0 = c * (j.^n) / factorial(n);err = c * (j.^(n+1)) / factorial(n + 1);

找到这样的问题的一个好方法是使用命令dbstop on error停止执行任何错误并进入调试模式。