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

How to ommit rows containing NaN/Inf?

Tags: None
(comma "," separated)
siciliner
Registered Member
Posts
7
Karma
0
I would to check if rows contain NaN/Inf, if they do, ommit these rows. What i did in matlab is as follows:

ok = all(isfinite(data), 2);
data = data(ok, : )

Is there a quick way to do similar things in Eigen? Thanks.
User avatar
bjacob
Registered Member
Posts
658
Karma
3
There are two ways that you could do this, either you wrap isfinite() as a functor (you can directly use std::ptr_fun) and use Eigen's unaryExpr() method with it,
http://eigen.tuxfamily.org/dox-devel/cl ... 9a4c5a9bc4

Or you can implement your function right away on whole matrices from scratch:

Code: Select all
// bare implementation directly working on passed expression
// inefficient if the expression x is costly to evaluate, as it will
// be evaluated 4 times
//
// based on these facts: isnan(x) is just x==x
// and is_inf_or_nan(x) is just isnan(x-x)
template<typename Derived>
bool is_finite(const DenseBase<Derived>& x)
{
  return (x - x).array() == (x - x).array();
}


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!
vernal
Registered Member
Posts
37
Karma
0
When I try that code snippet I get a compile error. Is this Eigen3?
error C2678: binary '-' : no operator found which takes a left-hand operand of type 'const Eigen::DenseBase<Derived>' (or there is no acceptable conversion)
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
The following should really work (it was missing a .all()):

return ((x - x).array() == (x - x).array()).all();
vernal
Registered Member
Posts
37
Karma
0
Now it works Not any more...
Interestingly, it now works also without the .all() but the only thing I changed was uncommenting that code part again. Strange.
Thank you very much anyway!

EDIT: See following posts.

Last edited by vernal on Wed May 18, 2011 3:32 pm, edited 1 time in total.
vernal
Registered Member
Posts
37
Karma
0
I have to correct myself: It works in my MSVC Release configuration but not in the Debug configuration. I'll try to find out, what is going on.

EDIT: It seems to have to do with Qt. It tries to use a Qt operator- but I don't know why. Here is the error:
EDITEDIT: It doesn't have to do with Qt. See below.

Code: Select all
error C2678: binary '-' : no operator found which takes a left-hand operand of type 'const Eigen::DenseBase<Derived>' (or there is no acceptable conversion) with
[
  Derived=Eigen::Matrix<double,15,1>
]
c:\programme\qt\4.7.2\include\qtcore\../../src/corelib/tools/qsize.h(86): could be 'const QSize operator -(const QSize &,const QSize &)'
c:\programme\qt\4.7.2\include\qtcore\../../src/corelib/tools/qsize.h(236): or 'const QSizeF operator -(const QSizeF &,const QSizeF &)'
while trying to match the argument list '(const Eigen::DenseBase<Derived>, const Eigen::DenseBase<Derived>)'
with
[
  Derived=Eigen::Matrix<double,15,1>
]
..\src\mycode.cpp: see reference to function template instantiation 'bool is_finite<Derived>(const Eigen::DenseBase<Derived> &)' being compiled
with
[
  Derived=Eigen::Matrix<double,15,1>
]


And here is the code:
Code: Select all
template<typename Derived>
inline bool is_finite(const Eigen::DenseBase<Derived>& x)
{
   return ( (x - x).array() == (x - x).array()).all();
}


template<typename Derived>
inline bool is_nan(const Eigen::DenseBase<Derived>& x)
{
   return ((x == x).array()).all();
}


The code compiles fine in another project (Debug and Release) or in the Release configuration of the affected project.

How can I use Eigen's operator- directly? With Eigen::DenseBase<Derived> I can only find operator-=

Last edited by vernal on Thu May 19, 2011 11:20 am, edited 1 time in total.
vernal
Registered Member
Posts
37
Karma
0
I thought I had found the reason, but it worked only because the function call was inside an assert statement that is not evaluated in Release mode. :(
So it doesn't work neither in Debug nor in Release mode.
vernal
Registered Member
Posts
37
Karma
0
I'm continuing my monologue if no one has objections ;)

The mere function definition in another project worked fine (that's what I tried and posted in an earlier post), however using the function forces template instantiation and that's where it fails. In another project without any Qt involved a test with a Matrix4d shows that it tries to use the operator- of iterator. Why is the Eigen::DenseBase::operator- (or whatever is needed here) not found?

Code: Select all
error C2784: '_RanIt1::difference_type std::operator -(std::move_iterator<_RanIt> &,const std::move_iterator<_RanIt2> &)' : could not deduce template argument for 'std::move_iterator<_RanIt> &' from 'const Eigen::DenseBase<Derived>'
with
[
 Derived=Eigen::Matrix<double,4,4>
]
c:\programs\microsoft visual studio 10.0\vc\include\iterator(344) : see declaration of 'std::operator -'
[my path]\[my codefile].cpp: see reference to function template instantiation 'bool is_finite<Derived>(const Eigen::DenseBase<Derived> &)' being compiled
with
[
 Derived=Eigen::Matrix<double,4,4>
]


Conclusion: It has nothing to do with Qt but seems to be indeed Eigen related.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
I'm not sure to follow you, could you show a simple self contained example that trigger the issue.
vernal
Registered Member
Posts
37
Karma
0
I'm sorry for the confusion. I posted my findings as they came up. To me this example fails:

Code: Select all
#include <Eigen/Core>
#include <Eigen/Geometry>

using namespace Eigen;

template<typename Derived>
inline bool is_finite(const Eigen::DenseBase<Derived>& x)
{
   return ( (x - x).array() == (x - x).array()).all();
}


template<typename Derived>
inline bool is_nan(const Eigen::DenseBase<Derived>& x)
{
   return ((x == x).array()).all();
}

int main()
{
   Matrix4d testmat;
   testmat.setRandom();
   is_finite(testmat);
   is_nan(testmat);
}


With the error
Code: Select all
error C2676: binary '-' : 'const Eigen::DenseBase<Derived>' does not define this operator or a conversion to a type acceptable to the predefined operator   c:\mypath\test_eigen.cpp  Line 9

for the first function and
Code: Select all
error C2676: binary '==' : 'const Eigen::DenseBase<Derived>' does not define this operator or a conversion to a type acceptable to the predefined operator   c:\mypath\test_eigen.cpp  Line 15

for the second which is basically the same.

Am I doing something wrong here?
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
correct versions:

Code: Select all
template<typename Derived>
inline bool is_finite(const Eigen::MatrixBase<Derived>& x)
{
   return ( (x - x).array() == (x - x).array()).all();
}


template<typename Derived>
inline bool is_nan(const Eigen::MatrixBase<Derived>& x)
{
   return ((x.array() == x.array())).all();
}
vernal
Registered Member
Posts
37
Karma
0
Thank you! It was only a DenseBase vs. MatrixBase issue. Interesting.
Works also for me here.

Cheers
vernal


Bookmarks



Who is online

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