Home | History | Annotate | Download | only in histogram
      1 /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
      2 
      3 Licensed under the Apache License, Version 2.0 (the "License");
      4 you may not use this file except in compliance with the License.
      5 You may obtain a copy of the License at
      6 
      7     http://www.apache.org/licenses/LICENSE-2.0
      8 
      9 Unless required by applicable law or agreed to in writing, software
     10 distributed under the License is distributed on an "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 See the License for the specific language governing permissions and
     13 limitations under the License.
     14 ==============================================================================*/
     15 
     16 #ifndef TENSORFLOW_LIB_HISTOGRAM_HISTOGRAM_H_
     17 #define TENSORFLOW_LIB_HISTOGRAM_HISTOGRAM_H_
     18 
     19 #include <string>
     20 #include <vector>
     21 #include "tensorflow/core/lib/gtl/array_slice.h"
     22 #include "tensorflow/core/platform/macros.h"
     23 #include "tensorflow/core/platform/mutex.h"
     24 #include "tensorflow/core/platform/thread_annotations.h"
     25 #include "tensorflow/core/platform/types.h"
     26 
     27 namespace tensorflow {
     28 
     29 class HistogramProto;
     30 
     31 namespace histogram {
     32 
     33 class Histogram {
     34  public:
     35   // Create a histogram with a default set of bucket boundaries.
     36   // Buckets near zero cover very small ranges (e.g. 10^-12), and each
     37   // bucket range grows by ~10% as we head away from zero.  The
     38   // buckets cover the range from -DBL_MAX to DBL_MAX.
     39   Histogram();
     40 
     41   // Create a histogram with a custom set of bucket boundaries,
     42   // specified in "custom_bucket_limits[0..custom_bucket_limits.size()-1]"
     43   // REQUIRES: custom_bucket_limits[i] values are monotonically increasing.
     44   // REQUIRES: custom_bucket_limits is not empty()
     45   explicit Histogram(gtl::ArraySlice<double> custom_bucket_limits);
     46 
     47   // Restore the state of a histogram that was previously encoded
     48   // via Histogram::EncodeToProto.  Note that only the bucket boundaries
     49   // generated by EncodeToProto will be restored.
     50   bool DecodeFromProto(const HistogramProto& proto);
     51 
     52   ~Histogram() {}
     53 
     54   void Clear();
     55   void Add(double value);
     56 
     57   // Save the current state of the histogram to "*proto".  If
     58   // "preserve_zero_buckets" is false, only non-zero bucket values and
     59   // ranges are saved, and the bucket boundaries of zero-valued buckets
     60   // are lost.
     61   void EncodeToProto(HistogramProto* proto, bool preserve_zero_buckets) const;
     62 
     63   // Return the median of the values in the histogram
     64   double Median() const;
     65 
     66   // Return the "p"th percentile [0.0..100.0] of the values in the
     67   // distribution
     68   double Percentile(double p) const;
     69 
     70   // Return the average value of the distribution
     71   double Average() const;
     72 
     73   // Return the standard deviation of values in the distribution
     74   double StandardDeviation() const;
     75 
     76   // Returns a multi-line human-readable string representing the histogram
     77   // contents.  Example output:
     78   //   Count: 4  Average: 251.7475  StdDev: 432.02
     79   //   Min: -3.0000  Median: 5.0000  Max: 1000.0000
     80   //   ------------------------------------------------------
     81   //   [      -5,       0 )       1  25.000%  25.000% #####
     82   //   [       0,       5 )       1  25.000%  50.000% #####
     83   //   [       5,      10 )       1  25.000%  75.000% #####
     84   //   [    1000,   10000 )       1  25.000% 100.000% #####
     85   std::string ToString() const;
     86 
     87  private:
     88   double min_;
     89   double max_;
     90   double num_;
     91   double sum_;
     92   double sum_squares_;
     93 
     94   std::vector<double> custom_bucket_limits_;
     95   gtl::ArraySlice<double> bucket_limits_;
     96   std::vector<double> buckets_;
     97 
     98   double Remap(double x, double x0, double x1, double y0, double y1) const;
     99 
    100   TF_DISALLOW_COPY_AND_ASSIGN(Histogram);
    101 };
    102 
    103 // Wrapper around a Histogram object that is thread safe.
    104 //
    105 // All methods hold a lock while delegating to a Histogram object owned by the
    106 // ThreadSafeHistogram instance.
    107 //
    108 // See Histogram for documentation of the methods.
    109 class ThreadSafeHistogram {
    110  public:
    111   ThreadSafeHistogram() {}
    112   explicit ThreadSafeHistogram(gtl::ArraySlice<double> custom_bucket_limits)
    113       : histogram_(custom_bucket_limits) {}
    114   bool DecodeFromProto(const HistogramProto& proto);
    115 
    116   ~ThreadSafeHistogram() {}
    117 
    118   void Clear();
    119 
    120   // TODO(touts): It might be a good idea to provide a AddN(<many values>)
    121   // method to avoid grabbing/releasing the lock when adding many values.
    122   void Add(double value);
    123 
    124   void EncodeToProto(HistogramProto* proto, bool preserve_zero_buckets) const;
    125   double Median() const;
    126   double Percentile(double p) const;
    127   double Average() const;
    128   double StandardDeviation() const;
    129   std::string ToString() const;
    130 
    131  private:
    132   mutable mutex mu_;
    133   Histogram histogram_ GUARDED_BY(mu_);
    134 };
    135 
    136 }  // namespace histogram
    137 }  // namespace tensorflow
    138 
    139 #endif  // TENSORFLOW_LIB_HISTOGRAM_HISTOGRAM_H_
    140