Re: [eigen] Passing result of block() as non-const reference-to-matrix?

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


Hi everyone,

a second problem is that the result of testMatrix.block(0, 0, 2, 2) is a 
temporary object which cannot be bound to an lvalue reference. I'm not sure 
how to circumvent this problem in C++ 03, but if you are using C++0x, you can 
define a second function which takes an rvalue reference. The following 
program works with g++ 4.5 and -std=c++0x, and outputs

0 0 0
0 1 0
0 0 1


Cheers,
Martin




#include <Eigen/Core>

template <typename Derived>
void incrementBottomRight(Eigen::MatrixBase<Derived>& m)
{
    m(m.rows() - 1, m.cols() - 1) += 1.0;
}


template <typename Derived>
void incrementBottomRight(Eigen::MatrixBase<Derived>&& m)
{
    m(m.rows() - 1, m.cols() - 1) += 1.0;
}


int main()
{
    Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> testMatrix(3, 3);
    
    testMatrix.setZero();

    // This uses the first version with an lvalue-reference parameter
    incrementBottomRight(testMatrix);

    // This uses the second version with an rvalue-reference parameter
    incrementBottomRight(testMatrix.block(0, 0, 2, 2));

    std::cout << testMatrix << std::endl;

    return 0;
}




Am Freitag 09 Juli 2010, 11:52:52 schrieb Hauke Heibel:
> Hi Sidney,
> 
> that is expected since a matrix block is not a matrix. It is a special
> matrix expression which shares operations defined in MatrixBase and
> DenseBase with matrices. So you need to declare your function as a
> template function like this
> 
> template <typename Derived>
> void incrementBottomRight(Eigen::MatrixBase<Derived> & m)
> {
>    m(m.rows() - 1, m.cols() - 1) += 1.0;
> }
> 
> In case this is not an option you could probably do
> 
> void incrementBottomRight(Eigen::Block<MatrixXd> & m)
> {
>    m(m.rows() - 1, m.cols() - 1) += 1.0;
> }
> 
> but then the function will be limited to blocks only.
> 
> Regards,
> Hauke
> 
> On Fri, Jul 9, 2010 at 11:28 AM, Sidney Cadot <sidney.cadot@xxxxxxxxx> 
wrote:
> > Hello,
> > 
> > Today I found, to my surprise, that passing the result of a
> > Matrix::block() method to a function that takes a reference to an
> > Eigen::Matrix doesn't seem to work. The program (which doesn't compile)
> > demonstrates the problem.
> > 
> > I know that it /is/ possible to pass the result of a Matrix::block()
> > const call to a const reference to an Eigen::Matrix. Is it intentional
> > that the non-const version of this does not work?
> > 
> > Any help would be greatly appreciated.
> > 
> > Regards, Sidney
> > 
> > /////////////////////// code fragment starts here
> > 
> > #include <Eigen/Core>
> > 
> > void incrementBottomRight(Eigen::Matrix<double, Eigen::Dynamic,
> > Eigen::Dynamic> & m) {
> >    m(m.rows() - 1, m.cols() - 1) += 1.0;
> > }
> > 
> > int main()
> > {
> >    Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> testMatrix(3,
> > 3);
> > 
> >    // This works fine
> >    incrementBottomRight(testMatrix);
> > 
> >    // This gives a compiler error
> >    incrementBottomRight(testMatrix.block(0, 0, 2, 2));
> > 
> >    std::cout << testMatrix << std::endl;
> > 
> >    return 0;
> > }




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