压缩稀疏行转置
Compressed Sparse Row Transpose
如您所知,我们可以在压缩行存储 (CRS)(或者压缩稀疏行 (CSR))中写入稀疏矩阵。
令 A 为 m n 矩阵。 A 的转置是一个 n x m 矩阵 A' 使得对于所有 0 <= i < n 和 0 <= j < m,A'(i; j) = A(j; i).
我需要编写用于在 CRS 表示中转置矩阵的算法。我该如何解决这个问题?
我正在寻找类似的东西。这是我的算法。不知道是不是最快的,不过我觉得挺好的
假设矩阵由这个结构表示:
struct CRSMatrix
{
int n; // number of rows
int m; // number of columns
int nz; // number of non-zero elements
std::vector<double> val; // non-zero elements
std::vector<int> colIndex; // column indices
std::vector<int> rowPtr; // row ptr
};
这个函数做到了:
CRSMatrix sparse_transpose(const CRSMatrix& input) {
CRSMatrix res{
input.m,
input.n,
input.nz,
std::vector<double>(input.nz, 0.0),
std::vector<int>(input.nz, 0),
std::vector<int>(input.m + 2, 0) // one extra
};
// count per column
for (int i = 0; i < input.nz; ++i) {
++res.rowPtr[input.colIndex[i] + 2];
}
// from count per column generate new rowPtr (but shifted)
for (int i = 2; i < res.rowPtr.size(); ++i) {
// create incremental sum
res.rowPtr[i] += res.rowPtr[i - 1];
}
// perform the main part
for (int i = 0; i < input.n; ++i) {
for (int j = input.rowPtr[i]; j < input.rowPtr[i + 1]; ++j) {
// calculate index to transposed matrix at which we should place current element, and at the same time build final rowPtr
const int new_index = res.rowPtr[input.colIndex[j] + 1]++;
res.val[new_index] = input.val[j];
res.colIndex[new_index] = i;
}
}
res.rowPtr.pop_back(); // pop that one extra
return res;
}
如您所知,我们可以在压缩行存储 (CRS)(或者压缩稀疏行 (CSR))中写入稀疏矩阵。 令 A 为 m n 矩阵。 A 的转置是一个 n x m 矩阵 A' 使得对于所有 0 <= i < n 和 0 <= j < m,A'(i; j) = A(j; i).
我需要编写用于在 CRS 表示中转置矩阵的算法。我该如何解决这个问题?
我正在寻找类似的东西。这是我的算法。不知道是不是最快的,不过我觉得挺好的
假设矩阵由这个结构表示:
struct CRSMatrix
{
int n; // number of rows
int m; // number of columns
int nz; // number of non-zero elements
std::vector<double> val; // non-zero elements
std::vector<int> colIndex; // column indices
std::vector<int> rowPtr; // row ptr
};
这个函数做到了:
CRSMatrix sparse_transpose(const CRSMatrix& input) {
CRSMatrix res{
input.m,
input.n,
input.nz,
std::vector<double>(input.nz, 0.0),
std::vector<int>(input.nz, 0),
std::vector<int>(input.m + 2, 0) // one extra
};
// count per column
for (int i = 0; i < input.nz; ++i) {
++res.rowPtr[input.colIndex[i] + 2];
}
// from count per column generate new rowPtr (but shifted)
for (int i = 2; i < res.rowPtr.size(); ++i) {
// create incremental sum
res.rowPtr[i] += res.rowPtr[i - 1];
}
// perform the main part
for (int i = 0; i < input.n; ++i) {
for (int j = input.rowPtr[i]; j < input.rowPtr[i + 1]; ++j) {
// calculate index to transposed matrix at which we should place current element, and at the same time build final rowPtr
const int new_index = res.rowPtr[input.colIndex[j] + 1]++;
res.val[new_index] = input.val[j];
res.colIndex[new_index] = i;
}
}
res.rowPtr.pop_back(); // pop that one extra
return res;
}