(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