逐行和逐列重复本征矩阵的每个元素

时间:2019-11-14 15:24:07

标签: eigen

给出一个特征矩阵

Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> A(2, 2);
A << 11, 12, 21, 22;

从A获得尺寸为4x4的矩阵B的最优雅的方法是,其中A的每个元素都按行和按列重复一次。

11 11 12 12
11 11 12 12
21 21 22 22
21 21 22 22

我正在寻找一种通用解决方案,该解决方案可以扩展到A的任何给定行和列大小。

1 个答案:

答案 0 :(得分:2)

使用Eigen的头,用几行代码编写这样的repelem

template<typename XprType, typename RowFactorType, typename ColFactorType>
auto repelem(const XprType &xpr, RowFactorType row_factor, ColFactorType col_factor) {
    using namespace Eigen;

    const int RowFactor = internal::get_fixed_value<RowFactorType>::value;
    const int ColFactor = internal::get_fixed_value<ColFactorType>::value;
    const int NRows = XprType::RowsAtCompileTime == Dynamic || RowFactor == Dynamic ? Dynamic : XprType::RowsAtCompileTime*RowFactor;
    const int NCols = XprType::ColsAtCompileTime == Dynamic || ColFactor == Dynamic ? Dynamic : XprType::ColsAtCompileTime*ColFactor;
    const int nrows = internal::get_runtime_value(row_factor) * xpr.rows();
    const int ncols = internal::get_runtime_value(col_factor) * xpr.cols();

    return xpr(
        Array<int,NRows,1>::LinSpaced(nrows,0,xpr.rows()-1),
        Array<int,NCols,1>::LinSpaced(ncols,0,xpr.cols()-1)
    );
}

用法:

Array22i A;
A << 1, 2, 3, 4;
std::cout << repelem(A,2,2) << "\n";

完整演示:https://godbolt.org/z/rYgDxF

此代码可能看起来有些复杂,但是要保留编译时的大小,如以下测试所示:

Array22i A;
static_assert(decltype(repelem(A,fix<2>,fix<2>))::RowsAtCompileTime==4,"Bad compile-time size");

人们可以跟踪其是否包含在本征there中。