Bar
Bar

Reputation: 2826

Operations on Eigen Map sparse objects

In my application I have to send Eigen::SparseMatrix<float> objects over the network, which means I need to serialize them and on the other end deserialize them into a Eigen::Map<Eigen::SparseMatrix<float>>, as suggested in this question.

My issue now is that I'd like to perform some operations on the receiving end, namely sum all matrices that arrive.

However when I try to add together two Eigen::Map objects it produces a compiler error. This is true for any operation I try to perform on an 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();

However this compiles and works as expected:

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

In my network case I'd like to perform a sum of the existing and incoming Map:

existing_matrix += incoming_matrix;

This causes the compiler error:

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();

So my question is: Are we supposed to convert Eigen::Map objects to Eigen:Matrix if we are to perform operations between them? The example in the docs seems to suggest otherwise.

Am I doing something wrong in my use of the Eigen::Map container?

Upvotes: 1

Views: 892

Answers (1)

Avi Ginsburg
Avi Ginsburg

Reputation: 10596

A Map object is a wrapper to existing memory, allowing you to treat it as if it's actually an Eigen object with a few exceptions. Specifically, you can't change the memory, so resizing, allocating, etc. aren't allowed. In your example,

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

should be changed to

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

(as you noted in your question) as the operator=/c'tor needs to allocate memory for recondouble. The sparse operator+= often needs to reallocate memory unless the rhs elements are a subset of the lhs ones. I don't know if the mapped sparse matrix disallows this operation for this reason or not (and I don't have time to look into it right now).

P.S. the example in the docs only talks about dense matrices, and therefore reallocation in operator+= is not relevant.

Upvotes: 1

Related Questions