(C++) GetStdDev

February 24, 2017 · View on GitHub

 

 

 

 

 

(C++) GetStdDev

 

GetStdDev is a math code snippet to calculate the standard deviation of the values in a container.

 


#include <cassert> #include <cmath> #include <functional> #include <numeric> #include <vector> template <class T> struct SquareAccumulator   : public std::binary_function<T,T,T> {   const T operator()(const T& sum, const T& x) const     { return sum+(x*x); } }; //From http://www.richelbilderbeek.nl/CppGetStdDev.htm double GetStdDev(const std::vector<double>& v) {   assert(v.size() > 1     && "Can only calculate standard deviations from "        "data sets with size 2 or larger");   const double sum_x     = std::accumulate(v.begin(),v.end(),0.0);   const double sum_x_squared     = std::accumulate(v.begin(),v.end(),         0.0,SquareAccumulator<double>());   const double sz = static_cast<double>(v.size());   return std::sqrt(((sz*sum_x_squared)-(sum_x*sum_x))     / (sz*(sz-1.0))); }

 

 

 

 

 

GetStdDev test

 

GetStdDev was tested by a previous version of this code snippet.

 


#include <cassert> #include <cmath> #include <functional> #include <numeric> #include <vector> template <class T> struct SquareAccumulator   : public std::binary_function<T,T,T> {   const T operator()(const T& sum, const T& x) const     { return sum+(x*x); } }; //From http://www.richelbilderbeek.nl/CppGetStdDev.htm double GetStdDev(const std::vector<double>& v) {   assert(v.size() > 1     && "Can only calculate standard deviations from "        "data sets with size 2 or larger");   const double sum_x     = std::accumulate(v.begin(),v.end(),0.0);   const double sum_x_squared     = std::accumulate(v.begin(),v.end(),         0.0,SquareAccumulator<double>());   const double sz = static_cast<double>(v.size());   return std::sqrt(((sz*sum_x_squared)-(sum_x*sum_x))     / (sz*(sz-1.0))); } //From http://www.richelbilderbeek.nl/CppGetStdDev.htm double GetStdDevOld(const std::vector<double>& v) {   const std::size_t sz = v.size();   assert(sz>1);   double sumX = 0.0;   double sumXsquared = 0.0;   for (std::size_t i=0; i!=sz; ++i)   {     const double x = v[i];     sumX+=x;     sumXsquared+=(x*x);   }   const double dSize = static_cast<double>(sz);   return std::sqrt(((dSize*sumXsquared)     -(sumX*sumX))/(dSize *(dSize-1.0))); } #include <cstdlib> //From htpp://www.richelbilderbeek.nl/CppGetRandomUniform.htm double GetRandomUniform() {   return static_cast<double>(std::rand())     / static_cast<double>(RAND_MAX); } #include <iostream> //From htpp://www.richelbilderbeek.nl/CppGetStdDev.htm int main() {   std::vector<double> v;   v.push_back(GetRandomUniform());   v.push_back(GetRandomUniform());   int max = 2;   while (max != 33554432)   {     for (int i=0; i!=max; ++i)     {       v.push_back(GetRandomUniform());     }     std::cout << max << ":\t"       << GetStdDev(v) << "\t"       << GetStdDevOld(v) << std::endl;     max*=2;   } }

 

Screen output:

 


Starting /MyFolder/MyProject... 2: 0.207834 0.207834 4: 0.273555 0.273555 8: 0.2501 0.2501 16: 0.295567 0.295567 32: 0.301386 0.301386 64: 0.28569 0.28569 128: 0.290935 0.290935 256: 0.283272 0.283272 512: 0.283464 0.283464 1024: 0.289154 0.289154 2048: 0.288763 0.288763 4096: 0.288992 0.288992 8192: 0.288068 0.288068 16384: 0.288728 0.288728 32768: 0.288723 0.288723 65536: 0.28853 0.28853 131072: 0.288398 0.288398 262144: 0.288527 0.288527 524288: 0.288621 0.288621 1048576: 0.288542 0.288542 2097152: 0.288646 0.288646 4194304: 0.288659 0.288659 8388608: 0.288658 0.288658 16777216: 0.288649 0.288649 /MyFolder/MyProject exited with code 0