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

Converting House Matrix types to Eigen

Tags: None
(comma "," separated)
martinakos
Registered Member
Posts
53
Karma
0
OS
Hi,

I'm converting a library that uses house made matrix types for linear algebra to use Eigen instead. There is a lot of existing code using this house made matrix types. I'm thinking to keep an interface with the old types while converting the code of the classes to use Eigen. This allows me to convert one class at a time (as opposed to converting the whole library to Eigen in one go) and still be able to run the applications that use that class and run the regression tests on the new Eigen converted class.

To interface the house matrix types with Eigen I use Maps. However, I don't want to have to pass the Map as a parameter to other functions that already work with Eigen. I would like to be able to pass to the function a reference to the Map template parameter. I want to avoid copying the contents of the HouseMatrix too as this can be big. Is there any way of doing this?

For example, one thing I have tried so far is:

void f(HouseMatrix &hm)
{
Map<MatrixXd> mm(hm.data(), hm.rows(), hm.cols());
MatrixXd sm(hm.rows(), hm.cols());
sm.swap(mm);
f(sm);
sm.swap(mm);
}

void f(MatrixXd &m) //What I don't want is this function to be f(Map<MatrixXd> &m)
{

//some code

}

This code has the problem that when I declare the MatrixXd sm there is a memory allocation.
Is there a way to avoid allocating memory but just declare the header of a MatrixXd with the correct cols/rows?

Is there any other way to approach this?

Alternatively, if I don't find a solution, I may reimplement HouseMatrix internally using one Eigen::MatrixXd and then inside my function to be converted to Eigen I'll use the inner MatrixXd instead of the HouseMatrix. Then eventually change all the interfaces of classes to be Eigen only.

Cheers
Martin.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
actually, that depends on how different is the API of HouseMatrix compared to MatrixXd. If that's only a few functions names then you could also make MatrixXd API compatible using "plugins":
http://eigen.tuxfamily.org/dox-devel/To ... MatrixBase

Otherwise you can make f a template function accepting any MatrixBase object:

template<typename T> void f(const MatrixBase<T>& m);

and if you don't want to have everything in headers and that you are only interested in MAtrixXd and MAp, then you can keep the template f version in you cpp file and implement the two version of f taking Matrix and Map objects and calling the templated version.

void f(MatrixXd& m) { return f<MatrixXd>(m); }
void f(MatrixXd::Map& m) { return f<MatrixXd::Map>(m); }
martinakos
Registered Member
Posts
53
Karma
0
OS
Hi Ggael,

Thanks for your answer.

I though that if I had a function like
template<typename T> void f(const MatrixBase<T>& m)
and I call it with a argument of type Map<MatrixXd> there would be a temporary object created, and only because of the const the parameter m can be a reference.
So it wouldn’t be very efficient. Unless Map inherits from MatrixBase and I can’t see that in the documentation. Am I missing something?

Also in some cases f would need to modify the contents of m, so in these cases I couldn’t use the const. what could I do in these cases?

The HouseMatrix(s) (there are a few of them) APIs don’t do anything that can’t be done with Eigen alone. The plan is to finally get rid of them and use Eigen, but because of the large amount of code using this HouseMatrixes and the limited time I can use for this refactor, I’ll have to do it gradually while other people including me keeps using and adding things to our libraries. That’s why the need of using Maps.

Thanks.
Martin.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
Yes, Map<> inherits MatrixBase, that's why this solution is efficient. If you need a non const argument, then simply rm the const ;)


Actually, my suggestion was to extend Eigen's Matrix/MatrixBase to make it compatible with code written for your HouseMatrix(s). And then your HouseMatrix would simply be typedef to extended Eigen's type. But of course this solution may not be possible for you, that depends on the API of HouseMatrix. Typically you can only add methods and cannot remove some.
martinakos
Registered Member
Posts
53
Karma
0
OS
Hi Ggael,

Thanks for your answer. I’m actually a bit puzzled about Map<> inheriting MatrixBase as in the Eigen documentation there isn’t a trace of that. I see that Map inherits from MapBase and that’s all. Now, if I look into MapBase.h I see MapBase inherits from internal::dense_xpr_base<Derived>::type. I assume that the inheritance from MatrixBase comes through this. I thought these are internal details and I don’t need to go into there.

The API of HouseMatrix in not very consistent with other HouseMatrixes (there are many) that’s one reason why we want to migrate to Eigen. So just during the refactoring it’ll be necessary to do the wrappers explained in my first message.

Cheers
Martin.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
yes in this case internal::dense_xpr_base<Derived>::type returns MatrixBase. Basically all eigen expressions inherits either MatrixBase or ArrayBase depending whether they come from the array or linear algebra world.
martinakos
Registered Member
Posts
53
Karma
0
OS
Ok, thanks.


Bookmarks



Who is online

Registered users: bartoloni, Bing [Bot], Evergrowing, Google [Bot], q.ignora