【问题标题】:Divide and conquer matrix multiplication base case + how to split matrix into 4 quarters分治矩阵乘法基本案例+如何将矩阵分成4个四分之一
【发布时间】:2013-07-25 18:40:47
【问题描述】:

我一直在尝试编写分治矩阵乘法算法

当我尝试将矩阵分成四部分时,它给了我一个错误 ArrayOutOfIndexBound

  • 我不确定我的基本情况是否正确,你们能帮帮我吗?

我遇到的问题是 double[][] a21

    public static double[][] divideAndConquer(double[][] a , double[][] b, int dimension){

if (a.length == 1){
    double[][] result = new double[1][1];
    result[0][0]= a[0][0]*b[0][0];
    return result;
}
else {
    int m = dimension/2;
    double[][] a11 = new double[m][m];
    for(int i = 0; i < m ; i++){
        for (int j = 0 ; j< m ; j++)
            a11[i][j]= a[i][j];
    }

              double[][] a21 = new double[m][m];
            for(int i = m; i < dimension; i++){
        for (int j = 0 ; j< m ; j++)
            a21[i][j]= a[i][j];
    }
     double[][] a12 = new double[m][m];
            for(int i = 0; i < m ; i++){
        for (int j = m ; j< dimension ; j++)
            a12[i][j]= a[i][j];
    }



    double[][] a22 = new double[m][m];
            for(int i = m; i < dimension; i++){
        for (int j =  m; j < dimension; j++)
            a21[i][j]= a[i][j];
    }


    double[][] b11 = new double[m][m];
    for(int i = 0; i < m ; i++){
        for (int j = 0 ; j< m ; j++)
            b11[i][j]= b[i][j];
    }

     double[][] b12 = new double[m][m];
            for(int i = 0; i < m ; i++){
        for (int j = m ; j< dimension ; j++)
            b12[i][j]= b[i][j];
    }

      double[][] b21 = new double[m][m];
            for(int i = m; i < dimension; i++){
        for (int j = 0 ; j< m ; j++)
            b21[i][j]= b[i][j];
    }

    double[][] b22 = new double[m][m];
            for(int i = m; i < dimension; i++){
        for (int j =  m; j < dimension; j++)
            b21[i][j]= b[i][j];
    }

            double[][] x1 = divideAndConquer(a11,b11,m);
            double[][] x2 = divideAndConquer(a12,b21,m);
            double[][] x3 = divideAndConquer(a11,b12,m);
            double[][] x4 = divideAndConquer(a12,b22,m);
            double[][] x5 = divideAndConquer(a21,b11,m);
            double[][] x6 = divideAndConquer(a22,b21,m);
            double[][] x7 = divideAndConquer(a21,b12,m);
            double[][] x8 = divideAndConquer(a22,b22,m);
        ..........................etc

【问题讨论】:

  • 您划分了象限,以便稍后实现大矩阵的 Strassen 算法。

标签: java matrix multiplication divide-and-conquer


【解决方案1】:

正如所写,您的问题是您需要减去数组偏移量;例如,

a12[i][j]= a[i][j];

应该是

a12[i][j-dimension]= a[i][j];

您更大的问题是您正在创建 4 个新的子矩阵,这将产生 的垃圾。一旦你完成了这项工作,我会强烈考虑通过操作数组索引来“就地”执行此操作的方法。

例如,你的新 api 看起来像

public static double[][] divideAndConquer(double[][] a , double[][] b, int aMinIndex, int aMaxIndex, int bMinIndex, bMaxIndex){

您的分而治之将构建最小和最大索引的子集。

【讨论】:

  • 感谢您帮助我。我不得不坚持使用 API。基本情况呢?这样对吗?还是我应该让它乘以 2×2 矩阵?
  • @HamadBinAbdullah - 1) 您可以将新 API 作为辅助函数,并让默认 API 使用适当的参数调用辅助函数。 2)我可能会将其设置为 2x2。
【解决方案2】:

如何使用它进行分区?请考虑它在 C 中,N/2 是每个分区的块大小

for (int i = 0; i < N / 2; i++) {
    for (int j = 0; j < N / 2; j++) {

        ha11[i][j] = hA[i][j]; // top left
        ha12[i][j] = hA[i][j + N / 2]; // top right
        ha21[i][j] = hA[i + N / 2][j]; // bottom left
        ha22[i][j] = hA[i + N / 2][j + N / 2]; // bottom right

        hb11[i][j] = hB[i][j]; // top left
        hb12[i][j] = hB[i][j + N / 2]; // top right
        hb21[i][j] = hB[i + N / 2][j]; // bottom left
        hb22[i][j] = hB[i + N / 2][j + N / 2]; // bottom right
    }
}

【讨论】:

    猜你喜欢
    • 2011-06-18
    • 2012-03-04
    • 2019-03-13
    • 2020-04-11
    • 2017-12-05
    • 2017-07-16
    • 2020-06-12
    • 1970-01-01
    • 2016-02-24
    相关资源
    最近更新 更多