2

I'm trying to replace the function for the sum of 3x1 Vector in Eigen with my own function. For example,

Matrix<float, 3, 1> q, q2, q3;
q.setRandom();
q2.setRandom();
q3.setRandom();
q3 = q + q2;

I hope that q3 is computed by my own function.

Since Eigen actually computes the sum by the operator= instead of operator+, and operator+ just returns a CwiseBinaryOp objects, I need to do overload the operator=.

Now I'm using EIGEN_MATRIX_PLUGIN marco to add my code to the Matrix.h of Eigen:

inline Matrix<float, 3, 1> &operator=(
const CwiseBinaryOp<internal::scalar_sum_op<float>, const Matrix<float, 3, 1>, const Matrix<float, 3, 1>>
    &op) {
    float *t = m_storage.data();
    op.lhs(); //error here
    return *this;
}

My own function needs to access the pointer to the data of q, q2 and q3. But I got the following error when trying to access the data of q and q2 by the CwiseBinaryOp object.

In file included from /home/tong/Program/Eigen/Eigen/src/Core/Matrix.h:340:0,
                 from /home/tong/Program/Eigen/Eigen/Core:294,
                 from /home/tong/Program/Eigen/Eigen/Dense:1,
                 from /home/tong/ClionProjects/EigenTest/main.cpp:7:
/home/tong/ClionProjects/EigenTest/MatrixAddon.h: In member function ‘Eigen::Matrix<float, 3, 1>& Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::operator=(const Eigen::CwiseBinaryOp<Eigen::internal::scalar_sum_op<float>, const Eigen::Matrix<float, 3, 1>, const Eigen::Matrix<float, 3, 1> >&)’:
/home/tong/ClionProjects/EigenTest/MatrixAddon.h:12:7: error: invalid use of incomplete type ‘const class Eigen::CwiseBinaryOp<Eigen::internal::scalar_sum_op<float>, const Eigen::Matrix<float, 3, 1>, const Eigen::Matrix<float, 3, 1> >’
     op.lhs();
       ^
In file included from /home/tong/Program/Eigen/Eigen/Core:252:0,
                 from /home/tong/Program/Eigen/Eigen/Dense:1,
                 from /home/tong/ClionProjects/EigenTest/main.cpp:7:
/home/tong/Program/Eigen/Eigen/src/Core/util/ForwardDeclarations.h:89:65: error: declaration of ‘const class Eigen::CwiseBinaryOp<Eigen::internal::scalar_sum_op<float>, const Eigen::Matrix<float, 3, 1>, const Eigen::Matrix<float, 3, 1> >’
 template<typename BinaryOp,  typename Lhs, typename Rhs>  class CwiseBinaryOp;

I wonder why does this error appear and how to get rid of it.

  • Well, I also tried what Džanan said with VS 2015 and it worked fine. I got the error when I was using g++ and I had to use it. But how could this problem have something to do with the compiler? –  Oct 24 '15 at 21:44

2 Answers2

1

I'm not sure what went wrong at your side, but I got it to work in the following way:

MatrixAddons.h

This is header that contains the definition of the operator= that you intend to place within Eigen::Matrix class.

Matrix<float, 3, 1>& operator=(
    const CwiseBinaryOp<internal::scalar_sum_op<float>, const Matrix<float,
    3, 1>, const Matrix<float, 3, 1>>& op)
{
    float *t = m_storage.data();
    op.lhs();
    return *this;
}

config.h

Header that defines the EIGEN_MATRIX_PLUGIN to point to the MatrixAddons.h header.

#define EIGEN_MATRIX_PLUGIN "MatrixAddons.h"

main.cpp

C++ source used to test the expanded Eigen::Matrix class.

#include <iostream>
#include "config.h"
#include "Eigen/Core"

int main()
{
    Eigen::Matrix<float, 3, 1> q1, q2, q3;
    q1.setRandom();
    q2.setRandom();
    q3 = q1 + q2;
    std::cout << q3 << std::endl;
}

A bit of debugging (or logging from new operator=) shows that newly added operator is invoked as part of q3 = q1 + q2 statement.

dbajgoric
  • 1,447
  • 11
  • 17
  • I used the exact same files as yours but still got this error. Did you add some flags when compiling? –  Oct 22 '15 at 19:25
  • Not really. I compiled the thing with MSVC 14.0 (VS 2015) if that can help you anyhow. – dbajgoric Oct 22 '15 at 19:35
  • But I have to use g++. So do you have any idea why this error has something to do with the compiler? –  Oct 24 '15 at 21:46
0

With g++, try running just the preprocessor (-E). When examining the output, you'll note that your operator= function appears in the middle of the definition of the Matrix class (the class declaration starts about 500 lines up). The declaration of the CwiseBinaryOp class appears above (about 5,000 lines above that) but is undefined. With your version, the compiler needs to use the definition of CwiseBinaryOp in the operator= function but it is not yet defined. The reason it works with MSVC and not g++ might be due to MSVC's "broken" two-phase template name lookup (I could be wrong on this. See e.g. here as to why MSVC accepts the code as opposed to g++).

You could get g++ to compile your function by changing it like so:

template <typename T>
Matrix<T, 3, 1>& operator=(
    const CwiseBinaryOp<
        internal::scalar_sum_op<T>,
        const Matrix<T, 3, 1>,
        const Matrix<T, 3, 1>
        > & op)
{
    std::cout << "Custom thingy\n";
    T *t = m_storage.data();
    op.lhs();
    return *this;
}

In this case, the operator= function is not "defined" until it's first use which is after the definition of the CwiseBinaryOp class (about 3,000 lines after the operator= definition).

Community
  • 1
  • 1
Avi Ginsburg
  • 10,323
  • 3
  • 29
  • 56
  • Thank you for pointing out the cause of this error. I think my problem is I try to use op.lhs(), but according to the result of preprocessor, CwiseBinaryOp is declared but not defined at that point. So the compiler doesn't know what lhs() is. My solution is just leaving the declaration of my function here and put the definition in another place after CwiseBinaryOp is defined. But I still can't understand why your code could access op.lhs() when CwiseBinary is not defined. –  Oct 27 '15 at 15:09
  • You're right. It's the `CwiseBinaryOp`, not the `Matrix` as I originally stated. The reason remains the same, however. The reason declaring it as a template helps is that the place in the code that the template is resolved is where where the `operator=` function is called, as opposed the original case where it needs to have the definition of the `CwiseBinaryOp` in the function definition. – Avi Ginsburg Oct 27 '15 at 15:41