我正在优化严重依赖于定制的Matrix库的代码(不会从项目中排除它,因为它无处不在。这不是很好,但这是事实......)许多计算都是用矩阵完成的10-20行和列,许多计算包括像
这样的二次形式 C = A*B*A'
我意识到A经常是稀疏的,我想利用这个事实。所以我正在寻找一种能够处理这种情况的算法。数值稳定性很重要。有什么我可以用的吗? (我没有写我们的图书馆所以我不知道我是否应该考虑到任何陷阱?)
由于“我们的”简单O(n ^ 3)乘法在目标平台上的执行速度比本征3快,因为我需要数值稳定性且矩阵不是很大,我猜Strassen的算法以及Coppersmith- Winograd算法不是我想要的。相反,它只是二次形式的乘法,让我可以轻松地检查A中的零。
感谢您的任何建议!
答案 0 :(得分:1)
存在this论文,处理快速稀疏矩阵乘法。所开发的算法将稀疏矩阵分为两部分:密集和稀疏,并在其上应用快速乘法算法。所以对我而言,它看起来并不依赖于矩阵的大小,就像你在Strassen中所提到的那样,而是因为它很稀疏。
答案 1 :(得分:1)
有一些方法可以实现稀疏矩阵,使其比密集矩阵更精简。我这样做的一种方式如下:
[0 0 0 0 0]
[0 1 2 0 9]
[0 0 0 2 0]
[0 1 0 0 0]
成为非零元素的线性数组
typedef struct {
int row;
int col;
double entry;
} Element;
typedef SparseMatrix Element*;
所以矩阵现在的空间复杂度为O(n)而不是O(n ^ 2) 对于A * B,其中A和B是矩阵,您只需要遍历每个数组以寻找匹配元素(即a->> row == b-> col&& a-> col == b-> ;行),并可能添加几个(内部产品)。 该算法的复杂度为O(n ^ 2)而不是O(n ^ 3)。这是因为你可以跳过采取导致零的内在产品的无聊操作。
答案 2 :(得分:1)