Re: [eigen] Recursion and block matrices |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] Recursion and block matrices
- From: Gael Guennebaud <gael.guennebaud@xxxxxxxxx>
- Date: Tue, 28 Aug 2012 10:01:08 +0200
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type; bh=RXrwiiWXuUIpI3ZNQFT0qrmgjiXlXuqTaTC9YY45uxU=; b=kWxAedZRz5ImMlX1YfMFRZh5FISiTigES4zFG7vzA/jg3fq91KqyLAPVUibu+hfBT+ LVDK0yz/RdDxxO9amSlmjE6ROWZ5NDCc4eL9K/uhuYQe9RqbeeL0ye0I8KDp61GwqtJq gNf73moT5M5RagVfQEbk0hlB8Rm/JSqGXsumN0cXJzq1q60qUwAKTrQTU6DWZA4hX/+z jQotCKs+W6zTl1GktvhWDREJ1ZizAYom4t0tncD+6zZAkWDjn7h6ZT0jJNEob/73lSk0 tSbdvbJvzHRaJV2t2i6jdeF1DBgdGmko+OSG35gGqYtEg3aSw/w9tZYn9a4Ph/hHTc2W 7qzw==
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
>>
>>
>
>
>