将 crs 格式的稀疏矩阵自身相乘并得到乘积

时间:2021-03-21 10:59:24

标签: c matrix compression sparse-matrix matrix-multiplication

我正在尝试通过使用经典朴素的方式与使用压缩行存储来比较 NxN 矩阵乘法的加速。矩阵中的值是二进制的,0 或 1。

在经典的矩阵乘法中,将矩阵与自身相乘很简单,如下所示:

   for (i = 0; i < N; i++) {
    for (j = 0; j < N; j++) {
        for (k = 0; k < N; k++) {
           product[i][j] += mat[i][k]*mat[k][j];
        }
        
        }
        }

在压缩行存储格式中,我需要将矩阵存储在数组 col_idx 中,该数组存储非零值的所有列索引。我还需要一个行指针,它对 col_idx 中给定行开始的索引进行编码。

例如,如果我们将下面的矩阵自乘,我们就得到了乘积:

Matrix Mult

给定矩阵中的列索引和行指针将具有数组值:

col_idx = [1,2,2,3,0,3,1]
row_ptr = [0,2,4,6,7]

要获取一行的列索引,比如第一行,我只需输入:

    for (i = row_ptr[0]; i < row_ptr[1]; i++) {
    printf("%d\n",col_idx[i]);
}

我想要与 CRS 算法的经典矩阵乘法相同的乘积,但在仅存储非零值的一维数组中,在本例中为:

product1D = [1,1,2,1,1,2,2,1,1,1]

我曾尝试同时获取所有行,但我一直坚持我应该做的事情。有什么提示吗?

1 个答案:

答案 0 :(得分:1)

https://www.geeksforgeeks.org/operations-sparse-matrices/ (C++) 中的实现很好:

void multiply(sparse_matrix b) 
{ 
    if (col != b.row) 
    { 

        // Invalid multiplication 
        cout << "Can't multiply, Invalid dimensions"; 
        return; 
    } 

    // transpose b to compare row 
    // and col values and to add them at the end 
    b = b.transpose(); 
    int apos, bpos; 

    // result matrix of dimension row X b.col 
    // however b has been transposed, 
    // hence row X b.row 
    sparse_matrix result(row, b.row); 

    // iterate over all elements of A 
    for (apos = 0; apos < len;) 
    { 

        // current row of result matrix 
        int r = data[apos][0]; 

        // iterate over all elements of B 
        for (bpos = 0; bpos < b.len;) 
        { 

            // current column of result matrix 
            // data[,0] used as b is transposed 
            int c = b.data[bpos][0]; 

            // temporary pointers created to add all 
            // multiplied values to obtain current 
            // element of result matrix 
            int tempa = apos; 
            int tempb = bpos; 

            int sum = 0; 

            // iterate over all elements with 
            // same row and col value 
            // to calculate result[r] 
            while (tempa < len && data[tempa][0] == r && 
                   tempb < b.len && b.data[tempb][0] == c) 
            { 
                if (data[tempa][1] < b.data[tempb][1]) 

                    // skip a 
                    tempa++; 

                else if (data[tempa][1] > b.data[tempb][1]) 

                    // skip b 
                    tempb++; 
                else

                    // same col, so multiply and increment 
                    sum += data[tempa++][2] *  
                         b.data[tempb++][2]; 
            } 

            // insert sum obtained in result[r] 
            // if its not equal to 0 
            if (sum != 0) 
                result.insert(r, c, sum); 

            while (bpos < b.len &&  
                   b.data[bpos][0] == c) 

                // jump to next column 
                bpos++; 
        } 
        while (apos < len && data[apos][0] == r) 

            // jump to next row 
            apos++; 
    } 
    result.print(); 
} 

稀疏矩阵的C++构造函数定义如下

 sparse_matrix(int r, int c) 
{ 

    // initialize row 
    row = r; 

    // initialize col 
    col = c; 

    // initialize length to 0 
    len = 0; 

    //Array of Pointer to make a matrix 
    data = new int *[MAX]; 

    // Array representation 
    // of sparse matrix 
    //[,0] represents row 
    //[,1] represents col 
    //[,2] represents value 
    for (int i = 0; i < MAX; i++) 
        data[i] = new int[3]; 
} 

带有int** data

https://codingee.com/c-programs/c-program-for-multiplication-of-two-sparse-matrices/ 中是 C 代码