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

Wrapping Eigen

Tags: None
(comma "," separated)
gregoire
Registered Member
Posts
3
Karma
0

Wrapping Eigen

Wed Aug 12, 2009 9:13 am
Hi,

I would like to know if someone as already tried to wrapp some Eigen classes (e.g. Matrix3d, Vector3d, ...) with SWIG.

If so, is it an easy task ? Do you have any advice ? Any SWIG file I could start with ?

Thanks.
User avatar
bjacob
Registered Member
Posts
658
Karma
3

Re: Wrapping Eigen

Wed Aug 12, 2009 12:30 pm
I don't know anything about SWIG but the closest thing that I've heard about is the Avogadro project which uses Boost::Python to make Python bindings; here's their file for Eigen:

http://avogadro.git.sourceforge.net/git ... 84;hb=HEAD

In any case, regardless of the technology that you use to make Python bindings, when wrapping Eigen it is very important to remember that you don't want to try to do expression templates in Python: Eigen is replete with compile-time mechanisms which would be too costly to execute at runtime in a Python interpreter. That means that you can't have the whole Eigen API faithfully mapped to Python, as far as I can see. Sorry i can't give more details, having no experience with python bindings generation, I hope the Avogadro link is useful.


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!
Seb
Registered Member
Posts
99
Karma
0

Re: Wrapping Eigen

Thu Aug 13, 2009 8:06 am
We are facing the very same problem, that is: Using SWIG to provide interfaces to the Lua language. As Benoit said, it is impossible to wrap the capabilities of expression templates and lazy evaluation. Moreover, SWIG can not provide in every script language what it promises. With the Swig-Lua module, for example, we experienced weird SWIG outputs regarding C++ references. And those are used everywhere in Eigen.

The specialties of SWIG are:
(1) differences in syntax.
A C++ function
Code: Select all
int func(const std::string & str, double & output);

would write in Lua
Code: Select all
 (return value, output) = func(str)


The parameter 'output' appears as additional return value of the function because it is a pure output parameter (similar to Matlab). One has to tell SWIG how to handle parameters. To this end one defines:
Code: Select all
#ifdef SWIG
int func(const std::string & INPUT, double & OUTPUT);
#endif

where the reserved words INPUT, OUTPUT and INOUT (the latter is a modifcation of existing objects) defines the way how to handle it. The problem: Languages like Lua do not support INOUT, that is one has to provide the copy constructor and then a new object will be returned which contains the modified data, eg. the function
Code: Select all
#ifdef SWIG
int func(const std::string & INPUT, double & INOUT);
#endif

would be translated to
Code: Select all
(return,output) func(string, output)


Notice that every script language handles such things differently. Therefore, one can not wrap any C++ logic 1-to-1.

Another example for this fact is, that Lua does not support the '=' operator and modifier operators such as '+='!

(2) bugs/special behaviour of SWIG
In the case of Lua, SWIG can not handle references at all. That is,

Code: Select all
#ifdef SWIG
int func(const std::string * INPUT, double * OUTPUT);
#endif

is correctly translated as
Code: Select all
(return,output) func(string)


whereas

Code: Select all
#ifdef SWIG
int func(const std::string & INPUT, double & OUTPUT);
#endif

results in
Code: Select all
(return) func(string, output)






Therefore, we decided to provide a wrapper to a simple abstraction layer of Eigen. Our considerations where:
  • Lua requires dynamically sized objects and knows only 'double' numbers.
  • The developers should be able to use the Eigen2 goodness on C++ level.
  • The developers should be able to use the SWIG goodness on Lua level, but when switching between both languages the learning curve must be steep regarding command set, etc.
  • We want to provide more features (i.e. Lapack bindings, statistics, Fourier, convenience functions etc.) on script level than Eigen2 provides out of the box.

Therefore, we derived the MatrixXd class of Eigen2, provided the wrapper definitions to wrapable functions, provide for each function 2 versions (one with references for C++ developers, one with pointers for SWIG). We still do not have a concept how to deal with expressions such as Eigen::CWise or ColWise/RowWise, though. It is not elegant, but sufficient for our audience.

I hope this helped a little,
Sebastian


Bookmarks



Who is online

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