E 'possibile utilizzare accumulatori spinta con vettori?
-
29-09-2019 - |
Domanda
ho voluto usare accumulatori spinta per calcolare le statistiche di una variabile che è un vettore. C'è un modo semplice per fare questo. Penso che non è possibile utilizzare la cosa più stupida:
using namespace boost::accumulators;
//stuff...
accumulator_set<vector<double>, stats<tag::mean> > acc;
vector<double> some_vetor;
//stuff
some_vector = doStuff();
acc(some_vector);
forse questo è ovvio, ma ho provato comunque. : P
Quello che volevo era di avere un accumulatore che potrebbe calcolare un vettore che è la media dei componenti di molti vettori. C'è un facile via d'uscita?
EDIT:
Non so se sono stato il più chiaro possibile. Non voglio che questo:
for_each(vec.begin(), vec.end(),acc);
Ciò calcolare la media delle voci di un dato vettore. Quello che mi serve è diverso. Ho una funzione che sputare vettori:
vector<double> doSomething();
// this is a monte carlo simulation;
E ho bisogno di correre questo molte volte e calcolare il vettoriale media di quei vettori:
for(int i = 0; i < numberOfMCSteps; i++){
vec = doSomething();
acc(vec);
}
cout << mean(acc);
E voglio media (acc) per essere un vettore per sé, il cui ingresso [i] sarebbero i mezzi delle voci [i] dei vettori accumulati.
C'è un suggerimento su questo nei documenti di Boost, ma nulla di esplicito. E io sono un po 'stupido. : P
Soluzione
Ho esaminato la tua domanda un po ', e mi sembra che Boost.Accumulators fornisce già supporto per std::vector
. Ecco quello che ho potuto trovare in una sezione della guida dell'utente :
Un altro esempio in cui l'numerico Operatori sub-Library è utile è quando un tipo non definisce la overload dell'operatore tenuti ad utilizzarla per alcuni calcoli statistici. Per esempio,
std::vector<>
non sovraccaricare tutti gli operatori aritmetici, ma può essere utile utilizzarestd::vector<>
come un tipo di campione o variate. Il definisce Numerico Operatori sub-Library i sovraccarichi operatore necessarie ilboost::numeric::operators
namespace, che viene portata in portata dal Quadro Accumulatori con una direttiva using.
In effetti, dopo la verifica, il file boost/accumulators/numeric/functional/vector.hpp
non contenere gli operatori necessari per la soluzione 'ingenuo' al lavoro.
Credo che si dovrebbe provare:
- comprendente alternativamente
-
boost/accumulators/numeric/functional/vector.hpp
prima di qualsiasi altra accumulatori intestazione -
boost/accumulators/numeric/functional.hpp
definendoBOOST_NUMERIC_FUNCTIONAL_STD_VECTOR_SUPPORT
-
- Portare gli operatori in ambito con un
using namespace boost::numeric::operators;
.
C'è solo un ultimo dettaglio rimasto: esecuzione si romperà in fase di esecuzione perché il valore iniziale accumulato è default-e della costruzione asserzione si verifica quando si tenta di aggiungere un vettore di dimensione n ad un vettore vuoto . Per questo, a quanto pare si dovrebbe inizializzare l'accumulatore con (dove n è il numero di elementi nel vostro vettore):
accumulator_set<std::vector<double>, stats<tag::mean> > acc(std::vector<double>(n));
Ho provato il seguente codice, mean
mi dà un std::vector
di dimensione 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);
}
Credo che questo sia quello che volevi?
Altri suggerimenti
Io non ce l'ho impostato in modo da provare in questo momento, ma se tutto boost :: accumulatori esigenza è correttamente definito operatori matematici, allora si potrebbe essere in grado di cavarsela con un diverso tipo di vettore: http://www.boost.org/doc/libs/1_37_0/libs /numeric/ublas/doc/vector.htm
E che dire del documentazione ?
// 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 );