为什么我的 MATLAB 代码用于反向替换比反斜杠运算符慢?

计算科学 线性代数 matlab 矩阵 表现
2021-12-21 09:35:38

我编写了下面的代码来反转上三角矩阵,避免任何可能的乘法/减法为零。它只是使用16n3+翻牌而不是n3+翻牌。

function B = InvTrMat(A,n,type)
  % This code inverts an upper triangular matrix of order n
  % without doing any multiplication or subtraction by zero.
  B = zeros(n);

  for j = 1:n
    B(j,j) = 1 / A(j,j);
    for i = j-1:-1:1
      for k = i+1:j
        B(i,j) = B(i,j) - A(i,k) * B(k,j);
      end
      B(i,j) = B(i,j) * B(i,i);
    end
  end

  return
end

问题是它比 Matlab 的反斜杠命令慢。我使用以下代码来测试和比较两者:

n = 128;
t = zeros(1,100);
u = zeros(1,100);

for i = 1:100
  A = rand(n,n);
  A = A+A';
  A = A + n*eye(n);

  R = chol(A);

  tic;
  B = R \ eye(n);
  t(i) = toc;

  tic;
  B = InvTrMat(R,n,'u');
  u(i) = toc;
end

sum(t)/100
sum(u)/100

有谁知道如何让我的代码比 Matlab 的代码更快?这一定是可能的,因为我只使用了其他代码中的一小部分触发器。

我的 Matlab 版本是 7.10.0 (R2010a),安装在 Windows 8.0 64 位 PC 上。

谢谢大家。

1个回答

MATLAB 的\(又名mldivide)命令不会盲目地计算矩阵的逆矩阵。相反,它使用基于矩阵类型的几种算法之一(请参阅http://www.mathworks.com/help/matlab/ref/mldivide.html的“算法”部分)。在三角矩阵的情况下,MATLAB 将使用三角求解器,该求解器在操作计数方面至少与您的一样好(我没有仔细查看您的代码,但它们可能是相同的算法)。

真正的区别在于 MATLAB 中的线性代数例程实际上是在底层调用高度优化的 Fortran 例程(即 LAPACK,请参阅http://www.mathworks.com/company/newsletters/articles/matlab-incorporates-lapack.html)。对于与这些例程的预期用途相匹配的任何情况,您将无法在本机 MATLAB 代码中匹配此性能。这是由于 MATLAB 语言的性质,它只接受即时编译器的有限优化。

为了在 MATLAB 中获得最佳性能,请尽可能对事物进行矢量化并使用内置例程。