Saltar al contenido

Calcule la media y la desviación estándar de un vector de muestras en C++ usando Boost

Te damos la bienvenida a nuestro espacio, en este lugar vas a hallar la solucíon que estabas buscando.

Solución:

No sé si Boost tiene funciones más específicas, pero puedes hacerlo con la biblioteca estándar.

Dado std::vector vesta es la manera ingenua:

#include 

double sum = std::accumulate(v.begin(), v.end(), 0.0);
double mean = sum / v.size();

double sq_sum = std::inner_product(v.begin(), v.end(), v.begin(), 0.0);
double stdev = std::sqrt(sq_sum / v.size() - mean * mean);

Esto es susceptible de desbordamiento o subdesbordamiento para valores grandes o pequeños. Una forma ligeramente mejor de calcular la desviación estándar es:

double sum = std::accumulate(v.begin(), v.end(), 0.0);
double mean = sum / v.size();

std::vector diff(v.size());
std::transform(v.begin(), v.end(), diff.begin(),
               std::bind2nd(std::minus(), mean));
double sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), 0.0);
double stdev = std::sqrt(sq_sum / v.size());

ACTUALIZAR para C++11:

la llamada a std::transform se puede escribir usando una función lambda en lugar de std::minus y std::bind2nd(ahora en desuso):

std::transform(v.begin(), v.end(), diff.begin(), [mean](double x)  return x - mean; );

Si el rendimiento es importante para usted y su compilador es compatible con lambdas, el cálculo de stdev se puede hacer más rápido y más simple: en las pruebas con VS 2012, descubrí que el siguiente código es más de 10 veces más rápido que el código Boost dado en la respuesta elegida ; también es 5 veces más rápido que la versión más segura de la respuesta utilizando bibliotecas estándar proporcionadas por musiphil.

Tenga en cuenta que estoy usando la desviación estándar de la muestra, por lo que el siguiente código da resultados ligeramente diferentes (¿Por qué hay un menos uno en las desviaciones estándar?)

double sum = std::accumulate(std::begin(v), std::end(v), 0.0);
double m =  sum / v.size();

double accum = 0.0;
std::for_each (std::begin(v), std::end(v), [&](const double d) 
    accum += (d - m) * (d - m);
);

double stdev = sqrt(accum / (v.size()-1));

Usando acumuladores es la forma de calcular medias y desviaciones estándar en Boost.

accumulator_set > acc;
for_each(a_vec.begin(), a_vec.end(), bind(ref(acc), _1));

cout << mean(acc) << endl;
cout << sqrt(variance(acc)) << endl;

Comentarios y calificaciones del artículo

Tienes la posibilidad dar visibilidad a este enunciado si si solucionó tu problema.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *