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

Repeating each elements of an Eigen Matrix both row wise and column wise

给定一个特征矩阵,说

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 的任何给定行和列大小的通用解决方案。

使用 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");

人们可以跟踪它在 Eigen 中的包含情况 there