稀疏矩阵中的裁剪

计算科学 矩阵 稀疏矩阵
2021-12-24 19:59:09

A豆角,扁豆M×N在类 C 编程环境中以压缩列格式存储的稀疏矩阵。我对获得子矩阵的最佳解决方案感兴趣A. 在 MATLAB 表示法中,这将显示为:

A_sub = A(i:i+m-1, j:j+n-1)

在哪里Asub又是一个稀疏矩阵,但这次是m×n.

2个回答

虽然您提到使用 C,但如果您对 Fortran 77 感到满意,Yousef Saad 的包SPARSKIT有很多稀疏矩阵算法。

压缩列格式由三个数组组成,jaia(整数)和a(浮点数/双精度数)。对于每个列 index jja(j)存储数组ia中列中所有非零行列表j开始的位置。

A_sub从中提取子矩阵的第一步A是计算每列中有多少非零条目n为此,您可以创建一个count全为零的数组,然后执行以下操作:

int k, l;
for (k=0; k<n; k++) {
    for (l=A.ja[k+j]; l<A.ja[k+j+1]; l++) {
        if (A.ia[l]>=i && A.ia[l]<i+m) {
            count[k]++;
        }
    }
}

接下来,您将填写A_sub.ja如下:

A_sub.ja[0] = 0;
for (k=0; k<n; k++) {
    A_sub.ja[k+1] = A_sub.ja[k]+count[k];
}

下一步是填写数组iaa,这需要第二次通过A

如果您有空间意识,而不是创建一个新数组count,您可以从地址开始存储相同的值A_sub.ja[1],而不影响输出。如果您想查看示例,SPARSKIT 会执行此操作。

使用 Eigen 矩阵类库 ( Eigen ),您可以用一行有效地提取子矩阵:

Eigen::SparseMatrix A(m,n);
Eigen::SparseMatrix B = A.block(startRow, startCol, numRows, numCols);

如果 A 已经以压缩稀疏列(或行)格式存在,您可以使用类似于以下代码的代码提取子矩阵:

Eigen::MappedSparseMatrix<double> Amap(A.m, A.n, A.nnz, A.colPtrs, A.rowPtrs, A.vals);
Eigen::SparseMatrix B = Amap.block(startRow, startCol, numRows, numCols);