重新排序c ++中矩阵乘法的指数

时间:2014-02-16 18:44:07

标签: c++

const int n=50;
    double a[n][n];
    double b[n][n];
    double c[n][n];

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < n; k++) {
                c[i][j] += a[i][k] * b[k][j];
            }
            cout << c[i][j] << "  ";
        }
        cout << "\n";

我目前有一个工作代码,它将两个nxn矩阵相乘。我试图重新排序索引(即i,k,j ... k,i,j)而不触及进行乘法的等式。我这样做是为了看看索引的顺序如何影响性能时间,但如果我只是在循环中将'j'更改为'k',反之亦然,那么我的乘法方程将不正确。 我想知道我试图做什么是可能的,如果有人能说明我可以采取什么步骤来实现这一目标。

2 个答案:

答案 0 :(得分:1)

首先,你不应该在你正在这样做的时候打印出c矩阵,特别是如果你试图计算算法的话。你应该做的更类似于:

const int n=50;
double a[n][n];
double b[n][n];
double c[n][n];

/* First multiply the matrices a,b into c. */
for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
        for (int k = 0; k < n; k++) {
            c[i][j] += a[i][k] * b[k][j];
        }
    }
}

/* now print out the result for visual correctness check */
for (int i = 0; i < n; i++){
    for (int j = 0; j < n; j++){
        std::cout << c[i][j] << ' '; //this will leave a space after last character, but for this use case, nobody cares.
    }
    std::cout << std::endl;
}

然后你可以绕过包含for循环的行(即for (int i = 0; i < n; i++)),看看更改访问模式是否会改变执行时间/结果。

Spoiler:它不应该影响结果,除了在矩阵内部的奇怪值的一些边界情况,这是由浮点数学的不精确性引起的。然而,它应该影响执行时间,但是除非经过适当的测量,否则它将被打印矩阵所花费的时间残酷地支配。

答案 1 :(得分:-1)

如果你正在考虑性能时间,那么它总是归结为复杂性。无论您如何更改顺序,您的复杂性都由执行大部分工作的代码区域定义。

此处所有循环都会运行到n。现在无论你改变什么顺序,你都会有秩序O(n ^ 3)的复杂性,除非你改变你的逻辑。到目前为止,已知的最佳矩阵乘法算法是Coppersmith-Winograd algorithm,其复杂度为O(n ^ 2.3736),但它并未用于实际目的。

但是你可以使用具有O(n ^ 2.8074)复杂度的Strassen's algorithm