Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 #include <iterator>
11 
12 #include "JLang/JException.hh"
13 #include "JLang/JTitle.hh"
14 #include "JLang/JVectorize.hh"
15 #include "JLang/JManip.hh"
16 #include "JMath/JMath.hh"
17 
18 
19 /**
20  * \author mdejong
21  */
22 
23 namespace JTOOLS {}
24 namespace JPP { using namespace JTOOLS; }
25 
26 namespace JTOOLS {
27 
28  using JMATH::JMath;
29  using JLANG::JTitle;
31  using JLANG::JNoValue;
32  using JLANG::array_type;
33  using JLANG::make_array;
34 
35 
36  /**
37  * Auxiliary data structure for quantiles.
38  */
39  struct JQuantile_t :
40  public JTitle
41  {
42  /**
43  * Constructor.
44  *
45  * \param title title
46  * \param quantiles quantiles
47  */
48  JQuantile_t(const JTitle& title = "",
49  const bool quantiles = false) :
50  JTitle (title),
52  {
53  reset();
54  }
55 
56 
57  /**
58  * Reset.
59  */
60  void reset()
61  {
62  sum = 0.0;
63  rms = 0.0;
64  tot = 0.0;
65  num = 0;
66  min = std::numeric_limits<double>::max();
67  max = std::numeric_limits<double>::lowest();
68 
69  buffer.clear();
70  }
71 
72  protected:
73  double sum;
74  double rms;
75  double tot;
76  double min;
77  double max;
78  long long int num;
79  bool quantiles;
81  };
82 
83 
84  /**
85  * Quantile calculator.\n
86  * This class acts as a zero-dimensional histogram.
87  */
88  struct JQuantile :
89  public JQuantile_t,
90  public JMath<JQuantile>
91  {
92  /**
93  * Constructor.
94  *
95  * \param title title
96  * \param quantiles quantiles
97  */
98  JQuantile(const JTitle& title = "",
99  const bool quantiles = false) :
101  {}
102 
103 
104  /**
105  * Constructor.
106  *
107  * \param title title
108  * \param __begin begin of data
109  * \param __end end of data
110  * \param quantiles quantiles
111  * \param w weight
112  */
113  template<class iterator_type>
115  iterator_type __begin,
116  iterator_type __end,
117  const bool quantiles = false,
118  const double w = 1.0) :
119  JQuantile_t(title, quantiles)
120  {
121  put(__begin, __end, w);
122  }
123 
124 
125  /**
126  * Constructor.
127  *
128  * \param title title
129  * \param buffer input data
130  * \param quantiles quantiles
131  * \param w weight
132  */
133  template<class JElement_t, class JAllocator_t>
136  const bool quantiles = false,
137  const double w = 1.0) :
138  JQuantile_t(title, quantiles)
139  {
140  put(buffer, w);
141  }
142 
143 
144  /**
145  * Add quantile.
146  *
147  * \param Q quantile
148  * \return this quantile
149  */
151  {
152  sum += Q.sum;
153  rms += Q.rms;
154  tot += Q.tot;
155  num += Q.num;
156  min = std::min(min, Q.min);
157  max = std::max(max, Q.max);
158 
159  if (quantiles) {
160  std::copy(Q.buffer.begin(), Q.buffer.end(), std::inserter(buffer, buffer.end()));
161  }
162 
163  return *this;
164  }
165 
166 
167  /**
168  * Put value.
169  *
170  * \param x value
171  * \param w weight
172  */
173  void put(const double x, const double w = 1.0)
174  {
175  sum += w*x;
176  rms += w*x*x;
177  tot += w;
178  num += 1;
179  min = std::min(min, x);
180  max = std::max(max, x);
181 
182  if (quantiles) {
183  buffer.insert(std::make_pair(x,w));
184  }
185  }
186 
187 
188  /**
189  * Put data.
190  *
191  * \param __begin begin of data
192  * \param __end end of data
193  * \param w weight
194  */
195  template<class iterator_type>
196  void put(iterator_type __begin,
197  iterator_type __end,
198  const double w = 1.0)
199  {
200  for (iterator_type i = __begin; i != __end; ++i) {
201  put(*i, w);
202  }
203  }
204 
205 
206  /**
207  * Put data.
208  *
209  * \param buffer input data
210  * \param w weight
211  */
212  template<class JElement_t, class JAllocator_t>
214  const double w = 1.0)
215  {
216  for (typename array_type<JElement_t, JAllocator_t>::const_iterator i = buffer.begin(); i != buffer.end(); ++i) {
217  put(*i, w);
218  }
219  }
220 
221 
222  /**
223  * Get total count.
224  *
225  * \return count
226  */
227  long long int getCount() const
228  {
229  return num;
230  }
231 
232 
233  /**
234  * Get total weight.
235  *
236  * \return weight
237  */
238  double getTotal() const
239  {
240  return tot;
241  }
242 
243 
244  /**
245  * Get weighted sum.
246  *
247  * \return weighted sum
248  */
249  double getSum() const
250  {
251  return sum;
252  }
253 
254 
255  /**
256  * Get minimum.
257  *
258  * \return minimum
259  */
260  double getMin() const
261  {
262  return min;
263  }
264 
265 
266  /**
267  * Get maximum.
268  *
269  * \return maximum
270  */
271  double getMax() const
272  {
273  return max;
274  }
275 
276 
277  /**
278  * Get mean value.
279  *
280  * \return mean value
281  */
282  double getMean() const
283  {
284  if (tot != 0.0)
285  return sum / tot;
286  else
287  THROW(JDivisionByZero, "JQuantile::getMean()");
288  }
289 
290 
291  /**
292  * Get RMS.
293  *
294  * \return RMS
295  */
296  double getRMS() const
297  {
298  if (tot != 0.0)
299  return sqrt(rms/tot);
300  else
301  THROW(JDivisionByZero, "JQuantile::getRMS()");
302  }
303 
304 
305  /**
306  * Get standard deviation
307  *
308  * \return standard deviation
309  */
310  double getSTDev() const
311  {
312  if (tot != 0.0)
313  return sqrt(rms*tot - sum*sum)/tot;
314  else
315  THROW(JDivisionByZero, "JQuantile::getSTDev()");
316  }
317 
318 
319  /**
320  * Get maximal deviation from average.
321  *
322  * \param relative if true, relative to average, else absolute
323  * \return deviation
324  */
325  double getDeviation(const bool relative = true) const
326  {
327  if (relative)
328  return std::max(getMax() - getMean(), getMean() - getMin());
329  else
330  return getMax() - getMin();
331  }
332 
333 
334  /**
335  * Test relative accuracy.
336  *
337  * \param precision relative precision
338  * \return true if reached accuracy; else false
339  */
340  bool hasAccuracy(const double precision) const
341  {
342  return getCount() > 3 && getSTDev() < precision * getMean();
343  }
344 
345 
346  /**
347  * Get quantile.
348  *
349  * \param Q quantile
350  * \param reverse reverse
351  * \return value
352  */
353  double getQuantile(const double Q, const bool reverse = false) const
354  {
355  if (quantiles) {
356 
357  double W = 0.0;
358 
359  for (std::map<double, double>::const_iterator i = buffer.begin(); i != buffer.end(); ++i) {
360  W += i->second;
361  }
362 
363  if (reverse)
364  return getQuantile(buffer.rbegin(), buffer.rend(), Q*W);
365  else
366  return getQuantile(buffer. begin(), buffer. end(), Q*W);
367  }
368 
369  THROW(JNoValue, "Option 'quantiles' at JQuantile() incompatible with method getQuantile().");
370  }
371 
372 
373  /**
374  * Print quantile.
375  *
376  * \param out output stream
377  * \param lpr long print
378  */
379  std::ostream& print(std::ostream& out, bool lpr = true) const
380  {
381  using namespace std;
382 
383  const int nc = getTitle().size();
384 
385  if (lpr) {
386  out << setw(nc) << left << " " << ' '
387  << setw(10) << left << " mean" << ' '
388  << setw(10) << left << " STD" << ' '
389  << setw(10) << left << " deviation" << endl;
390  }
391 
392  out << setw(nc) << left << getTitle() << ' '
393  << SCIENTIFIC(10,2) << getMean() << ' '
394  << SCIENTIFIC(10,2) << getSTDev() << ' '
395  << SCIENTIFIC(10,2) << getDeviation(false) << endl;
396 
397  return out;
398  }
399 
400 
401  /**
402  * Print quantile.
403  *
404  * \param out output stream
405  * \param quantile quantile
406  * \return output stream
407  */
408  friend inline std::ostream& operator<<(std::ostream& out, const JQuantile& quantile)
409  {
410  return quantile.print(out, getLongprint(out));
411  }
412 
413  protected:
414  /**
415  * Get quantile.
416  *
417  * \param __begin begin of data
418  * \param __end end of data
419  * \param W weight
420  * \return value
421  */
422  template<class T>
423  static double getQuantile(T __begin, T __end, const double W)
424  {
425  double w = 0.0;
426 
427  for (T i = __begin; i != __end; ++i) {
428 
429  w += i->second;
430 
431  if (w >= W) {
432  return i->first;
433  }
434  }
435 
436  THROW(JNoValue, "Invalid weight " << W);
437  }
438  };
439 }
440 
441 #endif
JQuantile_t(const JTitle &title="", const bool quantiles=false)
Constructor.
Definition: JQuantile.hh:48
data_type w[N+1][M+1]
Definition: JPolint.hh:741
Exceptions.
bool hasAccuracy(const double precision) const
Test relative accuracy.
Definition: JQuantile.hh:340
Auxiliary base class for aritmetic operations of derived class types.
Definition: JMath.hh:110
double getTotal() const
Get total weight.
Definition: JQuantile.hh:238
long long int num
Definition: JQuantile.hh:78
double getSTDev() const
Get standard deviation.
Definition: JQuantile.hh:310
Quantile calculator.
Definition: JQuantile.hh:88
friend std::ostream & operator<<(std::ostream &out, const JQuantile &quantile)
Print quantile.
Definition: JQuantile.hh:408
double getMax() const
Get maximum.
Definition: JQuantile.hh:271
void put(iterator_type __begin, iterator_type __end, const double w=1.0)
Put data.
Definition: JQuantile.hh:196
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:670
std::multimap< double, double > buffer
Definition: JQuantile.hh:80
double getRMS() const
Get RMS.
Definition: JQuantile.hh:296
const std::string & getTitle() const
Get title.
Definition: JTitle.hh:55
double getMean() const
Get mean value.
Definition: JQuantile.hh:282
double getQuantile(const double Q, const bool reverse=false) const
Get quantile.
Definition: JQuantile.hh:353
Exception for missing value.
Definition: JException.hh:198
JQuantile(const JTitle &title="", const bool quantiles=false)
Constructor.
Definition: JQuantile.hh:98
double getMin() const
Get minimum.
Definition: JQuantile.hh:260
double getSum() const
Get weighted sum.
Definition: JQuantile.hh:249
std::ostream & print(std::ostream &out, bool lpr=true) const
Print quantile.
Definition: JQuantile.hh:379
JQuantile(const JTitle &title, iterator_type __begin, iterator_type __end, const bool quantiles=false, const double w=1.0)
Constructor.
Definition: JQuantile.hh:114
Auxiliary class for title.
Definition: JTitle.hh:19
const array_type< JValue_t > & make_array(const JValue_t(&array)[N])
Method to create array of values.
Definition: JVectorize.hh:37
do set_variable OUTPUT_DIRECTORY $WORKDIR T
bool getLongprint(std::ostream &out)
Get long print option.
Definition: JManip.hh:120
void put(const double x, const double w=1.0)
Put value.
Definition: JQuantile.hh:173
void put(const array_type< JElement_t, JAllocator_t > &buffer, const double w=1.0)
Put data.
Definition: JQuantile.hh:213
long long int getCount() const
Get total count.
Definition: JQuantile.hh:227
Auxiliary methods to convert data members or return values of member methods of a set of objects to a...
I/O manipulators.
JQuantile & add(const JQuantile &Q)
Add quantile.
Definition: JQuantile.hh:150
Auxiliary data structure for quantiles.
Definition: JQuantile.hh:39
double getDeviation(const bool relative=true) const
Get maximal deviation from average.
Definition: JQuantile.hh:325
std::string title
Definition: JTitle.hh:73
Exception for division by zero.
Definition: JException.hh:270
void copy(const Head &from, JHead &to)
Copy header from from to to.
Definition: JHead.cc:139
JQuantile(const JTitle &title, const array_type< JElement_t, JAllocator_t > &buffer, const bool quantiles=false, const double w=1.0)
Constructor.
Definition: JQuantile.hh:134
Base class for data structures with artithmetic capabilities.
static double getQuantile(T __begin, T __end, const double W)
Get quantile.
Definition: JQuantile.hh:423
void reset()
Reset.
Definition: JQuantile.hh:60
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:483
Auxiliary data structure for return type of make methods.
Definition: JVectorize.hh:25