Histogram.cpp
Go to the documentation of this file.
1 // kate: replace-tabs off; indent-width 4; indent-mode normal
2 // vim: ts=4:sw=4:noexpandtab
3 /*
4 
5 Copyright (c) 2010--2012,
6 François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland
7 You can contact the authors at <f dot pomerleau at gmail dot com> and
8 <stephane at magnenat dot net>
9 
10 All rights reserved.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright
15  notice, this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright
17  notice, this list of conditions and the following disclaimer in the
18  documentation and/or other materials provided with the distribution.
19  * Neither the name of the <organization> nor the
20  names of its contributors may be used to endorse or promote products
21  derived from this software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY
27 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34 */
35 #include "PointMatcherPrivate.h"
36 
37 #include "Histogram.h"
38 
39 #include <iostream>
40 #include <fstream>
41 #include <iomanip>
42 #include <limits>
43 #include <algorithm>
44 #include <boost/format.hpp>
45 
46 namespace PointMatcherSupport
47 {
48  using namespace std;
49 
50  template<typename T>
51  Histogram<T>::Histogram(const size_t binCount, const std::string& name, const std::string&
52  filePrefix, const bool dumpStdErrOnExit):
53  binCount(binCount),
54  name(name),
55  filePrefix(filePrefix),
56  dumpStdErrOnExit(dumpStdErrOnExit)
57  {
58  }
59 
60  template<typename T>
62  {
63  T meanV, varV, medianV, lowQt, highQt, minV, maxV;
64  uint64_t maxBinC;
65  if (!dumpStdErrOnExit && filePrefix.empty())
66  return;
67 
68  const vector<uint64_t> bins(computeStats(meanV, varV, medianV, lowQt, highQt, minV, maxV, maxBinC));
69 
70  if (!filePrefix.empty())
71  {
72  LOG_INFO_STREAM("writing to " << (filePrefix + name + "Stats.csv"));
73  std::ofstream ofs_stats((filePrefix + name + "Stats.csv").c_str());
74  dumpStatsHeader(ofs_stats);
75  ofs_stats << endl;
76  dumpStats(ofs_stats);
77 
78  LOG_INFO_STREAM("writing to " << (filePrefix + name + ".csv"));
79  std::ofstream ofs((filePrefix + name + ".csv").c_str());
80  for (size_t i = 0; i < this->size(); ++i)
81  ofs << ((*this)[i]) << "\n";
82  }
83 
84  if (dumpStdErrOnExit)
85  {
86  std::cerr.precision(4);
87  std::cerr.fill(' ');
88  std::cerr.flags(std::ios::left);
89  std::cerr << "Histogram " << name << ":\n";
90  std::cerr << " count: " << this->size() << ", mean: " << meanV << ", var: " << varV << ", median: " << medianV << ", min: " << minV << ", max: " << maxV << ", lowQt: " << lowQt << ", highQt: " << highQt << ", maxBinC: " << maxBinC << "\n";
91  if(this->size() > 1)
92  {
93  for (size_t i = 0; i < binCount; ++i)
94  {
95  const T v(minV + i * (maxV - minV) / T(binCount));
96  std::cerr << " " << std::setw(10) << v << " (" << std::setw(6) << bins[i] << ") : ";
97  //std::cerr << (bins[i] * 60) / maxBinC << " " ;
98  if (maxBinC > 0) {
99  for (size_t j = 0; j < (bins[i] * 60) / maxBinC; ++j)
100  std::cerr << "*";
101  }
102  std::cerr << "\n";
103  }
104  std::cerr << std::endl;
105  }
106  }
107  }
108 
109  template<typename T>
110  vector<uint64_t> Histogram<T>::computeStats(T& meanV, T& varV, T& medianV, T& lowQt, T& highQt, T& minV, T& maxV, uint64_t& maxBinC)
111  {
112  typedef typename std::vector<T>::iterator Iterator;
113  vector<uint64_t> bins(binCount, 0);
114 
115  //assert(this->size() > 0);
116  if(this->size() > 0)
117  {
118  // basic stats
119  meanV = 0;
120  minV = std::numeric_limits<T>::max();
121  maxV = std::numeric_limits<T>::min();
122  for (size_t i = 0; i < this->size(); ++i)
123  {
124  const T v((*this)[i]);
125  meanV += v;
126  minV = std::min<T>(minV, v);
127  maxV = std::max<T>(maxV, v);
128  }
129  meanV /= T(this->size());
130  // var and hist
131  std::fill(bins.begin(), bins.end(), uint64_t(0));
132  maxBinC = 0;
133  varV = 0;
134  if (minV == maxV)
135  {
136  medianV = lowQt = highQt = minV;
137  return bins;
138  }
139  for (size_t i = 0; i < this->size(); ++i)
140  {
141  const T v((*this)[i]);
142  varV += (v - meanV)*(v - meanV);
143  const size_t index((v - minV) * (binCount) / ((maxV - minV) * (1+std::numeric_limits<T>::epsilon()*10)));
144  //std::cerr << "adding value " << v << " to index " << index << std::endl;
145  ++bins[index];
146  maxBinC = std::max<uint64_t>(maxBinC, bins[index]);
147  }
148  varV /= T(this->size());
149  // median
150  std::vector<T> hystCpy((*this));
151  const Iterator lowQtIt(hystCpy.begin() + (hystCpy.size() / 4));
152  const Iterator medianIt(hystCpy.begin() + (hystCpy.size() / 2));
153  const Iterator highQtIt(hystCpy.begin() + (3*hystCpy.size() / 4));
154  std::nth_element(hystCpy.begin(), medianIt, hystCpy.end());
155  medianV = *medianIt;
156  std::nth_element(hystCpy.begin(), lowQtIt, hystCpy.end());
157  lowQt = *lowQtIt;
158  std::nth_element(hystCpy.begin(), highQtIt, hystCpy.end());
159  highQt = *highQtIt;
160  }
161  else
162  {
163  meanV = std::numeric_limits<T>::quiet_NaN();
164  varV = std::numeric_limits<T>::quiet_NaN();
165  medianV = std::numeric_limits<T>::quiet_NaN();
166  lowQt = std::numeric_limits<T>::quiet_NaN();
167  highQt = std::numeric_limits<T>::quiet_NaN();
168  minV = std::numeric_limits<T>::quiet_NaN();
169  maxV = std::numeric_limits<T>::quiet_NaN();
170  maxBinC = 0;
171  }
172  return bins;
173  }
174 
175  template<typename T>
176  void Histogram<T>::dumpStats(std::ostream& os)
177  {
178  T meanV, varV, medianV, lowQt, highQt, minV, maxV;
179  uint64_t maxBinC;
180  const vector<uint64_t> bins(computeStats(meanV, varV, medianV, lowQt, highQt, minV, maxV, maxBinC));
181  os << this->size() << ", " << meanV << ", " << varV << ", " << medianV << ", " << lowQt << ", " << highQt << ", " << minV << ", " << maxV << ", " << binCount << ", ";
182 
183  for (size_t i = 0; i < binCount; ++i)
184  os << bins[i] << ", ";
185  os << maxBinC;
186  }
187 
188  template<typename T>
189  void Histogram<T>::dumpStatsHeader(std::ostream& os) const
190  {
191  os << name + "_count, ";
192  os << name + "_mean, ";
193  os << name + "_var, ";
194  os << name + "_median, ";
195  os << name + "_low_quartile, ";
196  os << name + "_high_quartile, ";
197  os << name + "_min_value, ";
198  os << name + "_max_value, ";
199  os << name + "_bin_count, ";
200  for (size_t i = 0; i < binCount; ++i)
201  os << (boost::format("%1%_bin_%2%,") % name % i).str();
202  os << name + "_max_elements_per_bin ";
203  }
204 
205  template struct Histogram<unsigned>;
206  template struct Histogram<float>;
207  template struct Histogram<double>;
208 } // namespace PointMatcherSupport
void dumpStats(std::ostream &os)
Definition: Histogram.cpp:176
#define LOG_INFO_STREAM(args)
std::vector< uint64_t > computeStats(T &meanV, T &varV, T &medianV, T &lowQt, T &highQt, T &minV, T &maxV, uint64_t &maxBinC)
This function compute statistics and writes them into the variables passed as reference.
Definition: Histogram.cpp:110
const std::string filePrefix
Definition: Histogram.h:50
::std::string string
Definition: gtest.h:1979
void dumpStatsHeader(std::ostream &os) const
Definition: Histogram.cpp:189
Functions and classes that are not dependant on scalar type are defined in this namespace.
const std::string name
Definition: Histogram.h:49
Histogram(const size_t binCount, const std::string &name, const std::string &filePrefix, const bool dumpStdErrOnExit)
Definition: Histogram.cpp:51


libpointmatcher
Author(s):
autogenerated on Sat May 27 2023 02:38:02