This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Storing a reference to a block expression

Tags: None
(comma "," separated)
vivan
Registered Member
Posts
2
Karma
0
Hi,
I would like to store and pass around a reference to a block expression, e.g.:
Code: Select all
MyBlock = BigMatrix.block(...);

I have tried using the Eigen::Ref class but I ran into a problem, since there is no paramerless constructor in this class. Because of this, I can't declare the reference variable and assign the reference later. In my particular scenario, I used a std::map to store the refs:
Code: Select all
std::map<std::string, Eigen::Ref<Eigen::MatrixXd> > > MyMap;
MyMap["BeatifulBlock"] = BigMatrix.block(...);

which failed because the map tried to create an empty reference Eigen::Ref().
I have managed to fix it with a workaround using a pointer to Ref:
Code: Select all
boost::shared_ptr<Eigen::Ref<Eigen::MatrixXd> > MyBlockPtr(new Eigen::Ref(BigMatrix.block(...)));

but this is a bit convoluted way of storing a reference to the block.

Is there a better/proper way of doing this?
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
Eigen::Ref is supposed to behave as closely as possible to a c++ reference, like "double&". This is why there is no default ctor. If we were adding such a default ctor, then we would also need to add another method to modify a Ref such that it references another object. Indeed, Ref::operator= is supposed to modify the referenced object, not the Ref object itself.

Anyways, in your case, using std::map::insert instead of std::map::operator[] should do the job.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
For the record, here is an example:

Code: Select all
#include <map>
#include <iostream>
#include <Eigen/Core>
using namespace Eigen;
int main() {
  MatrixXd A(5,5);
 
  {
    typedef Ref<MatrixXd> MyRef;
    A.setRandom();
    std::map<int,MyRef> m;
    m.insert(std::make_pair( 4,MyRef(A)));
    m.insert(std::make_pair(14,MyRef(A.block(0,1,3,4))));
    std::cout << m.at(14) << std::endl << std::endl;
  }
 
  {
    typedef Ref<const MatrixXd> MyRef;
    A.setRandom();
    std::map<int,MyRef> m;
    m.insert(std::make_pair( 4,A));
    m.insert(std::make_pair(14,A.block(0,1,3,4)));
    std::cout << m.at(14) << std::endl << std::endl;
  }
}
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
Btw, we also plain to add Ptr<> analogue to C++ pointers. Ptr<> will be more friendly with std::map. See: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=912
vivan
Registered Member
Posts
2
Karma
0
Thanks.

This will work for now and the Ptr<> class seems like a great idea :)


Bookmarks



Who is online

Registered users: Bing [Bot], Google [Bot], Yahoo [Bot]