2017-07-21 2 views
0

Eigen a une méthode replicate similaire à numpy.repeat, mais il ne supporte pas de répéter un nombre variable de fois. Par exemple:Comment faites-vous numpy.repeat dans Eigen?

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

donne

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

Comment puis-je reproduire ce comportement dans Eigen?

Répondre

3

Voilà ma tentative:

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; 
    } 
} 
0

J'aime la bibliothèque eigen et essayer d'encourager l'utilisation de l'API fourni autant que possible. Honnêtement, je n'ai pas cherché à trouver une fonction interne pour fournir ce que vous demandez, donc je vais vous croire que l'un n'existe pas. Si je devais le faire manuellement, j'utiliserais l'accès du pointeur au tableau sous-jacent et 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; 
} 

Mon VectorXt est similaire à votre ArrayXX juste pour un vecteur (Matrix<T, Dynamic,1>) à cause de l'exemple fourni.

+0

Ajout d'un meilleur exemple – user357269