2017-07-21 6 views
0

Eigen hat eine Methode replicate ähnlich wie numpy.repeat, aber es unterstützt nicht eine variable Anzahl von Wiederholungen zu wiederholen. Zum Beispiel:Wie machst du numpy.repeat in Eigen?

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

gibt

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

Wie kann ich dieses Verhalten in Eigen reproduzieren?

Antwort

3

Hier ist mein Versuch:

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

Ich mag die eigen Bibliothek und versuchen, unter Verwendung der bereitgestellten API so weit wie möglich zu fördern. Ich habe wirklich nicht nach einer internen Funktion gesucht, um das zu liefern, was Sie fragen, also werde ich Ihnen glauben, dass es keins gibt. Wenn ich dies manuell tun müsste, würde ich den Zeigerzugriff auf das zugrunde liegende Array und std::fill verwenden.

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

Mein VectorXt ist ähnlich wie Ihre ArrayXX nur für einen Vektor (Matrix<T, Dynamic,1>) wegen der vorgesehenen Beispiel.

+0

Ein besseres Beispiel hinzugefügt – user357269

Verwandte Themen