c++ - 对 Eigen Map 稀疏对象的操作

标签 c++ eigen

在我的申请中,我必须发送 Eigen::SparseMatrix<float>网络上的对象,这意味着我需要将它们序列化并在另一端将它们反序列化为 Eigen::Map<Eigen::SparseMatrix<float>> , 如 this question 中所建议.

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

但是,当我尝试将两个 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;

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

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 对象,但有一些异常(exception)。具体来说,您不能更改内存,因此不允许调整大小、分配等。在你的例子中,

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

应该改为

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

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

附言文档中的示例仅讨论稠密矩阵,因此 operator+= 中的重新分配不相关。

关于c++ - 对 Eigen Map 稀疏对象的操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51958172/

相关文章:

c++ - 如何安全地向下转换 USTRUCT

c++ - 大括号括起来的初始化列表

c++ - Eigen:如何防止大对象的额外拷贝;分配给结果而不实现 RHS 上的完整矩阵

c++ - 具有 O2+ 优化的英特尔编译器上的 Eigen 交换函数中的错误

c++ - 使用信号中止功能实现

c++ - QSystemTrayIcon 分别处理左键和右键?

c++ - 特征:通过引用访问矩阵的列

c++ - 使用 SIMD 对稀疏矩阵中的内部迭代器进行特征迭代

c++ - 通过引用传递数组

C++ eigen3 线性代数库,奇怪的性能结果