你怎么在Eigen做numpy.repeat?

时间:2017-07-21 13:40:36

标签: c++ numpy eigen

Eigen有一个类似于numpy.repeat的replicate方法,但它不支持重复变量次数。例如:

np.repeat(np.array([[ 0.,  1.,  2.], [ 3.,  4., 5.]]), [1, 2], axis=0)

给出

array([[ 0.,  1.,  2.],
       [ 3.,  4.,  5.],
       [ 3.,  4.,  5.]])

如何在Eigen中重现此行为?

2 个答案:

答案 0 :(得分:3)

这是我的尝试:

namespace Eigen {
    template <typename T>
    using ArrayXX = Array<T, Dynamic, Dynamic>;
}

template<typename A>
Eigen::ArrayXX<typename A::Scalar> repeat(const A& a, const Eigen::Ref<const Eigen::ArrayXi>& repeats, const int axis) {
    typedef typename A::Scalar T;
    if (axis==0) {
        eigen_assert(a.rows() == repeats.size());
        const int new_rows = repeats.sum();
        Eigen::ArrayXX<T> repeated_array (new_rows, a.cols());
        int j = 0;
        for (int i = 0; i < repeats.size(); ++i) {
            const int k = repeats(i);
            repeated_array.middleRows(j, k) = a.row(i).colwise().replicate(k);
            j += k;
        }
        return repeated_array;
    } else {
        eigen_assert(a.cols() == repeats.size());
        const int new_cols = repeats.sum();
        Eigen::ArrayXX<T> repeated_array (a.rows(), new_cols);
        int j = 0;
        for (int i = 0; i < repeats.size(); ++i) {
            const int k = repeats(i);
            repeated_array.middleCols(j, k) = a.col(i).rowwise().replicate(k);
            j += k;
        }
        return repeated_array;
    }
}

答案 1 :(得分:0)

我喜欢eigen库,并尝试尽可能鼓励使用提供的API。老实说,我很难找到一个内部函数来提供你所要求的内容,所以我相信你不会存在。如果我必须手动执行此操作,我将使用指针访问底层数组std::fill

#include <algorithm>

template<typename T>
Eigen::VectorXt<T> Repeat(const Eigen::VectorXt<T> &v, const Eigen::VectorXi &counts){
    Eigen::VectorXt<T> repeatedArray(counts.sum());
    T* dataPointer = repeatedArray.data();
    unsigned int placer = 0;
    for (unsigned int i = 0; i < counts.size(); ++i){
        std::fill(dataPointer + placer, dataPointer + placer + counts(i), v(i));
        placer += counts(i);
    }
    return repeatedArray;
}

由于提供的示例,我的VectorXt与您的ArrayXX类似,仅适用于向量(Matrix<T, Dynamic,1>)。