summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/benchmark/src/stat.h
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/benchmark/src/stat.h')
-rw-r--r--3rdparty/benchmark/src/stat.h307
1 files changed, 307 insertions, 0 deletions
diff --git a/3rdparty/benchmark/src/stat.h b/3rdparty/benchmark/src/stat.h
new file mode 100644
index 00000000000..c4ecfe8e044
--- /dev/null
+++ b/3rdparty/benchmark/src/stat.h
@@ -0,0 +1,307 @@
+#ifndef BENCHMARK_STAT_H_
+#define BENCHMARK_STAT_H_
+
+#include <cmath>
+#include <limits>
+#include <ostream>
+#include <type_traits>
+
+
+namespace benchmark {
+
+template <typename VType, typename NumType>
+class Stat1;
+
+template <typename VType, typename NumType>
+class Stat1MinMax;
+
+typedef Stat1<float, int64_t> Stat1_f;
+typedef Stat1<double, int64_t> Stat1_d;
+typedef Stat1MinMax<float, int64_t> Stat1MinMax_f;
+typedef Stat1MinMax<double, int64_t> Stat1MinMax_d;
+
+template <typename VType>
+class Vector2;
+template <typename VType>
+class Vector3;
+template <typename VType>
+class Vector4;
+
+template <typename VType, typename NumType>
+class Stat1 {
+ public:
+ typedef Stat1<VType, NumType> Self;
+
+ Stat1() { Clear(); }
+ // Create a sample of value dat and weight 1
+ explicit Stat1(const VType &dat) {
+ sum_ = dat;
+ sum_squares_ = Sqr(dat);
+ numsamples_ = 1;
+ }
+ // Create statistics for all the samples between begin (included)
+ // and end(excluded)
+ explicit Stat1(const VType *begin, const VType *end) {
+ Clear();
+ for (const VType *item = begin; item < end; ++item) {
+ (*this) += Stat1(*item);
+ }
+ }
+ // Create a sample of value dat and weight w
+ Stat1(const VType &dat, const NumType &w) {
+ sum_ = w * dat;
+ sum_squares_ = w * Sqr(dat);
+ numsamples_ = w;
+ }
+ // Copy operator
+ Stat1(const Self &stat) {
+ sum_ = stat.sum_;
+ sum_squares_ = stat.sum_squares_;
+ numsamples_ = stat.numsamples_;
+ }
+
+ void Clear() {
+ numsamples_ = NumType();
+ sum_squares_ = sum_ = VType();
+ }
+
+ Self &operator=(const Self &stat) {
+ sum_ = stat.sum_;
+ sum_squares_ = stat.sum_squares_;
+ numsamples_ = stat.numsamples_;
+ return (*this);
+ }
+ // Merge statistics from two sample sets.
+ Self &operator+=(const Self &stat) {
+ sum_ += stat.sum_;
+ sum_squares_ += stat.sum_squares_;
+ numsamples_ += stat.numsamples_;
+ return (*this);
+ }
+ // The operation opposite to +=
+ Self &operator-=(const Self &stat) {
+ sum_ -= stat.sum_;
+ sum_squares_ -= stat.sum_squares_;
+ numsamples_ -= stat.numsamples_;
+ return (*this);
+ }
+ // Multiply the weight of the set of samples by a factor k
+ Self &operator*=(const VType &k) {
+ sum_ *= k;
+ sum_squares_ *= k;
+ numsamples_ *= k;
+ return (*this);
+ }
+
+ // Merge statistics from two sample sets.
+ Self operator+(const Self &stat) const { return Self(*this) += stat; }
+
+ // The operation opposite to +
+ Self operator-(const Self &stat) const { return Self(*this) -= stat; }
+
+ // Multiply the weight of the set of samples by a factor k
+ Self operator*(const VType &k) const { return Self(*this) *= k; }
+
+ // Return the total weight of this sample set
+ NumType numSamples() const { return numsamples_; }
+
+ // Return the sum of this sample set
+ VType Sum() const { return sum_; }
+
+ // Return the mean of this sample set
+ VType Mean() const {
+ if (numsamples_ == 0) return VType();
+ return sum_ * (1.0 / numsamples_);
+ }
+
+ // Return the mean of this sample set and compute the standard deviation at
+ // the same time.
+ VType Mean(VType *stddev) const {
+ if (numsamples_ == 0) return VType();
+ VType mean = sum_ * (1.0 / numsamples_);
+ if (stddev) {
+ VType avg_squares = sum_squares_ * (1.0 / numsamples_);
+ *stddev = Sqrt(avg_squares - Sqr(mean));
+ }
+ return mean;
+ }
+
+ // Return the standard deviation of the sample set
+ VType StdDev() const {
+ if (numsamples_ == 0) return VType();
+ VType mean = Mean();
+ VType avg_squares = sum_squares_ * (1.0 / numsamples_);
+ return Sqrt(avg_squares - Sqr(mean));
+ }
+
+ private:
+ static_assert(std::is_integral<NumType>::value &&
+ !std::is_same<NumType, bool>::value,
+ "NumType must be an integral type that is not bool.");
+ // Let i be the index of the samples provided (using +=)
+ // and weight[i],value[i] be the data of sample #i
+ // then the variables have the following meaning:
+ NumType numsamples_; // sum of weight[i];
+ VType sum_; // sum of weight[i]*value[i];
+ VType sum_squares_; // sum of weight[i]*value[i]^2;
+
+ // Template function used to square a number.
+ // For a vector we square all components
+ template <typename SType>
+ static inline SType Sqr(const SType &dat) {
+ return dat * dat;
+ }
+
+ template <typename SType>
+ static inline Vector2<SType> Sqr(const Vector2<SType> &dat) {
+ return dat.MulComponents(dat);
+ }
+
+ template <typename SType>
+ static inline Vector3<SType> Sqr(const Vector3<SType> &dat) {
+ return dat.MulComponents(dat);
+ }
+
+ template <typename SType>
+ static inline Vector4<SType> Sqr(const Vector4<SType> &dat) {
+ return dat.MulComponents(dat);
+ }
+
+ // Template function used to take the square root of a number.
+ // For a vector we square all components
+ template <typename SType>
+ static inline SType Sqrt(const SType &dat) {
+ // Avoid NaN due to imprecision in the calculations
+ if (dat < 0) return 0;
+ return sqrt(dat);
+ }
+
+ template <typename SType>
+ static inline Vector2<SType> Sqrt(const Vector2<SType> &dat) {
+ // Avoid NaN due to imprecision in the calculations
+ return Max(dat, Vector2<SType>()).Sqrt();
+ }
+
+ template <typename SType>
+ static inline Vector3<SType> Sqrt(const Vector3<SType> &dat) {
+ // Avoid NaN due to imprecision in the calculations
+ return Max(dat, Vector3<SType>()).Sqrt();
+ }
+
+ template <typename SType>
+ static inline Vector4<SType> Sqrt(const Vector4<SType> &dat) {
+ // Avoid NaN due to imprecision in the calculations
+ return Max(dat, Vector4<SType>()).Sqrt();
+ }
+};
+
+// Useful printing function
+template <typename VType, typename NumType>
+std::ostream &operator<<(std::ostream &out, const Stat1<VType, NumType> &s) {
+ out << "{ avg = " << s.Mean() << " std = " << s.StdDev()
+ << " nsamples = " << s.NumSamples() << "}";
+ return out;
+}
+
+// Stat1MinMax: same as Stat1, but it also
+// keeps the Min and Max values; the "-"
+// operator is disabled because it cannot be implemented
+// efficiently
+template <typename VType, typename NumType>
+class Stat1MinMax : public Stat1<VType, NumType> {
+ public:
+ typedef Stat1MinMax<VType, NumType> Self;
+
+ Stat1MinMax() { Clear(); }
+ // Create a sample of value dat and weight 1
+ explicit Stat1MinMax(const VType &dat) : Stat1<VType, NumType>(dat) {
+ max_ = dat;
+ min_ = dat;
+ }
+ // Create statistics for all the samples between begin (included)
+ // and end(excluded)
+ explicit Stat1MinMax(const VType *begin, const VType *end) {
+ Clear();
+ for (const VType *item = begin; item < end; ++item) {
+ (*this) += Stat1MinMax(*item);
+ }
+ }
+ // Create a sample of value dat and weight w
+ Stat1MinMax(const VType &dat, const NumType &w)
+ : Stat1<VType, NumType>(dat, w) {
+ max_ = dat;
+ min_ = dat;
+ }
+ // Copy operator
+ Stat1MinMax(const Self &stat) : Stat1<VType, NumType>(stat) {
+ max_ = stat.max_;
+ min_ = stat.min_;
+ }
+
+ void Clear() {
+ Stat1<VType, NumType>::Clear();
+ if (std::numeric_limits<VType>::has_infinity) {
+ min_ = std::numeric_limits<VType>::infinity();
+ max_ = -std::numeric_limits<VType>::infinity();
+ } else {
+ min_ = std::numeric_limits<VType>::max();
+ max_ = std::numeric_limits<VType>::min();
+ }
+ }
+
+ Self &operator=(const Self &stat) {
+ this->Stat1<VType, NumType>::operator=(stat);
+ max_ = stat.max_;
+ min_ = stat.min_;
+ return (*this);
+ }
+ // Merge statistics from two sample sets.
+ Self &operator+=(const Self &stat) {
+ this->Stat1<VType, NumType>::operator+=(stat);
+ if (stat.max_ > max_) max_ = stat.max_;
+ if (stat.min_ < min_) min_ = stat.min_;
+ return (*this);
+ }
+ // Multiply the weight of the set of samples by a factor k
+ Self &operator*=(const VType &stat) {
+ this->Stat1<VType, NumType>::operator*=(stat);
+ return (*this);
+ }
+ // Merge statistics from two sample sets.
+ Self operator+(const Self &stat) const { return Self(*this) += stat; }
+ // Multiply the weight of the set of samples by a factor k
+ Self operator*(const VType &k) const { return Self(*this) *= k; }
+
+ // Return the maximal value in this sample set
+ VType Max() const { return max_; }
+ // Return the minimal value in this sample set
+ VType Min() const { return min_; }
+
+ private:
+ // The - operation makes no sense with Min/Max
+ // unless we keep the full list of values (but we don't)
+ // make it private, and let it undefined so nobody can call it
+ Self &operator-=(const Self &stat); // senseless. let it undefined.
+
+ // The operation opposite to -
+ Self operator-(const Self &stat) const; // senseless. let it undefined.
+
+ // Let i be the index of the samples provided (using +=)
+ // and weight[i],value[i] be the data of sample #i
+ // then the variables have the following meaning:
+ VType max_; // max of value[i]
+ VType min_; // min of value[i]
+};
+
+// Useful printing function
+template <typename VType, typename NumType>
+std::ostream &operator<<(std::ostream &out,
+ const Stat1MinMax<VType, NumType> &s) {
+ out << "{ avg = " << s.Mean() << " std = " << s.StdDev()
+ << " nsamples = " << s.NumSamples() << " min = " << s.Min()
+ << " max = " << s.Max() << "}";
+ return out;
+}
+} // end namespace benchmark
+
+#endif // BENCHMARK_STAT_H_