Re: [eigen] Recursion and block matrices |
[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]
OK, I
added
# ifdef EIGEN_BLOCK_TRUE_PLUGIN # include EIGEN_BLOCK_TRUE_PLUGIN # endif just before the protected part of HasDirectAccess==true in Block.h, and have this in Block_true_plugin.h: ////////////////////// Block_true_plugin code //////////////// inline Block<XprType, BlockRows, BlockCols, InnerPanel, true> block( Index startRow2, Index startCol2, Index blockRows2, Index blockCols2 ) { return Block<XprType, BlockRows, BlockCols, InnerPanel, true> ( derived(), startRow2 + startRow(), // <-- Accessor does not exist startCol2 + startCol(), // <-- Accessor does not exist blockRows2, blockCols2 ); } /////////////////////////////////////////////////////////////////// but, as I discovered, this specialization inherits from MapBase<Block>, and unlike the generic Block definition: there is no startRow() and startCol() accessors. Any suggestions, please? On 08/28/2012 01:01 AM, Gael Guennebaud wrote: there is a specialization for Block (right after the generic implementation) for HasDirectAccess==true, so you need to add your specialization there too. With the devel branch you might try: void incr(Ref<MatrixXd> mat) { // no cast needed .... } gael On Tue, Aug 28, 2012 at 9:07 AM, Norman Goldstein <normvcr@xxxxxxxxx> wrote: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/ |