【问题标题】:How to convert from a Compressed Row Storage to a Compressed Column Storage of a sparse matrix?如何从压缩行存储转换为稀疏矩阵的压缩列存储?
【发布时间】:2014-10-27 04:52:11
【问题描述】:

我有一个相对较大(例如,5000 行乘 8000 列)和稀疏矩阵,存储在 compressed row storage (CRS) 中。我正在尝试获取其compressed column storage (CCS) 表格。

是否已经有执行此操作的标准算法?一种选择是从 CRS 重建整个矩阵(4000 万个条目),然后使用简单的算法来获得其 CCS。但是,这种方法的时间复杂度很糟糕,我计划在更大的矩阵上使用这种算法。关于如何做到这一点的任何其他想法?

【问题讨论】:

    标签: algorithm matrix


    【解决方案1】:

    可能不如数字食谱代码那么有效,但我想出了这个似乎可行的方法:

    #include <stdio.h>
    #include <string.h>
    
    #define COLS 6
    #define SIZE(a) (sizeof(a)/sizeof(*(a)))
    
    int main() {
      float f[] = {10,-2, 3, 9, 3, 7, 8, 7, 3, 8, 7, 5, 8, 9, 9,13, 4, 2, 1};
      int   c[] = { 0, 4, 0, 1, 5, 1, 2, 3, 0, 2, 3, 4, 1, 3, 4, 5, 1, 4, 5};
      int   r[] = { 0,    2,       5,       8,         12,         16,       19};
      float nf[SIZE(f)];
      int   nc[COLS+1] = {0};
      int   nr[SIZE(f)];
      int   nn[COLS+1];
    
      int rr[SIZE(f)];
      for (int k = 0, i = 0; i < SIZE(r); i++)
        for (int j = 0; j < r[i+1] - r[i]; j++)
          rr[k++] = i;
    
      for (int i = 0; i < SIZE(f); i++)
        nc[c[i]+1]++;
      for (int i = 1; i <= COLS; i++)
        nc[i] += nc[i-1];
      memcpy(nn, nc, sizeof(nc));
    
      for (int i = 0; i < SIZE(f); i++) {
        int x = nn[c[i]]++;
        nf[x] = f[i];
        nr[x] = rr[i];
      }
    
      for (int i = 0; i < SIZE(nf); i++) printf("%2.0f ", nf[i]);
      putchar('\n');
      for (int i = 0; i < SIZE(nr); i++) printf("%2d ", nr[i]);
      putchar('\n');
      for (int i = 0; i < SIZE(nc); i++) printf("%2d ", nc[i]);
      putchar('\n');
    
      return 0;
    }
    

    【讨论】:

      【解决方案2】:

      似乎有一种标准方法,因为在数值食谱中描述了一种算法。我将在这里引用代码,它应该会给你这个想法,而更多细节你应该参考第 2.7 章。第三版。

      NRsparseMat NRsparseMat::transpose() const {
          Int i,j,k,index,m=nrows,n=ncols;
          NRsparseMat at(n,m,nvals); //Initialized to zero.
      
          //First find the column lengths for AT , i.e. the row lengths of A.
          VecInt count(m,0); //Temporary counters for each row of A.
          for (i=0;i<n;i++)
              for (j=col_ptr[i];j<col_ptr[i+1];j++) {
                  k=row_ind[j];
                  count[k]++;
              }
      
          for (j=0;j<m;j++) //Now set at.col_ptr. 0th entry stays 0.
              at.col_ptr[j+1]=at.col_ptr[j]+count[j];
      
          for(j=0;j<m;j++) //Reset counters to zero.
              count[j]=0;
      
          for (i=0;i<n;i++) //Main loop.
              for (j=col_ptr[i];j<col_ptr[i+1];j++) {
                  k=row_ind[j];
                  index=at.col_ptr[k]+count[k]; //Element’s position in column of AT .
                  at.row_ind[index]=i;
                  at.val[index]=val[j];
                  count[k]++; //Increment counter for next element in that column.
              }
          return at;
      }
      

      为了我个人的使用,我通常会从 Numerical Recipes 重写代码,方法是删除它的特定 typedef(例如 IntVecInt)、重命名、重新格式化等。

      【讨论】:

        猜你喜欢
        • 2019-03-12
        • 2015-12-05
        • 2014-09-18
        • 2011-10-02
        • 1970-01-01
        • 1970-01-01
        • 2020-07-11
        • 1970-01-01
        • 2016-10-04
        相关资源
        最近更新 更多