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

blitz++ or matlab find()

Tags: None
(comma "," separated)
n2k
Registered Member
Posts
41
Karma
0

blitz++ or matlab find()

Mon Aug 24, 2009 9:52 pm
Hi there,

I was wondering if there is a quick way to reproduce the Matlab/blitz++ function find() for vectors and matrixes. I wrote my own function but it looks a bit cumbersome. Any help is appreciated.

Btw, Eigen is by far the best library I've ever used, thank you!

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

void find(Eigen::MatrixXi A, Eigen::MatrixXi & F){
   F.resize(A.sum(),2);
   int k=0;
   for (int r=0; r<A.rows();++r){
   for (int c=0; c<A.cols();++c){
      if (A(r,c)==1){
         F.row(k)<<r,c;
         k+=1;
      }
   }}
}

int main (){

   
   Eigen::MatrixXd A;
   Eigen::MatrixXi F;
   A.setRandom(4,4);
   find((A.cwise()>0.5).cast<int>(),F);
   std::cout<< "A="<<std::endl<<A<<std::endl;
   std::cout<< "F="<<std::endl<<F<<std::endl;
}
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

Re: blitz++ or matlab find()

Tue Aug 25, 2009 7:51 am
hi,

I guess this function could fit in the Array module, find() being a member function of MatrixBase returning the coordinates, so that you would write:

F = (A.cwise()>0.5).find();

Note that you can already do that using EIGEN_MATRIXBASE_PLUGIN (see http://eigen.tuxfamily.org/api/Customiz ... MatrixBase).

At the same time this will remove the creation of an unnecessary temporary.

Also it should return a Matrix<int,Dynamic,2> instead of a MatrixXi. If we include it in Eigen this way we'll add a convenient:

typedef Matrix<int,Dynamic,2> MatricX2i;

Another problem is that the boolean matrix is evaluated twice, so 2 options:
- you return a std::vector<Vector2i> instead of a MatrixX2i and use std::vector::push(),
- you wait we add a conservativeResize() function in Matrix which will preserve the data while resizing.

Another option would be to allocate a big MatrixX2i of the same size than the input and return a VectorBlock expression of the meaningful part, but unfortunately this cannot be done easily because we cannot return an expression of a temporary object.
n2k
Registered Member
Posts
41
Karma
0

Re: blitz++ or matlab find()

Thu Oct 22, 2009 8:12 pm
Hi, I'm trying to use my find() functionality with EIGEN_MATRIXBASE_PLUGIN but I'm having a problem. The problem is with "cast" and, I suppose, M being template (?). I'm aware of the following topics:
viewtopic.php?f=74&t=62606&hilit=cast
viewtopic.php?f=74&t=57882&hilit=cast
but I think that doesn't apply to my case. I tried using the template keyword in many combinations but still receive ...

Code: Select all
expected primary-expression before 'int'

expected `)' before 'int'

expected `)' before ';' token

... at the "F.resize( (M.cast<int>()).sum() );" line. Can anybody please tell me what I'm doing wrong? The following is the function-form of the implementation that is giving me troubles.


Code: Select all

namespace Eigen {
   typedef Eigen::Matrix<int,Eigen::Dynamic,2> MatrixX2i;
}

   template<typename Derived>
   void find(const Eigen::MatrixBase<Derived>& M, Eigen::MatrixX2i & F){      
      F.resize( (M.cast<int>()).sum() ,2);
      int k=0;
      for (int r=0; r<M.rows();++r){
         for (int c=0; c<M.cols();++c){
            if (M(r,c)==true){
               F.row(k)<<r,c;
               k+=1;}}}
      
   }


Last edited by n2k on Thu Oct 22, 2009 8:20 pm, edited 1 time in total.
User avatar
bjacob
Registered Member
Posts
658
Karma
3

Re: blitz++ or matlab find()

Thu Oct 22, 2009 8:20 pm
Have you tried:
Code: Select all
F.resize( (M.template cast<int>()).sum() )


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

Re: blitz++ or matlab find()

Thu Oct 22, 2009 8:27 pm
Well... I thought I did, but apparently I didn't :)
Now it's working, thank you!

Btw, the correct line is:
F.resize( (M.template cast<int>()).sum(), 2 );
otherwise the compiler says:
YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX' is not a member of 'Eigen::ei_static_assert<false>'

Can the "2" in M.resize(*,2) be understood from the definition of MatrixX2i?
User avatar
bjacob
Registered Member
Posts
658
Karma
3

Re: blitz++ or matlab find()

Thu Oct 22, 2009 8:29 pm
Can the "2" in M.resize(*,2) be understood from the definition of MatrixX2i?


Ah, with the development branch you can do:

resize(newsize, NoChange);

not sure about the 2.0 branch.


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!


Bookmarks



Who is online

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