Jpp 21.0.0-rc.3
the software that should make you happy
Loading...
Searching...
No Matches
JGauss.hh
Go to the documentation of this file.
1#ifndef __JMATH__JGAUSS__
2#define __JMATH__JGAUSS__
3
4#include <istream>
5#include <ostream>
6#include <iomanip>
7#include <cmath>
8#include <limits>
9
10#include "JLang/JEquals.hh"
11#include "JLang/JManip.hh"
12#include "JMath/JMath.hh"
13#include "JMath/JConstants.hh"
14
15/**
16 * \author mdejong
17 */
18
19namespace JMATH {}
20namespace JPP { using namespace JMATH; }
21
22namespace JMATH {
23
24 using JLANG::JEquals;
26
27 /**
28 * Gauss model.
29 */
30 struct JGauss_t :
31 public JMath<JGauss_t>,
32 public JEquals<JGauss_t>
33 {
34 /**
35 * Default constructor.
36 */
38 mean (0.0),
39 sigma (0.0),
40 signal (0.0),
41 background(0.0)
42 {}
43
44
45 /**
46 * Constructor.
47 *
48 * Note that an error will be thrown for a sigma smaller or equal to zero.
49 *
50 * \param mean mean
51 * \param sigma sigma
52 * \param signal signal
53 * \param background background
54 */
55 JGauss_t(const double mean,
56 const double sigma,
57 const double signal,
58 const double background) :
59 mean (mean),
60 sigma (sigma),
61 signal (signal),
63 {}
64
65
66 /**
67 * Equality.
68 *
69 * \param gauss gauss
70 * \param eps numerical precision
71 * \return true if gauss's identical; else false
72 */
73 bool equals(const JGauss_t& gauss,
74 const double eps = std::numeric_limits<double>::min()) const
75 {
76 return (fabs(mean - gauss.mean) <= eps &&
77 fabs(sigma - gauss.sigma) <= eps &&
78 fabs(signal - gauss.signal) <= eps &&
79 fabs(background - gauss.background) <= eps);
80 }
81
82
83 /**
84 * Add gauss.
85 *
86 * \param gauss gauss
87 * \return this gauss
88 */
90 {
91 mean += gauss.mean;
92 sigma += gauss.sigma;
93 signal += gauss.signal;
94 background += gauss.background;
95
96 return *this;
97 }
98
99
100 /**
101 * Subtract gauss.
102 *
103 * \param gauss gauss
104 * \return this gauss
105 */
107 {
108 mean -= gauss.mean;
109 sigma -= gauss.sigma;
110 signal -= gauss.signal;
111 background -= gauss.background;
112
113 return *this;
114 }
115
116
117 /**
118 * Scale gauss.
119 *
120 * \param factor multiplication factor
121 * \return this gauss
122 */
123 JGauss_t& mul(const double factor)
124 {
125 mean *= factor;
126 sigma *= factor;
127 signal *= factor;
128 background *= factor;
129
130 return *this;
131 }
132
133
134 /**
135 * Write Gauss to input stream.
136 *
137 * \param in input stream
138 * \param gauss gauss
139 * \return input stream
140 */
141 friend inline std::istream& operator>>(std::istream& in, JGauss_t& gauss)
142 {
143 return in >> gauss.mean >> gauss.sigma >> gauss.signal >> gauss.background;
144 }
145
146
147 /**
148 * Write Gauss to output stream.
149 *
150 * \param out output stream
151 * \param gauss gauss
152 * \return output stream
153 */
154 friend inline std::ostream& operator<<(std::ostream& out, const JGauss_t& gauss)
155 {
156 using namespace std;
157
158 return out << FIXED(7,3) << gauss.mean << ' '
159 << FIXED(7,3) << gauss.sigma << ' '
160 << FIXED(9,3) << gauss.signal << ' '
161 << FIXED(9,3) << gauss.background;
162 }
163
164 double mean;
165 double sigma;
166 double signal;
168 };
169
170
171 /**
172 * Gauss function object.
173 *
174 * Evaluates function, derivative and gradient values.
175 */
176 struct JGauss :
177 public JGauss_t
178 {
179 /**
180 * Type definition of fit parameter.
181 */
182 typedef double JGauss_t::*parameter_type;
183
184
185 /**
186 * Default constructor.
187 */
189 JGauss_t()
190 {}
191
192
193 /**
194 * Copy constructor.
195 *
196 * \param gauss gauss
197 */
200 {}
201
202
203 /**
204 * Constructor.
205 *
206 * \param mean mean
207 * \param sigma sigma
208 * \param signal signal
209 * \param background background
210 */
211 JGauss(const double mean,
212 const double sigma,
213 const double signal = 1.0,
214 const double background = 0.0) :
216 {}
217
218
219 /**
220 * Function value.
221 *
222 * Note that an error will be thrown if sigma <= 0.0.
223 *
224 * \param x abscissa value
225 * \return function value
226 */
227 double getValue(const double x) const
228 {
229 if (sigma <= 0.0) { THROW(JValueOutOfRange, "JGauss::getValue: Invalid sigma " << sigma); }
230
231 const double u = (x - mean) / sigma;
232
233 return signal * get(u) + background;
234 }
235
236
237 /**
238 * Derivative value.
239 *
240 * Note that an error will be thrown if sigma <= 0.0.
241 *
242 * \param x abscissa value
243 * \return derivative value
244 */
245 double getDerivative(const double x) const
246 {
247 if (sigma <= 0.0) { THROW(JValueOutOfRange, "JGauss::getDerivative: Invalid sigma " << sigma); }
248
249 const double u = (x - mean) / sigma;
250
251 return signal * get(u) * -u / sigma;
252 }
253
254
255 /**
256 * Integral value.
257 *
258 * Note that an error will be thrown if sigma <= 0.0.
259 * Note that zero will be returned if xmin is equal to xmax.
260 * Note that the integration limits can be set to infinity using std::numeric_limits<double>::inifinity().
261 *
262 * \param xmin lower limit
263 * \param xmax upper limit
264 */
265 double getIntegral(const double xmin, const double xmax) const
266 {
267 if (sigma <= 0.0) { THROW(JValueOutOfRange, "JGauss::getIntegral: Invalid sigma " << sigma); }
268
269 double zmin = xmin;
270 double zmax = xmax;
271
272 if (xmax < xmin) {
273
274 zmin = xmax;
275 zmax = xmin;
276 }
277
278 if (zmin < zmax) {
279
280 const double umin = (zmin - mean) / sigma / sqrt(2.0);
281 const double umax = (zmax - mean) / sigma / sqrt(2.0);
282
283 double I;
284
285 if (std::isinf(zmin) && std::isinf(zmax)) {
286
287 I = 1.0;
288
289 } else if (std::isinf(zmin)) {
290
291 I = 0.5 * (1 + erf(umax));
292
293 } else if (std::isinf(zmax)) {
294
295 I = 0.5 * erfc(umin);
296
297 } else {
298
299 I = 0.5 * (erfc(umin) - erfc(umax));
300 }
301
302 return signal * I + background;
303
304 } else {
305
306 return 0.0;
307 }
308 }
309
310
311 /**
312 * Function value.
313 *
314 * \param x abscissa value
315 * \return function value
316 */
317 double operator()(const double x) const
318 {
319 return getValue(x);
320 }
321
322
323 /**
324 * Get gradient.
325 *
326 * Note that an error will be thrown if sigma <= 0.0.
327 *
328 * \param x abscissa value
329 * \return gradient
330 */
331 const JGauss_t& getGradient(const double x) const
332 {
333 if (sigma <= 0.0) { THROW(JValueOutOfRange, "JGauss::getGradient: Invalid sigma " << sigma); }
334
335 const double w = 1.0 / sigma;
336 const double u = (x - mean) * w;
337 const double f0 = get(u);
338 const double fs = signal * f0;
339
340 gradient.mean = fs * (u) * w; // d(f)/d(mean)
341 gradient.sigma = fs * (u + 1.0) * (u - 1.0) * w; // d(f)/d(sigma)
342 gradient.signal = f0; // d(f)/d(signal)
343 gradient.background = 1.0; // d(f)/d(background)
344
345 return gradient;
346 }
347
348 private:
349 /**
350 * Get ordinate value.
351 *
352 * Note that an error will be thrown if sigma <= 0.0.
353 *
354 * \param u abscissa value
355 * \return ordinate value
356 */
357 inline double get(const double u) const
358 {
359 if (sigma <= 0.0) { THROW(JValueOutOfRange, "JGauss::get: Invalid sigma " << sigma); }
360
361 return exp(-0.5*u*u) / (sqrt(2.0*PI) * sigma);
362 }
363
365 };
366}
367
368#endif
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
I/O manipulators.
Mathematical constants.
Base class for data structures with artithmetic capabilities.
Exception for accessing a value in a collection that is outside of its range.
double gauss(const double x, const double sigma)
Gauss function (normalised to 1 at x = 0).
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary data structure for floating point format specification.
Definition JManip.hh:448
Template definition of auxiliary base class for comparison of data structures.
Definition JEquals.hh:84
Gauss model.
Definition JGauss.hh:33
JGauss_t & sub(const JGauss_t &gauss)
Subtract gauss.
Definition JGauss.hh:106
double background
Definition JGauss.hh:167
JGauss_t(const double mean, const double sigma, const double signal, const double background)
Constructor.
Definition JGauss.hh:55
double signal
Definition JGauss.hh:166
friend std::istream & operator>>(std::istream &in, JGauss_t &gauss)
Write Gauss to input stream.
Definition JGauss.hh:141
bool equals(const JGauss_t &gauss, const double eps=std::numeric_limits< double >::min()) const
Equality.
Definition JGauss.hh:73
JGauss_t()
Default constructor.
Definition JGauss.hh:37
friend std::ostream & operator<<(std::ostream &out, const JGauss_t &gauss)
Write Gauss to output stream.
Definition JGauss.hh:154
JGauss_t & mul(const double factor)
Scale gauss.
Definition JGauss.hh:123
JGauss_t & add(const JGauss_t &gauss)
Add gauss.
Definition JGauss.hh:89
Gauss function object.
Definition JMathlib.hh:2000
JGauss(const JGauss_t &gauss)
Copy constructor.
Definition JGauss.hh:198
double operator()(const double x) const
Function value.
Definition JGauss.hh:317
double JGauss_t::* parameter_type
Type definition of fit parameter.
Definition JGauss.hh:182
double sigma
sigma
Definition JMathlib.hh:2076
double getDerivative(const double x) const
Derivative value.
Definition JGauss.hh:245
JGauss()
Default constructor.
Definition JGauss.hh:188
double getValue(const double x) const
Function value.
Definition JGauss.hh:227
JGauss_t gradient
Definition JGauss.hh:364
JGauss(const double mean, const double sigma, const double signal=1.0, const double background=0.0)
Constructor.
Definition JGauss.hh:211
double getIntegral(const double xmin, const double xmax) const
Integral value.
Definition JGauss.hh:265
double get(const double u) const
Get ordinate value.
Definition JGauss.hh:357
const JGauss_t & getGradient(const double x) const
Get gradient.
Definition JGauss.hh:331
Auxiliary base class for aritmetic operations of derived class types.
Definition JMath.hh:347