All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
prob_dens_func.h
Go to the documentation of this file.
1 /*
2  -------------------------------------------------------------------
3 
4  Copyright (C) 2012-2014, Andrew W. Steiner
5 
6  This file is part of O2scl.
7 
8  O2scl is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12 
13  O2scl is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with O2scl. If not, see <http://www.gnu.org/licenses/>.
20 
21  -------------------------------------------------------------------
22 */
23 /** \file prob_dens_func.h
24  \brief File for probability density functions
25 */
26 #ifndef O2SCL_PROB_DENS_FUNC_H
27 #define O2SCL_PROB_DENS_FUNC_H
28 
29 #include <gsl/gsl_rng.h>
30 #include <gsl/gsl_randist.h>
31 #include <gsl/gsl_cdf.h>
32 
33 #include <boost/numeric/ublas/vector.hpp>
34 
35 #include <o2scl/hist.h>
36 #include <o2scl/rng_gsl.h>
37 #include <o2scl/search_vec.h>
38 
39 #ifndef DOXYGEN_NO_O2NS
40 namespace o2scl {
41 #endif
42 
43  /** \brief A one-dimensional probability density function
44 
45  This class is experimental.
46 
47  \future Give functions for mean, median, mode, variance, etc?
48  */
50  //: public funct {
51 
52  public:
53 
54  /// Sample from the specified density
55  virtual double sample() const=0;
56 
57  /// The normalized density
58  virtual double operator()(double x) const=0;
59 
60  /// The cumulative distribution function (from the lower tail)
61  virtual double cdf(double x) const=0;
62 
63  /// The inverse cumulative distribution function
64  virtual double invert_cdf(double cdf) const=0;
65 
66  /// Entropy of the distribution (\f$ - \int f \ln f \f$ )
67  virtual double entropy() const=0;
68 
69  };
70 
71  /** \brief A one-dimensional Gaussian probability density
72 
73  The distribution
74  \f[
75  P(x)=\frac{1}{\sigma \sqrt{2 \pi}}
76  e^{-\frac{\left(x-x_0\right)^2}{2\sigma^2}}
77  \f]
78 
79  This class is experimental.
80  */
82 
83  protected:
84 
85  /** \brief Central value
86  */
87  double cent_;
88 
89  /** \brief Width parameter
90 
91  A value of -1 indicates it is yet unspecified.
92  */
93  double sigma_;
94 
95  /// Base GSL random number generator
96  gsl_rng *r;
97 
98  public:
99 
100  /** \brief Create a standard normal distribution
101  */
103  cent_=0.0;
104  sigma_=1.0;
105  r=gsl_rng_alloc(gsl_rng_mt19937);
106  }
107 
108  /** \brief Create a Gaussian distribution with width \c sigma
109 
110  The value of \c sigma must be larger than zero.
111  */
112  prob_dens_gaussian(double cent, double sigma) {
113  if (sigma<0.0) {
114  O2SCL_ERR2("Tried to create a Gaussian dist. with sigma",
115  "<0 in prob_dens_gaussian::prob_dens_gaussian().",
116  exc_einval);
117  }
118  cent_=cent;
119  sigma_=sigma;
120  r=gsl_rng_alloc(gsl_rng_mt19937);
121  }
122 
123  virtual ~prob_dens_gaussian() {
124  gsl_rng_free(r);
125  }
126 
127  /// Copy constructor
129  cent_=pdg.cent_;
130  sigma_=pdg.sigma_;
131  r=gsl_rng_alloc(gsl_rng_mt19937);
132  }
133 
134  /// Copy constructor with operator=
136  // Check for self-assignment
137  if (this==&pdg) return *this;
138  cent_=pdg.cent_;
139  sigma_=pdg.sigma_;
140  return *this;
141  }
142 
143  /// Set the seed
144  void set_seed(unsigned long int s) {
145  gsl_rng_set(r,s);
146  }
147 
148  /// Set the center
149  void set_center(double cent) {
150  cent_=cent;
151  }
152 
153  /// Set the Gaussian width
154  void set_sigma(double sigma) {
155  if (sigma<0.0) {
156  O2SCL_ERR2("Tried to set sigma negative",
157  "in prob_dens_gaussian::prob_dens_gaussian().",
158  exc_einval);
159  }
160  sigma_=sigma;
161  }
162 
163  /// Get the center
164  double get_center() {
165  return cent_;
166  }
167 
168  /// Get the Gaussian width
169  double get_sigma() {
170  if (sigma_<0.0) {
171  O2SCL_ERR2("Width not set in prob_dens_gaussian::",
172  "get_sigma().",exc_einval);
173  }
174  return sigma_;
175  }
176 
177  /// Sample from the specified density
178  virtual double sample() const {
179  if (sigma_<0.0) {
180  O2SCL_ERR2("Width not set in prob_dens_gaussian::",
181  "sample().",exc_einval);
182  }
183  return cent_+gsl_ran_gaussian(r,sigma_);
184  }
185 
186  /// The normalized density
187  virtual double operator()(double x) const {
188  if (sigma_<0.0) {
189  O2SCL_ERR2("Width not set in prob_dens_gaussian::",
190  "operator().",exc_einval);
191  }
192  return gsl_ran_gaussian_pdf(x-cent_,sigma_);
193  }
194 
195  /// The cumulative distribution function (from the lower tail)
196  virtual double cdf(double x) const {
197  if (sigma_<0.0) {
198  O2SCL_ERR2("Width not set in prob_dens_gaussian::",
199  "cdf().",exc_einval);
200  }
201  return gsl_cdf_gaussian_P(x-cent_,sigma_);
202  }
203 
204  /// The inverse cumulative distribution function
205  virtual double invert_cdf(double in_cdf) const {
206  if (sigma_<0.0) {
207  O2SCL_ERR2("Width not set in prob_dens_gaussian::",
208  "invert_cdf().",exc_einval);
209  }
210  if (in_cdf<0.0 || in_cdf>1.0) {
211  O2SCL_ERR2("Requested cdf inverse outside of [0,1] in ",
212  "prob_dens_gaussian::invert_cdf().",exc_einval);
213  }
214  return gsl_cdf_gaussian_Pinv(in_cdf,sigma_)+cent_;
215  }
216 
217  /// The inverse cumulative distribution function
218  virtual double entropy() const {
219  if (sigma_<0.0) {
220  O2SCL_ERR2("Width not set in prob_dens_gaussian::",
221  "invert_cdf().",exc_einval);
222  }
223  return log(2.0*o2scl_const::pi*exp(1.0)*sigma_*sigma_);
224  }
225 
226  };
227 
228  /** \brief A one-dimensional probability density over
229  a finite range
230 
231  This class is experimental.
232  */
234 
235  public:
236 
237  /// Lower limit of the range
238  virtual double lower_limit() const=0;
239 
240  /// Uower limit of the range
241  virtual double upper_limit() const=0;
242 
243  };
244 
245  /** \brief A uniform one-dimensional probability density
246  over a finite range
247 
248  A flat distribution given by \f$ P(x)=1/(b-a) \f$ for \f$ a<x<b
249  \f$, where \f$ a \f$ is the lower limit and \f$ b \f$ is the
250  upper limit.
251 
252  This class is experimental.
253  */
255 
256  protected:
257 
258  /// Lower limit
259  double ll;
260 
261  /// Upper limit
262  double ul;
263 
264  /// The GSL random number generator
265  gsl_rng *r;
266 
267  public:
268 
269  /** \brief Create a blank uniform distribution
270  */
272  ll=1.0;
273  ul=0.0;
274  r=gsl_rng_alloc(gsl_rng_mt19937);
275  }
276 
277  /** \brief Create a uniform distribution from \f$ a<x<b \f$
278  */
279  prob_dens_uniform(double a, double b) {
280  // Ensure a<b
281  if (a>b) {
282  double tmp=a;
283  a=b;
284  b=tmp;
285  }
286  ll=a;
287  ul=b;
288  r=gsl_rng_alloc(gsl_rng_mt19937);
289  }
290 
291  virtual ~prob_dens_uniform() {
292  gsl_rng_free(r);
293  }
294 
295  /// Copy constructor
297  ll=pdg.ll;
298  ul=pdg.ul;
299  r=gsl_rng_alloc(gsl_rng_mt19937);
300  }
301 
302  /// Copy constructor with operator=
304  // Check for self-assignment
305  if (this==&pdg) return *this;
306  ll=pdg.ll;
307  ul=pdg.ul;
308  return *this;
309  }
310 
311  /// Set the seed
312  void set_seed(unsigned long int s) {
313  gsl_rng_set(r,s);
314  }
315 
316  /** \brief Set the limits of the uniform distribution
317  */
318  void set_limits(double a, double b) {
319  // Ensure a<b
320  if (a>b) {
321  double tmp=a;
322  a=b;
323  b=tmp;
324  }
325  ll=a;
326  ul=b;
327  return;
328  }
329 
330  /// Lower limit of the range
331  virtual double lower_limit() const {
332  if (ll>ul) {
333  O2SCL_ERR2("Limits not set in prob_dens_uniform::",
334  "lower_limit().",exc_einval);
335  }
336  return ll;
337  }
338 
339  /// Uower limit of the range
340  virtual double upper_limit() const {
341  if (ll>ul) {
342  O2SCL_ERR2("Limits not set in prob_dens_uniform::",
343  "upper_limit().",exc_einval);
344  }
345  return ul;
346  }
347 
348  /// Sample from the specified density
349  virtual double sample() const {
350  if (ll>ul) {
351  O2SCL_ERR2("Limits not set in prob_dens_uniform::",
352  "sample().",exc_einval);
353  }
354  return gsl_ran_flat(r,ll,ul);
355  }
356 
357  /// The normalized density
358  virtual double operator()(double x) const {
359  if (ll>ul) {
360  O2SCL_ERR2("Limits not set in prob_dens_uniform::",
361  "operator().",exc_einval);
362  }
363  if (x<ll || x>ul) return 0.0;
364  return gsl_ran_flat_pdf(x,ll,ul);
365  }
366 
367  /// The cumulative distribution function (from the lower tail)
368  virtual double cdf(double x) const {
369  if (ll>ul) {
370  O2SCL_ERR2("Limits not set in prob_dens_uniform::",
371  "cdf().",exc_einval);
372  }
373  if (x<ll) return 0.0;
374  if (x>ul) return 1.0;
375  return gsl_cdf_flat_P(x,ll,ul);
376  }
377 
378  /// The inverse cumulative distribution function
379  virtual double invert_cdf(double in_cdf) const {
380  if (ll>ul) {
381  O2SCL_ERR2("Limits not set in prob_dens_uniform::",
382  "invert_cdf().",exc_einval);
383  }
384  if (in_cdf<0.0 || in_cdf>1.0) {
385  O2SCL_ERR2("Requested cdf inverse outside of [0,1] in ",
386  "prob_dens_uniform::invert_cdf().",exc_einval);
387  }
388  return gsl_cdf_flat_Pinv(in_cdf,ll,ul);
389  }
390 
391  /// The inverse cumulative distribution function
392  virtual double entropy() const {
393  if (ll>ul) {
394  O2SCL_ERR2("Limits not set in prob_dens_uniform::",
395  "entropy().",exc_einval);
396  }
397  return log(ul-ll);
398  }
399 
400  };
401 
402  /** \brief A one-dimensional probability density over the
403  positive real numbers
404 
405  This class is experimental.
406  */
408 
409  };
410 
411  /** \brief Lognormal density function
412 
413  The distribution
414  \f[
415  P(x)=\frac{1}{x \sigma \sqrt{2 \pi}}
416  \exp \left[-\frac{\left(\ln x-\mu\right)^2}{2\sigma^2}\right]
417  \f]
418 
419  This class is experimental.
420  */
422 
423  protected:
424 
425  /** \brief Width parameter
426 
427  A value of -1 indicates it is yet unspecified.
428  */
429  double sigma_;
430 
431  /** \brief Central value
432 
433  A value of -1 indicates it is yet unspecified.
434  */
435  double mu_;
436 
437  /// The GSL random number generator
438  gsl_rng *r;
439 
440  public:
441 
442  /** \brief Create a blank lognormal distribution
443  */
445  sigma_=-1.0;
446  mu_=0.0;
447  r=gsl_rng_alloc(gsl_rng_mt19937);
448  }
449 
450  /** \brief Create lognormal distribution with mean parameter \c mu
451  and width parameter \c sigma
452 
453  The value of \c sigma must be larger than zero.
454  */
455  prob_dens_lognormal(double mu, double sigma) {
456  if (sigma<0.0) {
457  O2SCL_ERR2("Tried to create log normal dist. with mu or sigma",
458  "<0 in prob_dens_lognormal::prob_dens_lognormal().",
459  exc_einval);
460  }
461  mu_=mu;
462  sigma_=sigma;
463  r=gsl_rng_alloc(gsl_rng_mt19937);
464  }
465 
466  virtual ~prob_dens_lognormal() {
467  gsl_rng_free(r);
468  }
469 
470  /// Copy constructor
472  mu_=pdg.mu_;
473  sigma_=pdg.sigma_;
474  r=gsl_rng_alloc(gsl_rng_mt19937);
475  }
476 
477  /// Copy constructor with operator=
479  // Check for self-assignment
480  if (this==&pdg) return *this;
481  mu_=pdg.mu_;
482  sigma_=pdg.sigma_;
483  return *this;
484  }
485 
486  /** \brief Set the maximum and width of the lognormal distribution
487  */
488  void set_mu_sigma(double mu, double sigma) {
489  if (sigma<0.0) {
490  O2SCL_ERR2("Tried to set mu or sigma negative",
491  "in prob_dens_lognormal::prob_dens_lognormal().",
492  exc_einval);
493  }
494  mu_=mu;
495  sigma_=sigma;
496  }
497 
498  /// Set the seed
499  void set_seed(unsigned long int s) {
500  gsl_rng_set(r,s);
501  }
502 
503  /// Sample from the specified density
504  virtual double sample() const {
505  return gsl_ran_lognormal(r,mu_,sigma_);
506  }
507 
508  /// The normalized density
509  virtual double operator()(double x) const {
510  if (x<0.0) {
511  return 0.0;
512  }
513  return gsl_ran_lognormal_pdf(x,mu_,sigma_);
514  }
515 
516  /// The cumulative distribution function (from the lower tail)
517  virtual double cdf(double x) const {
518  if (x<0.0) {
519  return 0.0;
520  }
521  return gsl_cdf_lognormal_P(x,mu_,sigma_);
522  }
523 
524  /// The inverse cumulative distribution function
525  virtual double invert_cdf(double in_cdf) const {
526  if (in_cdf<0.0 || in_cdf>1.0) {
527  O2SCL_ERR2("Requested cdf inverse outside of [0,1] in ",
528  "prob_dens_lognormal::invert_cdf().",exc_einval);
529  }
530  return gsl_cdf_lognormal_Pinv(in_cdf,mu_,sigma_);
531  }
532 
533  /// The inverse cumulative distribution function
534  virtual double entropy() const {
535  if (sigma_<0.0) {
536  O2SCL_ERR2("Parameters not set in prob_dens_lognormal::",
537  "entropy().",exc_einval);
538  }
539  return 0.5+0.5*log(2.0*o2scl_const::pi*sigma_*sigma_)+mu_;
540  }
541 
542  };
543 
544  /** \brief Probability density function based on a histogram
545 
546  This class is experimental.
547  */
549 
550  public:
551 
553 
554  protected:
555 
556  /// Search through the partial sums
558 
559  /// Number of original histogram bins
560  size_t n;
561 
562  /** \brief Normalized partial sum of histogram bins
563 
564  This vector has size \ref n plus one.
565  */
567 
568  /** \brief Vector specifying original histogram bins
569 
570  This vector has size \ref n plus one.
571  */
573 
574  /// Random number generator
575  mutable rng_gsl rng;
576 
577  public:
578 
579  prob_dens_hist();
580 
581  ~prob_dens_hist();
582 
583  /// Initialize with histogram \c h
584  void init(hist &h);
585 
586  /// Generate a sample
587  virtual double sample() const;
588 
589  /// Lower limit of the range
590  virtual double lower_limit() const;
591 
592  /// Uower limit of the range
593  virtual double upper_limit() const;
594 
595  /// The normalized density
596  virtual double operator()(double x) const;
597 
598  /// Cumulative distribution function (from the lower tail)
599  virtual double cdf(double x) const;
600 
601  /// Inverse cumulative distribution function (from the lower tail)
602  virtual double invert_cdf(double x) const;
603 
604  /// Inverse cumulative distribution function (from the lower tail)
605  virtual double entropy() const {
606  return 0.0;
607  }
608 
609  };
610 
611 #ifndef DOXYGEN_NO_O2NS
612 }
613 #endif
614 
615 #endif
double sigma_
Width parameter.
virtual double lower_limit() const
Lower limit of the range.
virtual double entropy() const
The inverse cumulative distribution function.
virtual double entropy() const
The inverse cumulative distribution function.
double mu_
Central value.
void set_limits(double a, double b)
Set the limits of the uniform distribution.
const double pi
Definition: constants.h:62
virtual double sample() const
Sample from the specified density.
prob_dens_gaussian & operator=(const prob_dens_gaussian &pdg)
Copy constructor with operator=.
virtual double lower_limit() const
Lower limit of the range.
virtual double invert_cdf(double in_cdf) const
The inverse cumulative distribution function.
void set_sigma(double sigma)
Set the Gaussian width.
invalid argument supplied by user
Definition: err_hnd.h:59
ubvector sum
Normalized partial sum of histogram bins.
size_t n
Number of original histogram bins.
prob_dens_lognormal & operator=(const prob_dens_lognormal &pdg)
Copy constructor with operator=.
prob_dens_lognormal()
Create a blank lognormal distribution.
A one-dimensional Gaussian probability density.
prob_dens_uniform(double a, double b)
Create a uniform distribution from .
virtual double operator()(double x) const
The normalized density.
prob_dens_gaussian()
Create a standard normal distribution.
void set_mu_sigma(double mu, double sigma)
Set the maximum and width of the lognormal distribution.
A one-dimensional histogram class.
Definition: hist.h:113
prob_dens_gaussian(const prob_dens_gaussian &pdg)
Copy constructor.
prob_dens_lognormal(const prob_dens_lognormal &pdg)
Copy constructor.
virtual double sample() const
Sample from the specified density.
double get_sigma()
Get the Gaussian width.
A uniform one-dimensional probability density over a finite range.
virtual double sample() const
Sample from the specified density.
prob_dens_gaussian(double cent, double sigma)
Create a Gaussian distribution with width sigma.
void set_seed(unsigned long int s)
Set the seed.
virtual double entropy() const
The inverse cumulative distribution function.
virtual double cdf(double x) const
The cumulative distribution function (from the lower tail)
virtual double operator()(double x) const
The normalized density.
virtual double cdf(double x) const
The cumulative distribution function (from the lower tail)
virtual double entropy() const =0
Entropy of the distribution ( )
virtual double cdf(double x) const
The cumulative distribution function (from the lower tail)
A one-dimensional probability density function.
A one-dimensional probability density over a finite range.
virtual double upper_limit() const =0
Uower limit of the range.
double get_center()
Get the center.
#define O2SCL_ERR2(d, d2, n)
Set an error, two-string version.
Definition: err_hnd.h:281
virtual double operator()(double x) const =0
The normalized density.
virtual double operator()(double x) const
The normalized density.
virtual double invert_cdf(double x) const
Inverse cumulative distribution function (from the lower tail)
ubvector range
Vector specifying original histogram bins.
double cent_
Central value.
search_vec< ubvector > sv
Search through the partial sums.
virtual double invert_cdf(double in_cdf) const
The inverse cumulative distribution function.
double sigma_
Width parameter.
virtual double upper_limit() const
Uower limit of the range.
A one-dimensional probability density over the positive real numbers.
double ul
Upper limit.
virtual double operator()(double x) const
The normalized density.
virtual double cdf(double x) const =0
The cumulative distribution function (from the lower tail)
Random number generator (GSL)
Definition: rng_gsl.h:51
prob_dens_uniform()
Create a blank uniform distribution.
Searching class for monotonic data with caching.
Definition: search_vec.h:78
prob_dens_lognormal(double mu, double sigma)
Create lognormal distribution with mean parameter mu and width parameter sigma.
virtual double sample() const
Generate a sample.
virtual double upper_limit() const
Uower limit of the range.
virtual double invert_cdf(double in_cdf) const
The inverse cumulative distribution function.
rng_gsl rng
Random number generator.
gsl_rng * r
Base GSL random number generator.
Probability density function based on a histogram.
void init(hist &h)
Initialize with histogram h.
virtual double lower_limit() const =0
Lower limit of the range.
prob_dens_uniform(const prob_dens_uniform &pdg)
Copy constructor.
void set_seed(unsigned long int s)
Set the seed.
virtual double sample() const =0
Sample from the specified density.
void set_seed(unsigned long int s)
Set the seed.
virtual double cdf(double x) const
Cumulative distribution function (from the lower tail)
virtual double entropy() const
Inverse cumulative distribution function (from the lower tail)
virtual double invert_cdf(double cdf) const =0
The inverse cumulative distribution function.
double ll
Lower limit.
Lognormal density function.
gsl_rng * r
The GSL random number generator.
void set_center(double cent)
Set the center.
prob_dens_uniform & operator=(const prob_dens_uniform &pdg)
Copy constructor with operator=.
gsl_rng * r
The GSL random number generator.

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).
Hosted at Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads..