从 Eigen::SparseMatrix 中提取块/ROI而不复制
Posted
技术标签:
【中文标题】从 Eigen::SparseMatrix 中提取块/ROI而不复制【英文标题】:Extracting blocks/ROIs from Eigen::SparseMatrix without copying 【发布时间】:2015-10-28 09:49:58 【问题描述】:我想知道有没有什么好方法可以从 Eigen::SparseMatrix 中提取块/ROI? 更准确地说,我要提取的是内向量。
我想做的是这样的:
typedef Eigen::SparseMatrix<double,Eigen::RowMajor> SpMat;
// Prepare some sparse matrix
SpMat spmat;
// Extract lines from it
const SpMat& row_i = spmat.innerVector(i);
const SpMat& row_j = spmat.innerVector(j);
// Some calculation with row_i and row_j...
经过我的测试,row_i
和row_j
的数据是从spmat
复制的(!!)。
但是,显然,它是低效的。
内部向量的数据(尤其是row_i.m_data.m_values
& row_i.m_data.m_indices
)是原始数据(分别为spmat.m_data.m_values
& spmat.m_data.m_indices
)的连续部分,所以应该有更聪明的方法。
我也许能够实现新的方法来做到这一点,但这需要我深入研究源代码。所以我不想。
任何帮助表示感谢! 提前致谢。
【问题讨论】:
【参考方案1】:您可以使用 c++11 auto
关键字将 row_i
和 row_j
声明为真正的读写表达式,或者使用正确的类型:
const auto row_i = spmap.innerVector(i); // C++11 version
const SpMat::InnerVectorReturnType row_i = spmap.innerVector(i); // C++98 version
此外,默认情况下,SparseMatrix 并非存储在主要列中,因此“内部向量”是一列。如果要引用行,则必须使用行优先存储布局:
typedef Eigen::SparseMatrix<double,RowMajor> SpMat;
【讨论】:
它按我的预期工作! Thxs :) 也感谢您指出列/行主要。我修改了我的问题。【参考方案2】:您可以尝试使用MappedSparseMatrix
类。它包装了一组现有的数据和相关参数(我想,我从未使用过它)。我认为它的工作原理类似于 Eigen::Map
类,但我可能错了。
MappedSparseMatrix<double> mat(int rows, int cols, int nnz,
int* outerIndexPtr, int* innerIndexPtr,
Scalar* valuePtr);
Source
【讨论】:
谢谢,它也解决了我的问题。我可以像Eigen::MappedSparseMatrix<double> row_i_map(1, spmat.innerSize(), nnz, spmat.outerIndexPtr()+j, spmat.innerIndexPtr(), spmat.valuePtr());
那样做。对于以后的用户,我指出MappedSparseMatrix
期望innerIndexPtr
和valuePtr
在内存上是连续的。这意味着,您只能与 innerVecotr(s)
一起使用,如果您想提取多个内部向量,则原始矩阵应为 compressd。
@ShinichiTAMURA 有没有办法知道每个外部、内部和值数组将容纳多少项?如果说我们需要创建一个深拷贝和memcpy
这些数组,有没有办法提取这些大小?值和内部索引的 nnz 和外部索引的 (n+1) 的 CSR 定义似乎无法正常工作。企业社会责任链接:netlib.org/linalg/html_templates/node91.html
@Bar 你可以看this 看一个序列化s稀疏矩阵的例子。寻找outS = m.outerSize();
。
感谢@AviGinsburg。还有一个问题:MappedSparseMatrix 的创建是零拷贝,还是涉及数据拷贝?
@Bar 零拷贝。以上是关于从 Eigen::SparseMatrix 中提取块/ROI而不复制的主要内容,如果未能解决你的问题,请参考以下文章
从 postgres 表中提取 json 数组给出错误:无法从标量中提取元素
REST API 访问控制从访问令牌中提取主题与从路径参数中提取主题