2016-11-17 3 views
1

Если я хочу, чтобы объединить две матрицы A и B, я быЭйген :: Ссылка для конкатенации матриц

using Eigen::MatrixXd; 
const MatrixXd A(n, p); 
const MatrixXd B(n, q); 
MatrixXd X(n, p+q); 
X << A, B; 

Теперь, если n, p, q большие, определяя X таким образом будет означать создание копий от A и B. Можно ли определить X вместо Eigen::Ref<MatrixXd>?

Спасибо.

+0

Это может создать копию, но Эйген будучи библиотека шаблонов выражения фокусируется на устранение необходимости создания таких временных рядов. – Arunmu

+0

Я имел в виду, что 'X' сам является« копией »' A' и 'B'. Если есть временные копии 'A' и' B', то это будет две копии каждого! – user3294195

ответ

3

No, Ref не предназначен для этого. Мы/вам нужно было бы определить новое выражение для этого, которое можно было бы назвать Cat. Если вам нужно всего лишь конкатенировать две матрицы по горизонтали, то в Eigen 3.3 это может быть реализовано менее чем в десятке строк кода в качестве нулевого выражения, см. Некоторые примеры there.

Edit: здесь является самодостаточным примером, показывающим, что можно смешивать матрицы и выражение:

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

using namespace Eigen; 

template<typename Arg1, typename Arg2> 
struct horizcat_helper { 
    typedef Matrix<typename Arg1::Scalar, 
    Arg1::RowsAtCompileTime, 
    Arg1::ColsAtCompileTime==Dynamic || Arg2::ColsAtCompileTime==Dynamic 
    ? Dynamic : Arg1::ColsAtCompileTime+Arg2::ColsAtCompileTime, 
    ColMajor, 
    Arg1::MaxRowsAtCompileTime, 
    Arg1::MaxColsAtCompileTime==Dynamic || Arg2::MaxColsAtCompileTime==Dynamic 
    ? Dynamic : Arg1::MaxColsAtCompileTime+Arg2::MaxColsAtCompileTime> MatrixType; 
}; 

template<typename Arg1, typename Arg2> 
class horizcat_functor 
{ 
    const typename Arg1::Nested m_mat1; 
    const typename Arg2::Nested m_mat2; 

public: 
    horizcat_functor(const Arg1& arg1, const Arg2& arg2) 
    : m_mat1(arg1), m_mat2(arg2) 
    {} 

    const typename Arg1::Scalar operator() (Index row, Index col) const { 
    if (col < m_mat1.cols()) 
     return m_mat1(row,col); 
    return m_mat2(row, col - m_mat1.cols()); 
    } 
}; 

template <typename Arg1, typename Arg2> 
CwiseNullaryOp<horizcat_functor<Arg1,Arg2>, typename horizcat_helper<Arg1,Arg2>::MatrixType> 
horizcat(const Eigen::MatrixBase<Arg1>& arg1, const Eigen::MatrixBase<Arg2>& arg2) 
{ 
    typedef typename horizcat_helper<Arg1,Arg2>::MatrixType MatrixType; 
    return MatrixType::NullaryExpr(arg1.rows(), arg1.cols()+arg2.cols(), 
           horizcat_functor<Arg1,Arg2>(arg1.derived(),arg2.derived())); 
} 

int main() 
{ 
    MatrixXd mat(3, 3); 
    mat << 0, 1, 2, 3, 4, 5, 6, 7, 8; 

    auto example1 = horizcat(mat,2*mat); 
    std::cout << example1 << std::endl; 

    auto example2 = horizcat(VectorXd::Ones(3),mat); 
    std::cout << example2 << std::endl; 
    return 0; 
} 
+0

Спасибо за добавление в примере. Каков тип, принятый в примере example1 в приведенном выше коде? – user3294195

+0

Это 'CwiseNullaryOp', определяемый возвращаемым типом horizcat. – ggael

Смежные вопросы