TruncatedExponential.h
Go to the documentation of this file.
1 /*!
2  *
3  *
4  * \brief Implements a truncated exponential.
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_TRUNCATED_EXPONENTIAL_H
33 #define SHARK_RNG_TRUNCATED_EXPONENTIAL_H
34 
35 #include <shark/Rng/Rng.h>
36 #include <boost/random.hpp>
37 #include <boost/random/uniform_01.hpp>
38 
39 #include <cmath>
40 #include <istream>
41 
42 namespace shark{
43 
44  /**
45  * \brief boost random suitable distribution for an truncated exponential. See TruncatedExponential for more details.
46  */
47  template<class RealType = double>
49  public:
50  typedef RealType input_type;
51  typedef RealType result_type;
52 
53  explicit TruncatedExponential_distribution( RealType lambda, RealType max)
54  :m_max(max),m_lambda(lambda),m_integral(1-std::exp(-lambda*max))
55  {}
56  explicit TruncatedExponential_distribution( RealType lambda, RealType max, RealType integral)
57  :m_max(max),m_lambda(lambda),m_integral(integral)
58  {}
59 
60  RealType max() const
61  {
62  return m_max;
63  }
64  RealType lambda()const
65  {
66  return m_lambda;
67  }
68  RealType integral()const
69  {
70  return m_integral;
71  }
72  void reset() { }
73 
74  template<class Engine>
75  result_type operator()(Engine& eng)
76  {
77  if(m_lambda == 0){
78  return boost::uniform_01<RealType>()(eng);
79  }
80  double y = m_max * boost::uniform_01<RealType>()(eng);
81  return - std::log(1. - y*m_integral)/m_lambda;
82  }
83 
84  template<class CharT, class Traits,class T>
85  friend std::basic_ostream<CharT,Traits>&
86  operator<<(std::basic_ostream<CharT,Traits>& os, const TruncatedExponential_distribution<T>& d){
87  os << d.m_max;
88  os << d.m_lambda;
89  return os;
90  }
91 
92  template<class CharT, class Traits,class T>
93  friend std::basic_istream<CharT,Traits>&
94  operator>>(std::basic_istream<CharT,Traits>& is, TruncatedExponential_distribution<T>& d){
95  double max = 0;
96  double lambda = 0;
97  is >> max;
98  is >> lambda;
100  return is;
101  }
102  private:
103  RealType m_max;
104  RealType m_lambda;
105  RealType m_integral;
106  };
107 
108  /**
109  * \brief Implements a generator for the truncated exponential function
110  *
111  * Often, not the full range of an exponential distribution is needed. instead only an interval between [0,b]
112  * is required. In this case, the TruncatedExponential can be used. The propability function is
113  * \f$ p(x)=\frac{\lambda e^{-\lambda x}}{1-e^{-\lambda b}} \f$
114  * as default, the maximum value for x is 1
115  */
116  template<typename RngType = DefaultRngType>
117  class TruncatedExponential:public boost::variate_generator<RngType*,TruncatedExponential_distribution<> > {
118  private:
119  typedef boost::variate_generator<RngType*,TruncatedExponential_distribution<> > Base;
120  public:
121 
122  TruncatedExponential(RngType& rng, double lambda = 1, double max = 1.0 )
124  {}
125 
126  ///\brief special version, when the integral of the truncated exponential is allready known
127  TruncatedExponential(double integral, RngType& rng, double lambda = 1, double max = 1.0 )
128  :Base(&rng,TruncatedExponential_distribution<>(lambda,max, integral))
129  {}
130 
131  using Base::operator();
132 
133  double operator()(double lambda,double max = 1.0){
135  return dist(Base::engine());
136  }
137 
138  double lambda()const{
139  return Base::distribution().lambda();
140  }
141  double max()const{
142  return Base::distribution().max();
143  }
144  void setLambda(double newLambda){
145  Base::distribution() = TruncatedExponential_distribution<>(newLambda, max());
146  }
147  void setMax(double newMax){
148  Base::distribution() = TruncatedExponential_distribution<>(lambda(), newMax);
149  }
150 
151  double p(double x)
152  {
153  if(x >= 0 && x<=max()) {
154  return std::exp(-lambda()*x)/Base::distribution().integral();
155  }
156  return 0.;
157  }
158 
159  };
160 }
161 #endif
162 
163 
164 
165 
166 
167