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

Passing Eigen Arrays as function parameters

Tags: None
(comma "," separated)
GeorgeKnight
Registered Member
Posts
15
Karma
0
I've been struggling with a virtual class member function that takes an Eigen Array as parameter.
I've read http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html, but I still have problems.
I stripped down and simplified my code to the bare minimum:

One short header file:

Code: Select all
#include <Eigen/Core>

class Base
{
    public:
        virtual void myfunction(const Eigen::ArrayBase<double> &myArray);
};

class Derived : public Base
{
    public:
        virtual void myfunction(const Eigen::ArrayBase<double> &myArray);
};

void Derived::myfunction(const Eigen::ArrayBase<double> &myArray)
{
    Eigen::ArrayBase<double> &_myArray = const_cast<Eigen::ArrayBase<double>&>(myArray);
    _myArray.setOnes();
}


and one simple main file:

Code: Select all
#include <iostream>
#include <cstddef>
#include <Eigen/Core>
#include "header.h"

using namespace std;

int main()
{
    Derived derived;
    Eigen::ArrayXXd myArray(2,2);
    derived.myfunction(myArray);
    cout << myArray << endl;
   
    return EXIT_SUCCESS;
}



Compiling this code gives about a hundred lines of errors with Eigen internals, but the main problem seems to be that the statement

Code: Select all
_myArray.setOnes();


causes an implicit instantiation of an undefined template
Code: Select all
Eigen::internal::traits<double>
.
I'ld like the member function to work with ArrayXd, as well as ArrayXXd, as well as with a row() of a 2D Eigen Array. As it is virtual member function, I can't templatize it.

Any pointers to how this can be made to work?
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
ArrayBase<> can only be used in template code. In your case, the Ref<> class in the devel branch is what you need, all explanation there: http://eigen.tuxfamily.org/dox-devel/cl ... _1Ref.html
GeorgeKnight
Registered Member
Posts
15
Karma
0
Thanks Gaël, that seems exactly what I need. For the visitors who had the same question, I include a compilable code snippet below, with your suggestion taken into account. I have one remaining question:
Although I can change an element of a Ref<> object by e.g. myArray(0) = 1.0; it does not seem to allow myArray.setOnes(). I get an error "no viable conversion from 'const CwiseNullaryOp<...> Ref<...> non-const lvalue reference to type 'Ref<ArrayXd>' cannot bind to a temporary of type 'ColXpr'". Is this intentional?


------
The compilable code snippet. I want to define a virtual (member) function that accepts an ArrayXd, and I would also like it to work with an ArrayXXd.col() expression. The standard way of solving this, is with templates and ArrayBase<> as explained in the link in my original post. This does not work, however, with virtual functions as they cannot be templatized. The suggestion is to use the Ref<> class functionality in the Eigen developers branch.
The header file:

Code: Select all
#include <Eigen/Core>

typedef Eigen::Ref<Eigen::ArrayXd> RefArrayXd;

class Base
{
    public:
        virtual void myfunction(RefArrayXd myArray)=0;
};

class Derived : public Base
{
    public:
        virtual void myfunction(RefArrayXd myArray);
};

void Derived::myfunction(RefArrayXd myArray)
{
    // myArray.setOnes();     // does not compile
    myArray(0) = 1.0;         // does compile
}


and the main file:

Code: Select all
#include <iostream>
#include <cstddef>
#include <Eigen/Core>
#include "header.h"

using namespace std;

int main()
{
    Derived derived;
    Eigen::ArrayXXd myArray(2,2);
    derived.myfunction(myArray.col(0));
    cout << myArray << endl;
   
    return EXIT_SUCCESS;
}


-------
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
Should be fixed now.

https://bitbucket.org/eigen/eigen/commits/c61574c36caa/
changeset: c61574c36caa
user: ggael
date: 2013-02-07 17:49:16
summary: Add missing operator= in RefBase
GeorgeKnight
Registered Member
Posts
15
Karma
0
Great! Justed tested it, and it works nicely. Thanks!


Bookmarks



Who is online

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