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

function parsing unary expression

Tags: None
(comma "," separated)
quantdev
Registered Member
Posts
17
Karma
0

function parsing unary expression

Fri Aug 22, 2014 1:51 pm
How do I write a function which returns the output of a unary expression on a dense Eigen object?

As an example, suppose I want to write a function that checks whether each floating point number in a dense eigen object is normal, and returns 1.0 for the corresponding position if it is normal, or 0.0 if it is not. The output must not be evaluated immediately, and would preferably be in the form of an expression.

I've read through the documentation on passing eigen objects as parameters (http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html), which has led me to attempt the following:

Code: Select all
#include <functional>                                                             

#include <Eigen/Dense>                                                             

template <typename Derived>                                                       
auto Fun(const Eigen::DenseBase<Derived>& matrix) -> decltype(matrix.unaryExpr(std::ptr_fun<typename Derived::Scalar, bool>(std::isnormal)).template cast<typename Derived::Scalar>())
{                                                                                 
    return matrix.unaryExpr(std::ptr_fun<typename Derived::Scalar, bool>(std::isnormal)).template cast<typename Derived::Scalar>();
}                                                                                 

int main()                                                                         
{                                                                                 
    Eigen::Matrix<double, -1, -1> mat;                                             
    mat.resize(100,100);                                                           
    mat.fill(100);                                                                 
    auto mat2 = Fun(mat);                                                         

    return 0;                                                                     
}


This fails with the error that unaryExpr is not defined for an object of type Eigen::DenseBase<Derived>, and sure enough, if I look at the documentation for DenseBase I see that there is no such function.

So then, short of forcing evaluation every time I want to call this function and casting the eigen object to an evaluated Matrix, how can I achieve this?
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
You need to either take a MatrixBase or use matrix.derived().unaryExpr(...). Also, it's probably simpler to call ptr_fun as follow:
std::ptr_fun(std::isnormal<typename Derived::Scalar>)
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
btw, note that in your exemple mat2 is not a matrix but an expression so if you use mat2 multiple times, then the expression will be evaluated multiple times. For instance:

cout << mat2;
mat = ...;
cout << mat2;

will produce different outputs as mat2 stores a reference to mat.
quantdev
Registered Member
Posts
17
Karma
0
ggael wrote:You need to either take a MatrixBase or use matrix.derived().unaryExpr(...). Also, it's probably simpler to call ptr_fun as follow:
std::ptr_fun(std::isnormal<typename Derived::Scalar>)


Great, thank you :)

What is the overhead of calling the derived() method? Does it force evaluation of the expression or simply add some sort of "visitor" (not in the eigen sense) that gets evaluated with the rest of the expression?
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
derived() is simply a static cast to the Derived type.


Bookmarks



Who is online

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