2010-11-30 24 views
13

Je voulais utiliser des accumulateurs boost pour calculer les statistiques d'une variable qui est un vecteur. Y a-t-il un moyen simple de le faire. Je pense qu'il est impossible d'utiliser la plus stupide chose:Est-il possible d'utiliser des accumulateurs boost avec des vecteurs?

using namespace boost::accumulators; 
    //stuff... 

    accumulator_set<vector<double>, stats<tag::mean> > acc; 
    vector<double> some_vetor; 
    //stuff 
    some_vector = doStuff(); 
    acc(some_vector); 

peut-être cela est évident, mais j'ai essayé quand même. : P

Ce que je voulais, c'était avoir un accumulateur qui calculerait un vecteur qui est la moyenne des composantes de nombreux vecteurs. Y a-t-il un moyen facile de sortir?

EDIT:

Je ne sais pas si je suis bien clair. Je ne veux pas cela:

for_each(vec.begin(), vec.end(),acc); 

Cela permettrait de calculer la moyenne des entrées d'un vecteur donné. Ce dont j'ai besoin est différent. J'ai une fonction qui crache des vecteurs:

vector<double> doSomething(); 
// this is a monte carlo simulation; 

Et je dois courir cela plusieurs fois et calculer la Vectorial signifie de ces vecteurs:

for(int i = 0; i < numberOfMCSteps; i++){ 
    vec = doSomething(); 
    acc(vec); 
    } 
    cout << mean(acc); 

Et je veux dire (acc) à être un vecteur lui-même, dont l'entrée [i] serait le moyen des entrées [i] des vecteurs accumulés.

Theres un indice à ce sujet dans les documents de Boost, mais rien d'explicite. Et je suis un peu bête. : P

+1

Soufflé à l'esprit. J'ai beaucoup utilisé Boost Accumulator, et je n'ai jamais compris qu'il supporte les types d'échantillons non-scalaires. – sehe

Répondre

9

Je l'ai regardé dans votre question un peu, et il me semble que Boost.Accumulators fournit déjà un soutien pour std::vector. Voici ce que je pouvais trouver dans a section of the user's guide:

Un autre exemple où les numérique Les opérateurs sous-bibliothèque est utile est lorsqu'un type ne définit pas les surcharge de l'opérateur requis pour l'utiliser pour certains calculs statistiques. Par exemple, std::vector<> ne surcharge aucun opérateur arithmétique, cependant il peut être utile d'utiliser std::vector<> comme un échantillon ou un type variable. Les opérateurs numériques Sous-Library définit les opérateurs nécessaires surcharges dans l'espace de noms boost::numeric::operators , qui est mis en portée par le cadre d'une Accumulateurs directive à l'aide.

En effet, après vérification, le fichier boost/accumulators/numeric/functional/vector.hppne contient les opérateurs nécessaires à la solution « naïve » de travailler.

Je crois que vous devriez essayer:

  • Y compris soit
    • boost/accumulators/numeric/functional/vector.hpp avant tout autre accumulateurs header
    • boost/accumulators/numeric/functional.hpp tout en définissant BOOST_NUMERIC_FUNCTIONAL_STD_VECTOR_SUPPORT
  • Apporter les opérateurs dans le périmètre d'un using namespace boost::numeric::operators; .

Il n'y a qu'un seul détail gauche: l'exécution cassera à l'exécution parce que la valeur initiale accumulée est construite par défaut, et une assertion se produit lorsque vous essayez d'ajouter un vecteur de taille n à un vecteur vide. Pour cela, il semble que vous devez initialiser l'accumulateur avec (où n est le nombre d'éléments dans votre vecteur):

accumulator_set<std::vector<double>, stats<tag::mean> > acc(std::vector<double>(n)); 

J'ai essayé le code suivant, mean me donne un std::vector de taille 2:

int main() 
{ 
    accumulator_set<std::vector<double>, stats<tag::mean> > acc(std::vector<double>(2)); 

    const std::vector<double> v1 = boost::assign::list_of(1.)(2.); 
    const std::vector<double> v2 = boost::assign::list_of(2.)(3.); 
    const std::vector<double> v3 = boost::assign::list_of(3.)(4.); 
    acc(v1); 
    acc(v2); 
    acc(v3); 

    const std::vector<double> &meanVector = mean(acc); 
} 

Je crois que c'est ce que vous vouliez?

+0

Probablement oui! Je vais l'essayer ici. Juste un min. –

+0

J'ai de la difficulté à compiler ceci, mais je pense que c'est correct. –

+0

@Rafael: J'ai édité ma réponse à propos de la compilation: soit inclure [...]/numeric/functional/vector.hpp' avant tout le reste, soit inclure [...]/numeric/functional.hpp' pendant que définir 'BOOST_NUMERIC_FUNCTIONAL_STD_VECTOR_SUPPORT' – icecrime

2

Je ne l'ai pas mis en place pour essayer dès maintenant, mais si tous les accumulateurs boost :: Le besoin est correctement défini les opérateurs mathématiques, alors vous pourriez être en mesure de sortir avec un autre type de vecteur: http://www.boost.org/doc/libs/1_37_0/libs/numeric/ublas/doc/vector.htm

+0

C'est probablement le chemin. Mais j'obtiens une erreur d'exécution de correspondance de taille avec ublas :: vector. Mais merci, c'est probablement ce qui va fonctionner. –

+1

J'essaie d'obtenir de l'aide dans la communauté boost :: ublas. Si je parviens à le faire fonctionner, je posterai une solution ici. –

-3

Et qu'en est-il du documentation?

// The data for which we wish to calculate statistical properties: 
std::vector<double> data(/* stuff */); 

// The accumulator set which will calculate the properties for us:  
accumulator_set< double, features< tag::min, tag::mean > > acc; 

// Use std::for_each to accumulate the statistical properties: 
acc = std::for_each(data.begin(), data.end(), acc); 
+1

Je pense qu'il veut un vecteur de moyennes pour un groupe de vecteurs, pas un seul moyen pour un seul vecteur, mais je peux me tromper. – Eclipse

+1

Nous devrons juste l'attendre et voir :) –

+0

Eclipse l'a eu. J'avoue que c'est un peu confus. Je veux un accumulateur qui accumule des vecteurs et renvoie un vecteur moyen. –