从 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_irow_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_irow_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&lt;double&gt; row_i_map(1, spmat.innerSize(), nnz, spmat.outerIndexPtr()+j, spmat.innerIndexPtr(), spmat.valuePtr()); 那样做。对于以后的用户,我指出MappedSparseMatrix 期望innerIndexPtrvaluePtr 在内存上是连续的。这意味着,您只能与 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 访问控制从访问令牌中提取主题与从路径参数中提取主题

FFmpeg从视频中提取音频

从时间中提取小时并添加转换为小时的分钟以及从时间中提取分钟并找到提醒(模数)

从.aar文件Android中提取代码

如何从Java中提取PDF文件中的表格数据