Jpp
JQuantile.hh
Go to the documentation of this file.
1 #ifndef __JTOOLS__JQUANTILE__
2 #define __JTOOLS__JQUANTILE__
3 
4 #include <ostream>
5 #include <iomanip>
6 #include <cmath>
7 #include <limits>
8 #include <algorithm>
9 #include <map>
10 
11 #include "JLang/JException.hh"
12 #include "JLang/JTitle.hh"
13 #include "Jeep/JPrint.hh"
14 
15 
16 /**
17  * \author mdejong
18  */
19 
20 namespace JTOOLS {}
21 namespace JPP { using namespace JTOOLS; }
22 
23 namespace JTOOLS {
24 
25  using JLANG::JTitle;
27  using JLANG::JNoValue;
28 
29 
30  /**
31  * Quantile calculator.\n
32  * This class acts as a zero-dimensional histogram.
33  */
34  class JQuantile :
35  public JTitle
36  {
37  public:
38  /**
39  * Constructor.
40  *
41  * \param title title
42  * \param option option
43  */
44  JQuantile(const JTitle& title = "",
45  const int option = 0) :
46  JTitle (title),
47  quantiles(false)
48  {
49  reset();
50 
51  quantiles = (option > 0);
52  }
53 
54 
55  /**
56  * Constructor.\n
57  * Set range according to minimal and maximal value in input data.
58  *
59  * \param title title
60  * \param __begin begin of data
61  * \param __end end of data
62  * \param member pointer to data member
63  * \param w weight
64  */
65  template<class iterator_type, class value_type, class result_type>
67  iterator_type __begin,
68  iterator_type __end,
69  result_type value_type::*member,
70  const double w = 1.0) :
71  JTitle (title),
72  quantiles(true)
73  {
74  put(__begin, __end, member, w);
75  }
76 
77 
78  /**
79  * Constructor.\n
80  * Set range according to minimal and maximal value in input data.
81  *
82  * \param title title
83  * \param __begin begin of data
84  * \param __end end of data
85  * \param function pointer to member method
86  * \param w weight
87  */
88  template<class iterator_type, class value_type, class result_type>
90  iterator_type __begin,
91  iterator_type __end,
92  result_type (value_type::*function)() const,
93  const double w = 1.0) :
94  JTitle (title),
95  quantiles(true)
96  {
97  put(__begin, __end, function, w);
98  }
99 
100 
101  /**
102  * Reset.
103  */
104  void reset()
105  {
106  sum = 0.0;
107  rms = 0.0;
108  tot = 0.0;
109  num = 0;
110  min = +std::numeric_limits<double>::max();
111  max = -std::numeric_limits<double>::max();
112 
113  buffer.clear();
114  }
115 
116 
117  /**
118  * Put value.
119  *
120  * \param x value
121  * \param w weight
122  */
123  void put(const double x, const double w = 1.0)
124  {
125  sum += w*x;
126  rms += w*x*x;
127  tot += w;
128  num += 1;
129  min = std::min(min, x);
130  max = std::max(max, x);
131 
132  if (quantiles) {
133  buffer.insert(std::make_pair(x,w));
134  }
135  }
136 
137 
138  /**
139  * Put data.
140  *
141  * \param __begin begin of data
142  * \param __end end of data
143  * \param member pointer to data member
144  * \param w weight
145  */
146  template<class iterator_type, class value_type, class result_type>
147  void put(iterator_type __begin,
148  iterator_type __end,
149  result_type value_type::*member,
150  const double w = 1.0)
151  {
152  for (iterator_type i = __begin; i != __end; ++i) {
153  put((*i).*member, w);
154  }
155  }
156 
157 
158  /**
159  * Put data.
160  *
161  * \param __begin begin of data
162  * \param __end end of data
163  * \param function pointer to member method
164  * \param w weight
165  */
166  template<class iterator_type, class value_type, class result_type>
167  void put(iterator_type __begin,
168  iterator_type __end,
169  result_type (value_type::*function)() const,
170  const double w = 1.0)
171  {
172  for (iterator_type i = __begin; i != __end; ++i) {
173  put(((*i).*function)(), w);
174  }
175  }
176 
177 
178  /**
179  * Get total count.
180  *
181  * \return count
182  */
183  long long int getCount() const
184  {
185  return num;
186  }
187 
188 
189  /**
190  * Get total weight.
191  *
192  * \return weight
193  */
194  double getTotal() const
195  {
196  return tot;
197  }
198 
199 
200 
201  /**
202  * Get weighted sum.
203  *
204  * \return weighted sum
205  */
206  double getSum() const
207  {
208  return sum;
209  }
210 
211 
212  /**
213  * Get mean value.
214  *
215  * \return mean value
216  */
217  double getMean() const
218  {
219  if (tot != 0.0)
220  return sum / tot;
221  else
222  THROW(JDivisionByZero, "JQuantile::getMean()");
223  }
224 
225 
226  /**
227  * Get RMS.
228  *
229  * \return RMS
230  */
231  double getRMS() const
232  {
233  if (tot != 0.0)
234  return sqrt(rms/tot);
235  else
236  THROW(JDivisionByZero, "JQuantile::getRMS()");
237  }
238 
239 
240  /**
241  * Get standard deviation
242  *
243  * \return standard deviation
244  */
245  double getSTDev() const
246  {
247  if (tot != 0.0)
248  return sqrt(rms*tot - sum*sum)/tot;
249  else
250  THROW(JDivisionByZero, "JQuantile::getSTDev()");
251  }
252 
253 
254  /**
255  * Get maximal deviation from average.
256  *
257  * \param relative relative to average or absolute
258  * \return deviation
259  */
260  double getDeviation(const bool relative = true) const
261  {
262  if (relative)
263  return std::max(max - getMean(), getMean() - min);
264  else
265  return std::max(fabs(max), fabs(min));
266  }
267 
268 
269  /**
270  * Test relative accuracy.
271  *
272  * \param precision relative precision
273  * \return true if reached accuracy; else false
274  */
275  bool hasAccuracy(const double precision) const
276  {
277  return getCount() > 3 && getSTDev() < precision * getMean();
278  }
279 
280 
281  /**
282  * Get quantile.
283  *
284  * \param Q quantile
285  * \param reverse reverse
286  * \return value
287  */
288  double getQuantile(const double Q, const bool reverse = false) const
289  {
290  if (quantiles) {
291 
292  double W = 0.0;
293 
294  for (std::map<double, double>::const_iterator i = buffer.begin(); i != buffer.end(); ++i) {
295  W += i->second;
296  }
297 
298  if (reverse)
299  return getQuantile(buffer.rbegin(), buffer.rend(), Q*W);
300  else
301  return getQuantile(buffer. begin(), buffer. end(), Q*W);
302  }
303 
304  THROW(JNoValue, "JQuantile::getQuantile()");
305  }
306 
307 
308  /**
309  * Print quantile.
310  *
311  * \param out output stream
312  * \param lpr long print
313  */
314  std::ostream& print(std::ostream& out, bool lpr = true) const
315  {
316  using namespace std;
317 
318  const int nc = getTitle().size();
319 
320  if (lpr) {
321  out << setw(nc) << left << " " << ' '
322  << setw(10) << left << " mean" << ' '
323  << setw(10) << left << " STD" << ' '
324  << setw(10) << left << " deviation" << endl;
325  }
326 
327  out << setw(nc) << left << getTitle() << ' '
328  << SCIENTIFIC(10,2) << getMean() << ' '
329  << SCIENTIFIC(10,2) << getSTDev() << ' '
330  << SCIENTIFIC(10,2) << getDeviation(false) << endl;
331 
332  return out;
333  }
334 
335 
336  /**
337  * Print quantile.
338  *
339  * \param out output stream
340  * \param quantile quantile
341  * \return output stream
342  */
343  friend inline std::ostream& operator<<(std::ostream& out, const JQuantile& quantile)
344  {
345  return quantile.print(out, getLongprint(out));
346  }
347 
348  protected:
349  double sum;
350  double rms;
351  double tot;
352  double min;
353  double max;
354  long long int num;
355 
356  bool quantiles;
358 
359 
360  /**
361  * Get quantile.
362  *
363  * \param __begin begin of data
364  * \param __end end of data
365  * \param W weight
366  * \return value
367  */
368  template<class T>
369  static double getQuantile(T __begin, T __end, const double W)
370  {
371  double w = 0.0;
372 
373  for (T i = __begin; i != __end; ++i) {
374 
375  w += i->second;
376 
377  if (w >= W) {
378  return i->first;
379  }
380  }
381 
382  THROW(JNoValue, "JQuantile::getQuantile()");
383  }
384  };
385 }
386 
387 #endif
JException.hh
JTOOLS::JQuantile::buffer
std::multimap< double, double > buffer
Definition: JQuantile.hh:357
JTOOLS::w
data_type w[N+1][M+1]
Definition: JPolint.hh:708
JTOOLS::JQuantile::getCount
long long int getCount() const
Get total count.
Definition: JQuantile.hh:183
JPrint.hh
JLANG::JNoValue
Exception for missing value.
Definition: JException.hh:198
JTOOLS::JQuantile::getQuantile
static double getQuantile(T __begin, T __end, const double W)
Get quantile.
Definition: JQuantile.hh:369
JTOOLS::JQuantile::quantiles
bool quantiles
Definition: JQuantile.hh:356
JTOOLS::JQuantile::getDeviation
double getDeviation(const bool relative=true) const
Get maximal deviation from average.
Definition: JQuantile.hh:260
JTOOLS::JQuantile::min
double min
Definition: JQuantile.hh:352
JTOOLS::JQuantile::num
long long int num
Definition: JQuantile.hh:354
JTOOLS::JQuantile::hasAccuracy
bool hasAccuracy(const double precision) const
Test relative accuracy.
Definition: JQuantile.hh:275
JTOOLS::JQuantile::getSTDev
double getSTDev() const
Get standard deviation.
Definition: JQuantile.hh:245
JTOOLS::JQuantile::put
void put(iterator_type __begin, iterator_type __end, result_type value_type::*member, const double w=1.0)
Put data.
Definition: JQuantile.hh:147
JTOOLS::JQuantile::getSum
double getSum() const
Get weighted sum.
Definition: JQuantile.hh:206
JTOOLS::JQuantile::sum
double sum
Definition: JQuantile.hh:349
JTOOLS::JQuantile::JQuantile
JQuantile(const JTitle &title="", const int option=0)
Constructor.
Definition: JQuantile.hh:44
JPP
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Definition: JAAnetToolkit.hh:37
JTOOLS::JQuantile::JQuantile
JQuantile(const JTitle &title, iterator_type __begin, iterator_type __end, result_type value_type::*member, const double w=1.0)
Constructor.
Definition: JQuantile.hh:66
getLongprint
bool getLongprint(std::ostream &out)
Get long print option.
Definition: JPrint.hh:157
JLANG::JTitle
Auxiliary class for title.
Definition: JTitle.hh:19
JTOOLS::JQuantile::put
void put(const double x, const double w=1.0)
Put value.
Definition: JQuantile.hh:123
JTOOLS::JQuantile::getRMS
double getRMS() const
Get RMS.
Definition: JQuantile.hh:231
JTOOLS::JQuantile::rms
double rms
Definition: JQuantile.hh:350
JTitle.hh
JLANG::JTitle::getTitle
const std::string & getTitle() const
Get title.
Definition: JTitle.hh:55
THROW
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:670
JTOOLS::JQuantile::print
std::ostream & print(std::ostream &out, bool lpr=true) const
Print quantile.
Definition: JQuantile.hh:314
JTOOLS::JQuantile::max
double max
Definition: JQuantile.hh:353
JTOOLS::JQuantile::getTotal
double getTotal() const
Get total weight.
Definition: JQuantile.hh:194
SCIENTIFIC
Auxiliary data structure for floating point format specification.
Definition: JPrint.hh:518
std::map
Definition: JSTDTypes.hh:16
JTOOLS::JQuantile::getMean
double getMean() const
Get mean value.
Definition: JQuantile.hh:217
JTOOLS::JQuantile::put
void put(iterator_type __begin, iterator_type __end, result_type(value_type::*function)() const, const double w=1.0)
Put data.
Definition: JQuantile.hh:167
JTOOLS::JQuantile::tot
double tot
Definition: JQuantile.hh:351
JTOOLS::JQuantile
Quantile calculator.
Definition: JQuantile.hh:34
std::multimap< double, double >
JTOOLS::JQuantile::getQuantile
double getQuantile(const double Q, const bool reverse=false) const
Get quantile.
Definition: JQuantile.hh:288
JTOOLS::JQuantile::reset
void reset()
Reset.
Definition: JQuantile.hh:104
std
Definition: jaanetDictionary.h:36
JTOOLS::JQuantile::JQuantile
JQuantile(const JTitle &title, iterator_type __begin, iterator_type __end, result_type(value_type::*function)() const, const double w=1.0)
Constructor.
Definition: JQuantile.hh:89
JLANG::JDivisionByZero
Exception for division by zero.
Definition: JException.hh:270
JTOOLS
Auxiliary classes and methods for multi-dimensional interpolations and histograms.
Definition: JAbstractCollection.hh:9
JTOOLS::JQuantile::operator<<
friend std::ostream & operator<<(std::ostream &out, const JQuantile &quantile)
Print quantile.
Definition: JQuantile.hh:343
JLANG::JTitle::title
std::string title
Definition: JTitle.hh:73