user3294195 user3294195 - 19 days ago 5
C++ Question

Eigen - Concatenated matrix as a reference

The following code concatenates a vector of ones to a matrix:

using Eigen::VectorXd;
using Eigen::MatrixXd;

MatrixXd cbind1(const Eigen::Ref<const MatrixXd> X) {
const unsigned int n = X.rows();
MatrixXd Y(n, 1 + X.cols());
Y << VectorXd::Ones(n), X;
return Y;
}


The function copies the contents of X to Y. How do I define the function so that it avoids doing the copy and returns a reference to a matrix containing
VectorXd::Ones(n), X
?

Thanks.

Answer

If you had followed and read ggael's answer to your previous question (and it appears you did, as you accepted his answer), you would have read this page of the docs. By modifying the example slightly, you could have written as part of an MCVE:

#include <iostream>
#include <Eigen/Core>

using namespace Eigen;

template<class ArgType>
struct ones_col_helper {
    typedef Matrix<typename ArgType::Scalar,
        ArgType::SizeAtCompileTime,
        ArgType::SizeAtCompileTime,
        ColMajor,
        ArgType::MaxSizeAtCompileTime,
        ArgType::MaxSizeAtCompileTime> MatrixType;
};

template<class ArgType>
class ones_col_functor
{
    const typename ArgType::Nested m_mat;

public:
    ones_col_functor(const ArgType& arg) : m_mat(arg) {};

    const typename ArgType::Scalar operator() (Index row, Index col) const {
        if (col == 0) return typename ArgType::Scalar(1);
        return m_mat(row, col - 1);
    }
};

template <class ArgType>
CwiseNullaryOp<ones_col_functor<ArgType>, typename ones_col_helper<ArgType>::MatrixType>
cbind1(const Eigen::MatrixBase<ArgType>& arg)
{
    typedef typename ones_col_helper<ArgType>::MatrixType MatrixType;
    return MatrixType::NullaryExpr(arg.rows(), arg.cols()+1, ones_col_functor<ArgType>(arg.derived()));
}

int main()
{
    MatrixXd mat(4, 4);
    mat << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16;

    auto example = cbind1(mat);

    std::cout << example << std::endl;
    return 0;
}