如何在 Chapel 的稀疏矩阵中迭代非零值

How to iterate non-zeroes in a sparse matrix in Chapel

我还有一个矩阵 A 还在附近。它很大、稀疏且 new 对称。我创建了一个名为 spDom 的稀疏域,其中包含非零条目。现在,我想遍历 r 行并在那里找到非零条目以及索引。我的目标是构建另一个域,该域本质上是行 r 的非零值。

这里有一个适用于 Chapel 1.15 的答案,只要您愿意以 CSR 格式存储您的稀疏 domain/array:

首先,出于演示目的,我将建立我的(小的、非对称的)稀疏矩阵:

use LayoutCS;                               // use the CSR/CSC layout module

config const n = 10;                        // declare problem size
const D = {1..n, 1..n};                     // declare dense domain                                  
var SD: sparse subdomain(D) dmapped CS();   // declare sparse subdomain                 

// populate sparse domain with some indices                                                       
SD += (1,1);
SD += (1,n/2);
SD += (2, n/4);
SD += (2, 3*n/4);
SD += (n/2, 1);
SD += (n/2, n);

var A: [SD] real;                          // declare sparse array                                  

forall (i,j) in SD do                      // initialize sparse array values                       
  A[i,j] = i + j/10.0;

我的解决方案依赖于名为 dimIter() 的稀疏 CS* 域上的未记录迭代器,它可用于迭代连续存储在内存中的维度(因此 CSR 的行和 CSC 的列)。 dimIter() 采用两个参数:要迭代的维度(1=行,2=列)和另一个维度中的索引。因此,要遍历我在上面定义的行,我可以这样做:

for r in 1..n {
  writeln("row ", r, " contains elements at:");
  for c in SD.dimIter(2, r) do
    writeln("  column ", c, ": ", A[r,c]);
}

对于上面显示的稀疏矩阵,这会产生:

row 1 contains elements at:
  column 1: 1.1
  column 5: 1.5
row 2 contains elements at:
  column 2: 2.2
  column 7: 2.7
row 3 contains elements at:
row 4 contains elements at:
row 5 contains elements at:
  column 1: 5.1
  column 10: 6.0
row 6 contains elements at:
row 7 contains elements at:
row 8 contains elements at:
row 9 contains elements at:
row 10 contains elements at:

我们有兴趣泛化 dimIter() 迭代器并使其成为标准稀疏 domain/array 接口的一部分,但由于 (a) 关于如何泛化的问题尚未这样做它到 n 维稀疏数组和 (b) 关于我们是否需要支持低效迭代方向的问题(例如,考虑到费用,是否应该能够迭代 CSR 的列或 CSC 的行?)