2014-10-08 14 views

risposta

4

Sembra come sarebbe facile per scrivere se è solo per i vettori:

#include "Eigen/Core" 

template <typename T, typename T2> 
T extract(const T2& full, const T& ind) 
{ 
    int num_indices = ind.innerSize(); 
    T target(num_indices); 
    for (int i = 0; i < num_indices; i++) 
    { 
     target[i] = full[ind[i]]; 
    } 
    return target; 
} 

int main() 
{ 
    Eigen::VectorXd full(8); 
    full << 1, 2, 3, 4, 5, 6, 7, 8; 
    Eigen::Vector4d ind_vec(4); 
    ind_vec << 0, 2, 4, 5; 
    std::cout << "full:" << full<< std::endl; 
    std::cout << "ind_vec:" << ind_vec<< std::endl; 
    std::cout << "extracted" << extract(full,ind_vec) << std::endl; 
} 

che dovrebbe funzionare per la maggior parte dei casi

edit: nei casi in cui il tipo di indice scalare è diverso rispetto al tipo scalare di origine e di destinazione funzionerà quanto segue (per tutti i tipi Eigen incorporati).

template <typename T, typename T2> 
Eigen::Matrix<typename T2::Scalar,T::RowsAtCompileTime,T::ColsAtCompileTime,T::Options> 
extract2(const Eigen::DenseBase<T2>& full, const Eigen::DenseBase<T>& ind) 
{ 
    using target_t = Eigen::Matrix < T2::Scalar, T::RowsAtCompileTime, T::ColsAtCompileTime, T::Options > ; 
    int num_indices = ind.innerSize(); 
    target_t target(num_indices); 
    for (int i = 0; i < num_indices; i++) 
    { 
     target[i] = full[ind[i]]; 
    } 
    return target; 
} 

(questo è diverso da l'altro in che è possibile utilizzare un vettore di interi come indici e un vettore di raddoppia come fonte e ottenere un vettore di doppie restituito al posto di un vettore di int come extract() sopra farebbe do)

+0

Grazie! Immagino che sia il modo più efficiente. Anche se mi chiedo se questo è ciò che viene fatto dietro le quinte nell'estrazione di subvector in Matlab: qualcosa come x [[1,2,4,8]]. Passa attraverso un ciclo for su 1,2,4,8 come la tua soluzione o qualcosa di ancora più efficiente? – user1526533

+0

@ user1526533, Matlab è diverso da C++. – CroCo

7

Poiché la risposta corrente non è stata soddisfacente per me, ho cercato su Google un po 'e ho trovato this tutorial nella documentazione di Eigen.

#include <Eigen/Dense> 
#include <iostream> 
using namespace std; 
int main() 
{ 
    Eigen::ArrayXf v(6); 
    v << 1, 2, 3, 4, 5, 6; 
    cout << "v.head(3) =" << endl << v.head(3) << endl << endl; 
    cout << "v.tail<3>() = " << endl << v.tail<3>() << endl << endl; 
    v.segment(1,4) *= 2; 
    cout << "after 'v.segment(1,4) *= 2', v =" << endl << v << endl; 
} 

uscita sarà:

v.head(3) = 
1 
2 
3 

v.tail<3>() = 
4 
5 
6 

after 'v.segment(1,4) *= 2', v = 
1 
4 
6 
8 
10 
6 

non l'ho provato con i vettori, ma credo che dovrebbe essere possibile pure.