Normal.h
Go to the documentation of this file.
1 /*!
2  *
3  *
4  * \brief Implements a univariate normal distribution.
5  *
6  *
7  *
8  * \author O. Krause
9  * \date 2010-01-01
10  *
11  *
12  * \par Copyright 1995-2017 Shark Development Team
13  *
14  * <BR><HR>
15  * This file is part of Shark.
16  * <http://shark-ml.org/>
17  *
18  * Shark is free software: you can redistribute it and/or modify
19  * it under the terms of the GNU Lesser General Public License as published
20  * by the Free Software Foundation, either version 3 of the License, or
21  * (at your option) any later version.
22  *
23  * Shark is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26  * GNU Lesser General Public License for more details.
27  *
28  * You should have received a copy of the GNU Lesser General Public License
29  * along with Shark. If not, see <http://www.gnu.org/licenses/>.
30  *
31  */
32 #ifndef SHARK_RNG_NORMAL_H
33 #define SHARK_RNG_NORMAL_H
34 
35 #include "shark/Core/Math.h"
37 #include "shark/Rng/Rng.h"
38 
39 #include <boost/math/special_functions.hpp>
40 #include <boost/random.hpp>
41 
42 #include <cmath>
43 
44 namespace shark {
45 
46 /// \brief Implements a univariate normal (Gaussian) distribution.
47 ///
48 /// For backwards compatibility with older shark versions
49 /// instead of the standard deviation sigma the
50 /// variance=sigma^2 is used as argument.
51 template<typename RngType = DefaultRngType>
52 class Normal
53 :
54  public AbstractDistribution,
55  public boost::variate_generator<RngType*, boost::normal_distribution<> >
56 {
57 private:
58  typedef boost::variate_generator<RngType*, boost::normal_distribution<> > Base;
59 
60 public:
61  /// constructor
62  /// \param rng: random number generator
63  /// \param mean: mean of distribution
64  /// \param variance: variance of distribution
65  Normal( RngType & rng, double mean = 0., double variance =1. )
66  :Base(&rng,boost::normal_distribution<>(mean,std::sqrt(variance)))
67  {}
68 
69  using Base::operator();
70 
71  double operator()(double mean,double variance)
72  {
73  boost::normal_distribution<> dist(mean,std::sqrt(variance));
74  return dist(Base::engine());
75  }
76 
77  double mean()const
78  {
79  return Base::distribution().mean();
80  }
81 
82  double variance()const
83  {
84  return Base::distribution().sigma() * Base::distribution().sigma();
85  }
86 
87  void mean(double newMean)
88  {
89  Base::distribution() = boost::normal_distribution<>(newMean, Base::distribution().sigma());
90  }
91 
92  void variance(double newVariance)
93  {
94  Base::distribution() = boost::normal_distribution<>(mean(), std::sqrt(newVariance));
95  }
96 
97  double p(double x) const
98  {
99  const double standardDeviation = Base::distribution().sigma();
100  return std::exp(-sqr((x - mean()) / standardDeviation) / 2.0) / (SQRT_2_PI * standardDeviation);
101  }
102 
103  double logP(double x) const
104  {
105  const double standardDeviation = Base::distribution().sigma();
106  return (-sqr((x - mean()) / standardDeviation) / 2.0) - safeLog(SQRT_2_PI * standardDeviation);
107  }
108 };
109 
110 ///\brief Draws a number from the normal distribution with given mean and variance by drawing random numbers from rng.
111 template<class RngType>
112 double gauss(RngType& rng, double mean, double variance){
113  Normal<RngType> dist(rng, mean, variance);
114  return dist();
115 }
116 
117 
118 } // namespace shark {
119 
120 #endif // SHARK_RNG_NORMAL_H