对 Eigen Map 稀疏对象的操作

Operations on Eigen Map sparse objects

在我的应用程序中,我必须通过网络发送 Eigen::SparseMatrix<float> 个对象,这意味着我需要将它们序列化并在另一端将它们反序列化为 Eigen::Map<Eigen::SparseMatrix<float>>,如 [=17] 中所建议=].

我现在的问题是,我想在接收端执行一些操作,即对所有到达的矩阵求和。

然而,当我尝试将两个 Eigen::Map 对象加在一起时,它会产生编译器错误。对于我尝试在 Eigen::Map:

上执行的任何操作都是如此
// This leads to a compiler error
Eigen::Map<Eigen::SparseMatrix<float>> recon = SerializedVectorToMappedSparseMatrix(serialized_vec);
Eigen::Map<Eigen::SparseMatrix<float>> recondouble = recon * 2;

error: conversion from ‘const type {aka const Eigen::SparseMatrix}’ to non-scalar type ‘Eigen::Map >’ requested
Eigen::Map> recondouble = (recon * 2).eval();

然而,这会按预期编译和工作:

Eigen::SparseMatrix<float> recondouble = recon * 2;

在我的网络案例中,我想对现有和传入的地图执行总和:

existing_matrix += incoming_matrix;

这会导致编译器错误:

error: no match for ‘operator=’ (operand types are ‘Eigen::Map >’ and ‘const Eigen::CwiseBinaryOp, const Eigen::Map >, const Eigen::Map > >’) return derived() = derived() + other.derived();

所以我的问题是:如果我们要在它们之间执行操作,我们是否应该将 Eigen::Map 对象转换为 Eigen:Matrix? The example in the docs 似乎另有建议。

我在使用 Eigen::Map 容器时是否做错了什么?

Map 对象是现有内存的包装器,允许您将其视为实际上是 Eigen 对象,但有一些例外。具体来说,您不能更改内存,因此不允许调整大小、分配等。在您的示例中,

Eigen::Map<Eigen::SparseMatrix<float>> recondouble = recon * 2;

应该改为

Eigen::SparseMatrix<float> recondouble = recon * 2;

(如您在问题中所述)因为 operator=/c'tor 需要为 recondouble 分配内存。稀疏 operator+= 经常需要重新分配内存,除非 rhs 元素是 lhs 元素的子集。我不知道映射的稀疏矩阵是否出于这个原因不允许此操作(我现在没有时间研究它)。

P.S。文档中的示例仅讨论密集矩阵,因此 operator+= 中的重新分配不相关。