Re: [eigen] Recursion and block matrices

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


Thank you for the pointers. It is reassuring to know that it was a bug that stumped me. I coded up an override Block::block() method to avoid the infinite recursion:

////////////////////// Plugin Code //////////////////////////////////////
// EIGEN_BLOCK_PLUGIN

inline
Block<XprType, BlockRows, BlockCols, InnerPanel, HasDirectAccess>
block( Index startRow2,
       Index startCol2,
       Index blockRows2,
       Index blockCols2 )
{
  return
Block<XprType, BlockRows, BlockCols, InnerPanel, HasDirectAccess>
    ( derived(),
      startRow2 + startRow(),
      startCol2 + startCol(),
      blockRows2,
      blockCols2 );
}
/////////////////////////////////////////////////////////////////////////////

There is no Block plugin hook, so I put one in right before the protected section of Block.h .
Also, I slightly modified the test driver:

//////////////////////////////// Code ////////////////////////////////////
#include <Eigen/Core>
using namespace Eigen;

#include <iostream>
using namespace std;

template< class Derived >
void incr( const Block< Derived >& mat )     // <-- Using Block< Derived >
{
  Block< Derived >& matV =
    const_cast< Block< Derived >& >( mat );

  ++matV(0,0);

  if( ( 1 == mat.rows() ) ||
      ( 1 == mat.cols() ) )
  {
    return;
  }
  else
  {
incr( matV.block( 1, // <-- Using dynamic blocks, only
              1,
              mat.rows() - 1,
              mat.cols() - 1 ) );
  }
}// incr


int main( int argc, char* argv[] )
{
  MatrixXd mat( 2, 3 );
  mat << 1, 2, 3, 4, 5, 6;
  cout << "Before: " << mat << endl;

incr( mat.block( 0, 0, mat.rows(), mat.cols() ) ); // <-- Start off with a block

  cout << "After: " << mat << endl;
  return 0;
}// main
////////////////////////////////////////////////////////////////////////////////////////////////////

But there is still infinite recursion, even though the Block::block
method returns the same type of Block.  What am I missing?



On 08/27/2012 12:13 PM, Christoph Hertzberg wrote:
On 27.08.2012 19:33, Norman Goldstein wrote:
I haven't been able to figure out how to write a routine that calls
itself recursively
with successively smaller sub-blocks of the original matrix. Here is a
simple example,

With the current stable branch this is not possible, because this would possibly generate infinitely many template instanciations. See also:
http://eigen.tuxfamily.org/bz/show_bug.cgi?id=408
There is an experimental solution here:
http://eigen.tuxfamily.org/bz/show_bug.cgi?id=481.


[...]

template< class Derived >
void incr( const DenseBase< Derived >& mat )
{
   DenseBase< Derived >& matV =
     const_cast< DenseBase< Derived >& >( mat );
[...]
   {
     incr( mat.bottomRightCorner( mat.rows() - 1,
mat.cols() - 1 ) );

Your problem here, however, is that mat is const, so mat.bottomRightCorner(...) is a Block<const ...> and that inner const is not removed by a const_cast. If you do matV.bottomRightCorner(...) instead, you should get to the problem above ^^.

Btw:
If you just do tail recursion, you don't need to do recursion at all, just do sth like this:

template<class Derived>
void incr(const DenseBase<Derived>& mat){

    for(int i=mat.rows(); i>0; --i) {
        ++mat.bottomRightCorner(i,i)(0,0);
    }
}

This version only works for square matrices, I guess you get the idea, though.


Christoph






Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/