【问题标题】:Complexity of arbitrary matrix multiplications任意矩阵乘法的复杂度
【发布时间】:2012-03-09 17:04:39
【问题描述】:

我有一个关于矩阵乘法实现的简单问题。我知道有用于具有 O(n^2.xxx) 复杂度的相等大小 (n x n) 的矩阵的算法。但是如果我有两个不同大小的矩阵 A 和 B (p x q, q x r),那么迄今为止实现的最小复杂度是多少?我猜它是 O(pqr),因为我会用 3 个嵌套循环和 p、q 和 r 迭代来实现乘法。特别是,现在有人知道Eigen 库是如何实现乘法的吗?

【问题讨论】:

  • 你看过 Eigen 源代码吗?
  • 是的,我没听懂。我不是一个伟大的数学家。 :(

标签: algorithm math matrix time-complexity


【解决方案1】:

一种常见的技术是用大小 (p*q, q*r) 填充矩阵,使它们的大小变为 (n*n)。然后,您可以应用 Strassen 算法。

【讨论】:

  • 是否有任何关于此的出版物或是否有任何库使用此技术?
  • 嗯。 Strassen 的算法是关于递归分割成相等的大小。二分查找也是如此。对非 2 的幂进行快速二分搜索的方法是首先确定要搜索的大小为二的幂的剩余块,然后执行精确除以 2 的高效二分搜索。我希望类似的概念适用于 Strassen。你没有得到一个整洁的分区,做一个丑陋的分区,在大二进制块上做 Strassen 并对剩下的部分应用 strassen 和修复。 (四叉树非常成功地完成了这样的事情)。
【解决方案2】:

由于您所说的原因,您认为它是 O(pqr) 是正确的。

我不确定 Eigen 是如何实现的,但是有很多方法可以优化矩阵乘法算法,例如通过 tiling 优化缓存性能以及了解您使用的语言是否为 row major or column major(您希望内部循环以尽可能小的步骤访问内存,以防止缓存未命中)。其他一些优化技术详解here

【讨论】:

    【解决方案3】:

    正如 Yu-Had Lyu 所说,您可以用零填充它们,但除非 p、q 和 r 接近,否则复杂性会退化(执行填充的时间)。

    回答您关于 Eigen 如何实现它的其他问题:

    数字包实现矩阵乘法的方式通常是使用典型的 O(pqr) 算法,但在“非数学”方式上进行了大量优化:使用特殊处理器指令(SIMD 等)阻塞以获得更好的缓存局部性

    p>

    一些软件包(MATLAB、Octave、ublas)使用两个名为 BLAS 和 LAPACK 的库,它们提供了以这种方式进行了高度优化的线性代数基元(如矩阵乘法)(有时使用特定于硬件的优化)。

    AFAIK,Eigen 只使用阻塞和 SIMD 指令。

    很少有常见的数值库(包括 Eigen)使用 Strassen Algorithm。这样做的原因实际上很有趣:虽然复杂度更好(O(n ^(log2 7))),但由于执行了所有加法,大哦后面的隐藏常数非常大 - 换句话说,该算法仅有用在实践中非常大型矩阵。

    注意: 有一种比 Strassen 算法更有效(就渐近复杂度而言)的算法:Coppersmith–Winograd algorithm,O(n^(2.3727)),但其常数为如此之大,以至于它不太可能在实践中使用。事实上,人们相信存在一种运行时间为 O(n^2) 的算法(这是微不足道的下界,因为任何算法都需要至少读取矩阵的 n^2 个元素)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-16
      • 1970-01-01
      • 2018-03-30
      • 1970-01-01
      • 2012-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多