【问题标题】:Fastest algorithm for computing the determinant of a matrix?计算矩阵行列式的最快算法?
【发布时间】:2015-01-16 03:47:04
【问题描述】:

为了一篇研究论文,我被分配研究计算矩阵行列式的最快算法。

我已经知道 LU 分解Bareiss 算法 都在 O(n^3) 中运行,但是经过一些挖掘,似乎有一些算法在 n^2 和 n^3 之间运行。

source(见第 113-114 页)和source(见第 198 页)表示存在一种运行时间为 O(n^2.376) 的算法,因为它基于 Coppersmith-Winograd 的乘法算法矩阵。但是,我无法找到有关这种算法的任何细节。

我的问题是:

  1. 计算矩阵行列式的最快(非理论)算法是什么?
  2. 在哪里可以找到有关此最快算法的信息?

非常感谢。

【问题讨论】:

  • 矩阵有多大?您要计算多少行列式?
  • 我会假设矩阵非常大(N > 22 可能足够大?)。还有多少?只是给定矩阵的一个行列式。输入:1 个大矩阵输出:输入矩阵的单行列。
  • 数值稳定性是否也是一个问题?
  • 关于Ladderman乘法的问题和答案可能值得研究,stackoverflow.com/q/10827209/249341
  • @Henry 抱歉,我不知道数值稳定性是什么。

标签: algorithm matrix complexity-theory linear-algebra determinants


【解决方案1】:

我相信实践中最快的(也是常用的)算法是 Strassen 算法。您可以在 Wikipedia 上找到解释以及示例 C 代码。

基于Coppersmith-Winograd's multiplication algorithms 的算法过于复杂而无法实用,尽管它们具有迄今为止最好的渐近复杂度。

【讨论】:

  • 值得注意的是,当前的界限是O(n^{2.3728639}),但正如 Sopel 所说,较小的指数不太可能值得在实际计算中追求,因为它们有一个巨大的前面的常数因子。
  • @Sopel 我相信 Strassen 用于矩阵求逆。见en.wikipedia.org/wiki/… 至于基于 Coppersmith-Winograd 的算法,你是对的——我问过我的教授,他说它们是最快的,但是太复杂了,不实用。谢谢!
  • 我相信它们是非常相似的问题(我从 Coppersmith-Winograd 的矩阵乘法算法可以转换为计算行列式得出结论),但我对此并不了解,所以我可能错了。
  • 您能解释一下矩阵乘法算法如何用于计算行列式吗?
【解决方案2】:

我知道这不是我问题的直接答案,但为了完成我的研究论文,这就足够了。 我刚问了我的教授,我会总结他说的话:

总结:

  • 最快的矩阵乘法算法(例如 Coppersmith-Winograd 和最近的改进)可以与 O(n^~2.376) 算术运算一起使用,但使用繁重的数学工具并且通常不切实际。
  • LU 分解和 Bareiss 确实使用 O(n^3) 运算,但更实用

简而言之,尽管 LU Decomposition 和 Bareiss 不如最有效的算法快,但它们更实用,我应该将我的研究论文集中在这两个上。

感谢所有评论和帮助的人!

【讨论】:

  • 这是一个 nit,但“LU 分解和 Bareiss 没有那么快”并不是真正正确的。您的意思是“LU 分解和 Bareiss 没有那么快 渐近”。渐近优越的算法在其实际执行时间函数中具有如此高的常数,以至于“较慢”的算法在实践中更快。例如,对于所有 n
【解决方案3】:

请参阅以下 Matlab 测试脚本,该脚本计算任意方阵的行列式(还包括与 Matlab 内置函数的比较):

nMin = 2;  % Start with 2-by-2 matrices
nMax = 50; % Quit with 50-by-50 matrices
nTests = 10000;
detsOfL = NaN*zeros(nTests, nMax - nMin + 1);
detsOfA = NaN*zeros(nTests, nMax - nMin + 1);
disp(' ');
for n = nMin:nMax
    tStart = tic;
    for j = 1:nTests
       A = randn(n, n);
       detA1 = det(A); % Matlab's built-in function
       if n == 1
           detsOfL(j, 1) = 1;
           detsOfA(j, 1) = A;
           continue; % Trivial case => Quick return
       end
       [L, U, P] = lu(A);
       PtL = P'*L;
       realEigenvaluesOfPtL = real(eig(PtL));
       if min(prod(realEigenvaluesOfPtL)) < 0 % det(L) is always +1 or -1
           detL = -1;
       else
           detL = 1;
       end
       detU = prod(diag(U));
       detA2 = detL * detU; % Determinant of A using LU decomposition
       if detA1 ~= detA2
           error(['Determinant computation failed at n = ' num2str(n) ', j = ' num2str(j)]);
       end
       detsOfL(j, n - nMin + 1) = detL;
       detsOfA(j, n - nMin + 1) = detA2;
    end
    tElapsed = toc(tStart);
    disp(sprintf('Determinant computation was successful for n = %d!! Elapsed time was %.3f seconds', n, tElapsed));
end
disp(' ');

【讨论】:

  • 只是转储代码并不能解决问题。 (0) 这是你写的吗?它的许可证是什么?如果没有,你从哪里得到的?现在来实际回答问题:(1)它的性能与其他性能相比如何,具体量化? (2) 关于它如何表现如此出色的信息是什么?
猜你喜欢
  • 1970-01-01
  • 2013-05-12
  • 1970-01-01
  • 2013-07-02
  • 1970-01-01
  • 1970-01-01
  • 2021-02-11
  • 2015-12-10
  • 2018-04-14
相关资源
最近更新 更多