任意矩阵乘法的复杂性

时间:2012-03-09 17:04:40

标签: algorithm math matrix time-complexity

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

3 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:2)

你说的是正确的O(pqr)你是正确的。

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

答案 2 :(得分:2)

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

回答关于Eigen如何实现它的另一个问题:

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

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

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

很少有常见的数字库(包括Eigen)使用Strassen Algorithm。其实的原因实际上非常有趣:虽然复杂性更好(O(n ^(log2 7)))由于所有添加的操作,大Oh后面的隐藏常量非常大 - 换句话说,算法只有用在实践中非常大型矩阵。

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