如何在 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 的行?)
我还有一个矩阵 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 的行?)