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