Jpp test-rotations-old-533-g2bdbdb559
the software that should make you happy
Loading...
Searching...
No Matches
JQuantiles.hh
Go to the documentation of this file.
1#ifndef __JTOOLS__JQUANTILES__
2#define __JTOOLS__JQUANTILES__
3
4#include <limits>
5#include <cmath>
6
7#include "JLang/JException.hh"
8#include "JTools/JRange.hh"
9#include "JTools/JElement.hh"
10#include "JTools/JResult.hh"
13
14
15/**
16 * \author mdejong
17 */
18
19namespace JTOOLS {}
20namespace JPP { using namespace JTOOLS; }
21
22namespace JTOOLS {
23
26
27
28 /**
29 * Quantile calculator for a given interpolating function.
30 * It is assumed that the function has a single maximum.
31 */
32 class JQuantiles :
33 public JRange<double>
34 {
35 public:
36
38
39 /**
40 * Default constructor.
41 */
43 Xmax(0.0),
44 Ymax(0.0),
45 fwhm(0.0),
46 sum (0.0)
47 {}
48
49
50 /**
51 * Constructor.
52 *
53 * \param f1 functional collection
54 * \param Q quantile
55 * \param eps relative precision
56 */
57 template<class JFunction1D_t>
58 JQuantiles(const JFunction1D_t& f1,
59 const double Q = 1.0,
60 const double eps = 1.0e-6) :
61 Xmax(0.0),
62 Ymax(0.0),
63 fwhm(0.0),
64 sum (0.0)
65 {
66 set(f1, Q, eps);
67 }
68
69
70 /**
71 * Constructor.
72 *
73 * \param abscissa abscissa
74 * \param f1 function
75 * \param Q quantile
76 * \param eps relative precision
77 */
78 template<class JFunction1D_t>
79 JQuantiles(const JAbscissa_t& abscissa,
80 const JFunction1D_t& f1,
81 const double Q = 1.0,
82 const double eps = 1.0e-6) :
83 Xmax(0.0),
84 Ymax(0.0),
85 fwhm(0.0),
86 sum (0.0)
87 {
88 set(abscissa, f1, Q, eps);
89 }
90
91
92 /**
93 * Set quantiles.
94 *
95 * \param f1 functional collection
96 * \param Q quantile
97 * \param eps relative precision
98 */
99 template<class JFunction1D_t>
100 void set(const JFunction1D_t& f1,
101 const double Q = 1.0,
102 const double eps = 1.0e-6)
103 {
104 typedef typename JFunction1D_t::const_iterator const_iterator;
105
106 if (f1.empty()) {
107 throw JEmptyCollection("JQuantiles() no data.");
108 }
109
110
111 // maximum
112
113 const_iterator p = f1.begin();
114
115 for (const_iterator i = f1.begin(); i != f1.end(); ++i) {
116 if (i->getY() > p->getY()) {
117 p = i;
118 }
119 }
120
121
122 // x at maximum
123
124 Xmax = p->getX();
125
126 if (p != f1.begin()) {
127
128 const double xa = (--p)->getX();
129 const double xb = (++p)->getX();
130
131 if (++p != f1.end()) {
132
133 const double xc = p->getX();
134
135 Xmax = search(xa, xb, xc, f1, -1, eps);
136 }
137 }
138
139 Ymax = get_value(f1(Xmax));
140
141
142 // integral & quantile
143
144 if (Q > 0.0 && Q <= 1.0) {
145
147
148 try {
149
150 sum = makeCDF(f1, buffer);
151
152 setLowerLimit(buffer(0.5 * (1.0 - Q)));
153 setUpperLimit(buffer(0.5 * (1.0 + Q)));
154 }
155 catch(const JException& error) {
156 sum = 0.0;
157 }
158
159 } else {
160
162
163 if (Q > 1.0) {
164 setLowerLimit(f1. begin()->getX());
165 setUpperLimit(f1.rbegin()->getX());
166 } else if (Q <= 0.0) {
169 }
170 }
171
172
173 // FWHM
174
175 fwhm = 0.0;
176
177 for (double xmin = f1.begin()->getX(), xmax = Xmax, v = 0.5*Ymax; ; ) {
178
179 const double x = 0.5 * (xmin + xmax);
180 const double y = get_value(f1(x));
181
182 if (fabs(y - v) < eps*v || xmax - xmin < eps) {
183 fwhm -= x;
184 break;
185 }
186
187 if (y > v)
188 xmax = x;
189 else
190 xmin = x;
191 }
192
193 for (double xmin = Xmax, xmax = f1.rbegin()->getX(), v = 0.5*Ymax; ; ) {
194
195 const double x = 0.5 * (xmin + xmax);
196 const double y = get_value(f1(x));
197
198 if (fabs(y - v) < eps*v || xmax - xmin < eps) {
199 fwhm += x;
200 break;
201 }
202
203 if (y > v)
204 xmin = x;
205 else
206 xmax = x;
207 }
208 }
209
210
211 /**
212 * Set quantiles.
213 *
214 * \param abscissa abscissa
215 * \param f1 function
216 * \param Q quantile
217 * \param eps relative precision
218 */
219 template<class JFunction1D_t>
220 void set(const JAbscissa_t& abscissa,
221 const JFunction1D_t& f1,
222 const double Q = 1.0,
223 const double eps = 1.0e-6)
224 {
226
227 buffer.configure(abscissa, f1);
228 buffer.compile();
229
230 set(buffer, Q, eps);
231 }
232
233
234 /**
235 * Get position of maximum.
236 *
237 * \return x value at maximum
238 */
239 double getX() const
240 {
241 return Xmax;
242 }
243
244
245 /**
246 * Get value of maximum.
247 *
248 * \return y value at maximum
249 */
250 double getY() const
251 {
252 return Ymax;
253 }
254
255
256 /**
257 * Get Full Width at Half Maximum.
258 *
259 * \return FWHM
260 */
261 double getFWHM() const
262 {
263 return fwhm;
264 }
265
266
267 /**
268 * Get integral of function.
269 *
270 * \return integral
271 */
272 double getIntegral() const
273 {
274 return sum;
275 }
276
277
278 protected:
279
280 double Xmax;
281 double Ymax;
282 double fwhm;
283 double sum;
284
285
286 /**
287 * Locate maximum or minimun of function.
288 *
289 * Golden section search code is adopted from reference:
290 * Numerical Recipes in C++, W.H. Press, S.A. Teukolsky, W.T. Vetterling and B.P. Flannery,
291 * Cambridge University Press.
292 *
293 * xa < xb < xc
294 *
295 * is = +1 -> There is a minimum, i.e: f(xb) < min(f(xa),f(xc))
296 * is = -1 -> There is a maximum, i.e: f(xb) > max(f(xa),f(xc))
297 *
298 * \param xa
299 * \param xb
300 * \param xc
301 * \param f function
302 * \param is sign (+1 -> minimim, -1 -> maximum)
303 * \param eps relative precision
304 */
305 template<class JFunction1D_t>
306 static double search(const double xa,
307 const double xb,
308 const double xc,
309 const JFunction1D_t& f,
310 const int is,
311 const double eps = 1.0e-6)
312 {
313 static const double R = 0.61803399;
314 static const double C = 1.0 - R;
315
316 double x0 = xa;
317 double x3 = xc;
318 double x1, x2;
319
320 if (fabs(xc-xb) > fabs(xb-xa)) {
321 x1 = xb;
322 x2 = xb + C*(xc-xb);
323 } else {
324 x2 = xb;
325 x1 = xb - C*(xb-xa);
326 }
327
328 double f1 = is * get_value(f(x1));
329 double f2 = is * get_value(f(x2));
330
331 while (fabs(x3-x0) > eps*(fabs(x1)+fabs(x2))) {
332
333 if (f2 < f1) {
334
335 x0 = x1;
336 x1 = x2;
337 x2 = R*x2 + C*x3;
338
339 f1 = f2;
340 f2 = is * get_value(f(x2));
341
342 } else {
343
344 x3 = x2;
345 x2 = x1;
346 x1 = R*x1 + C*x0;
347
348 f2 = f1;
349 f1 = is * get_value(f(x1));
350 }
351 }
352
353 if (f1 < f2)
354 return x1;
355 else
356 return x2;
357 }
358 };
359}
360
361#endif
The elements in a collection are sorted according to their abscissa values and a given distance opera...
Exceptions.
Auxiliary class to define a range between two values.
This include file containes various data structures that can be used as specific return types for the...
This include file contains various recursive methods to operate on multi-dimensional collections.
Exception for an empty collection.
General exception.
Definition JException.hh:24
General purpose class for collection of elements, see: <a href="JTools.PDF";>Collection of elements....
Definition JSet.hh:22
Quantile calculator for a given interpolating function.
Definition JQuantiles.hh:34
double getIntegral() const
Get integral of function.
void set(const JFunction1D_t &f1, const double Q=1.0, const double eps=1.0e-6)
Set quantiles.
static double search(const double xa, const double xb, const double xc, const JFunction1D_t &f, const int is, const double eps=1.0e-6)
Locate maximum or minimun of function.
double getY() const
Get value of maximum.
void set(const JAbscissa_t &abscissa, const JFunction1D_t &f1, const double Q=1.0, const double eps=1.0e-6)
Set quantiles.
JQuantiles(const JAbscissa_t &abscissa, const JFunction1D_t &f1, const double Q=1.0, const double eps=1.0e-6)
Constructor.
Definition JQuantiles.hh:79
JQuantiles()
Default constructor.
Definition JQuantiles.hh:42
double getX() const
Get position of maximum.
JQuantiles(const JFunction1D_t &f1, const double Q=1.0, const double eps=1.0e-6)
Constructor.
Definition JQuantiles.hh:58
JAbstractCollection< double > JAbscissa_t
Definition JQuantiles.hh:37
double getFWHM() const
Get Full Width at Half Maximum.
Range of values.
Definition JRange.hh:42
void setUpperLimit(argument_type y)
Definition JRange.hh:235
void setLowerLimit(argument_type x)
Definition JRange.hh:224
Template class for spline interpolation in 1D.
Definition JSpline.hh:734
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary classes and methods for multi-dimensional interpolations and histograms.
JContainer_t::ordinate_type makeCDF(const JContainer_t &input, JMappableCollection< JKey_t, JValue_t > &output, const typename JContainer_t::ordinate_type eps=JMATH::zero)
Conversion of data points to cumulative probability distribition (CDF).
JContainer_t::ordinate_type getIntegral(const JContainer_t &input)
Get integral of input data points.
JResultEvaluator< JResult_t >::result_type get_value(const JResult_t &value)
Helper method to recursively evaluate a to function value.
Definition JResult.hh:998
Abstract interface for abscissa values of a collection of elements.