xerus
a general purpose tensor library
histogram.cpp
Go to the documentation of this file.
1 // Xerus - A General Purpose Tensor Library
2 // Copyright (C) 2014-2017 Benjamin Huber and Sebastian Wolf.
3 //
4 // Xerus is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as published
6 // by the Free Software Foundation, either version 3 of the License,
7 // or (at your option) any later version.
8 //
9 // Xerus is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
13 //
14 // You should have received a copy of the GNU Affero General Public License
15 // along with Xerus. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // For further information on Xerus visit https://libXerus.org
18 // or contact us at contact@libXerus.org.
19 
25 #include <xerus/misc/histogram.h>
26 #include <xerus/misc.h>
27 #include <xerus/misc/internal.h>
28 
29 namespace xerus { namespace misc {
30 
31  LogHistogram::LogHistogram(const double _base) : base(_base), totalCount(0) {}
32 
34  REQUIRE(misc::approx_equal(_other.base, base), "only histograms of identical base can be added");
35  for (const auto &h : _other.buckets) {
36  buckets[h.first] += h.second;
37  }
38  totalCount += _other.totalCount;
39  return *this;
40  }
41 
42  void LogHistogram::add(double _value, size_t _count) {
43  double logRate = log(_value)/log(base);
44  REQUIRE(std::isfinite(_value), "tried to add illegal value " << _value << " into a histogram");
45  buckets[int(logRate)] += _count;
46  totalCount += _count;
47  }
48 
49  LogHistogram LogHistogram::read_from_file(const std::string &_fileName) {
50  std::ifstream in(_fileName);
51  LogHistogram result(0.0);
52  std::string line;
53  std::getline(in, line);
54  REQUIRE(line == "# raw data:", "unknown histogram file format " << _fileName); //TODO this should throw an exception
55  char c;
56  in >> c;
57  REQUIRE(c == '#', "missing information in histogram file " << _fileName);
58  in >> result.base >> result.totalCount;
59  std::getline(in, line); // read in rest of this line
60  std::getline(in, line); // line now contains all buckets
61  std::stringstream bucketData(line);
62  bucketData >> c;
63  REQUIRE(c == '#', "missing information in histogram file " << _fileName);
64  int bucketIndex;
65  while (bucketData >> bucketIndex) {
66  size_t count;
67  if (!(bucketData >> count)) {
68  LOG(fatal, "missing bucket count in histogram file " << _fileName);
69  }
70  result.buckets[bucketIndex] = count;
71  }
72  size_t accountedTime=0;
73  for (auto &h : result.buckets) {
74  accountedTime += h.second;
75  }
76  REQUIRE(accountedTime == result.totalCount, "histogram data inconsistent in file " << _fileName);
77  return result;
78  }
79 
80  void LogHistogram::dump_to_file(const std::string &_fileName) const {
81  std::ofstream out(_fileName);
82  out << "# raw data:\n";
83  out << "# " << base << ' ' << totalCount << '\n';
84  out << '#';
85  for (auto &h : buckets) {
86  out << ' ' << h.first << ' ' << h.second;
87  }
88  out << "\n# plotable data:\n";
89  if (!buckets.empty()) {
90  int firstOutput = buckets.begin()->first - 1;
91  int lastOutput = buckets.rbegin()->first + 1;
92  for (int i=firstOutput; i<=lastOutput; ++i) {
93  out << pow(base, i) << ' ';
94  if (buckets.count(i) > 0) {
95  out << double(buckets.find(i)->second)/double(totalCount) << '\n';
96  } else {
97  out << "0\n";
98  }
99  }
100  }
101  out.close();
102  }
103 
104 } // namespace misc
105 } // namespace xerus
106 
Default include file for the misc (ie. non-tensor) functionality.
void dump_to_file(const std::string &_fileName) const
Definition: histogram.cpp:80
#define REQUIRE
Definition: internal.h:33
#define LOG
Definition: internal.h:38
bool approx_equal(T _a, T _b, T _eps=4 *std::numeric_limits< T >::epsilon()) noexcept
: Checks whether the relative difference between _a and _b (i.e. |a-b|/(|a|/2+|b|/2)) is smaller than...
Definition: math.h:91
The main namespace of xerus.
Definition: basic.h:37
Header file for comfort functions and macros that should not be exported in the library.
LogHistogram & operator+=(const LogHistogram &_other)
Definition: histogram.cpp:33
static LogHistogram read_from_file(const std::string &_fileName)
Definition: histogram.cpp:49
Header file for the histogram classes.
A logarithmic histogram, i.e. the size of all buckets is given by a constant factor [x - x*base) ...
Definition: histogram.h:37
void add(double _value, size_t _count=1)
Definition: histogram.cpp:42
std::map< int, size_t > buckets
Definition: histogram.h:40
LogHistogram(const double _base)
Definition: histogram.cpp:31
constexpr T pow(const T &_base, const uint32 _exp) noexcept
: Calculates _base^_exp by binary exponentiation
Definition: math.h:50