mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
expModGaussian.hpp
Go to the documentation of this file.
1 /** \file expModGaussian.hpp
2  * \brief The Exponentially Modified Gaussian distribution.
3  * \ingroup gen_math_files
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  */
7 
8 //***********************************************************************//
9 // Copyright 2023 Jared R. Males (jaredmales@gmail.com)
10 //
11 // This file is part of mxlib.
12 //
13 // mxlib is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // mxlib is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
25 //***********************************************************************//
26 
27 #ifndef expModGaussian_hpp
28 #define expModGaussian_hpp
29 
30 #include <boost/math/tools/minima.hpp>
31 #include <limits>
32 
33 namespace mx
34 {
35 namespace math
36 {
37 namespace func
38 {
39 
40 
41 
42 
43 /// The Exponentially Modified Gaussian at a point.
44 /** Calculates the value of the Exponentially Modified Gaussian distribution at a location specified by x.
45  *
46  *
47  * \tparam realT a real floating point type
48  *
49  * \returns the value of the Exponentially Modified Gaussian distribution at x.
50  *
51  * \ingroup gen_math_expModGaussian
52  */
53 template<typename realT>
54 realT expModGaussian( realT x, ///< [in] the location at which to calculate the distribution
55  realT mu, ///< [in] the mean parameter
56  realT sigma, ///< [in] the standard deviation
57  realT lambda ///< [in] the rate of decay
58  )
59 {
60  return (lambda/2)*exp((lambda/2)*(2*mu+lambda*sigma*sigma-2*x))*std::erfc((mu+lambda*sigma*sigma-x)/(root_two<realT>()*sigma));
61 }
62 
63 /// The Mean of the Exponentially Modified Gaussian.
64 /** Calculates the mean of the Exponentially Modified Gaussian distribution.
65  *
66  *
67  * \tparam realT a real floating point type
68  *
69  * \returns the mean of the Exponentially Modified Gaussian.
70  *
71  * \ingroup gen_math_expModGaussian
72  */
73 template<typename realT>
74 realT expModGaussianMean( realT mu, ///< [in] the mean parameter
75  realT lambda ///< [in] the rate of decay
76  )
77 {
78  return mu + 1.0/lambda;
79 }
80 
81 /// The Variance of the Exponentially Modified Gaussian.
82 /** Calculates the variance of the Exponentially Modified Gaussian distribution.
83  *
84  *
85  * \tparam realT a real floating point type
86  *
87  * \returns the variance of the Exponentially Modified Gaussian.
88  *
89  * \ingroup gen_math_expModGaussian
90  */
91 template<typename realT>
92 realT expModGaussianVariance( realT sigma, ///< [in] the standard deviation
93  realT lambda ///< [in] the rate of decay
94  )
95 {
96  return sigma*sigma + 1.0/(lambda*lambda);
97 }
98 
99 template<typename realT>
100 struct emgModeFunc
101 {
102  realT mu;
103  realT sigma;
104  realT lambda;
105 
106  realT operator()(const realT & x)
107  {
108  return -expModGaussian(x, mu, sigma, lambda);
109  }
110 };
111 
112 /// The Mode of the Exponentially Modified Gaussian.
113 /** Calculates the mode of the Exponentially Modified Gaussian distribution.
114  * This is done iteratively with Brent's method.
115  *
116  * \tparam realT a real floating point type
117  *
118  * \returns the mode of the Exponentially Modified Gaussian.
119  *
120  * \ingroup gen_math_expModGaussian
121  */
122 template<typename realT>
123 realT expModGaussianMode( realT mu, ///< [in] the mean parameter
124  realT sigma, ///< [in] the standard deviation
125  realT lambda ///< [in] the rate of decay
126  )
127 {
128  realT mn = expModGaussianMean(mu, lambda);
129  realT sd = sqrt(expModGaussianVariance(sigma, lambda));
130 
131  std::cerr << mn << " " << sd << "\n";
132 
133  emgModeFunc<realT> mf;
134  mf.mu = mu;
135  mf.sigma = sigma;
136  mf.lambda = lambda;
137 
138  uintmax_t maxit = 1000;
139  try
140  {
141  std::pair<realT,realT> brack;
142  brack = boost::math::tools::brent_find_minima<emgModeFunc<realT>, realT>(mf, mn-2*sd, mn+2*sd, std::numeric_limits<realT>::digits, maxit);
143  std::cerr << brack.first << " " << brack.second << " " << maxit << "\n";
144 
145  return brack.first;
146  }
147  catch(...)
148  {
149  std::cerr << "expModGaussianMode: No mode found\n";
150  return std::numeric_limits<realT>::quiet_NaN();
151  }
152 }
153 
154 } //namespace func
155 } //namespace math
156 } //namespace mx
157 
158 #endif //expModGaussian_hpp
constexpr units::realT sigma()
Stefan-Boltzmann Constant.
Definition: constants.hpp:82
realT expModGaussianVariance(realT sigma, realT lambda)
The Variance of the Exponentially Modified Gaussian.
realT expModGaussian(realT x, realT mu, realT sigma, realT lambda)
The Exponentially Modified Gaussian at a point.
realT expModGaussianMode(realT mu, realT sigma, realT lambda)
The Mode of the Exponentially Modified Gaussian.
realT expModGaussianMean(realT mu, realT lambda)
The Mean of the Exponentially Modified Gaussian.
The mxlib c++ namespace.
Definition: mxError.hpp:107