Stan  1.1
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
double_exponential.hpp
Go to the documentation of this file.
1 #ifndef __STAN__PROB__DISTRIBUTIONS__DOUBLE_EXPONENTIAL_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__DOUBLE_EXPONENTIAL_HPP__
3 
4 #include <stan/agrad.hpp>
7 #include <stan/meta/traits.hpp>
9 #include <stan/prob/traits.hpp>
10 
11 namespace stan {
12 
13  namespace prob {
14  template<typename T>
15  inline int sign(const T& z) {
16  return (z == 0) ? 0 : z < 0 ? -1 : 1;
17  }
18 
19  // DoubleExponential(y|mu,sigma) [sigma > 0]
20  // FIXME: add documentation
21  template <bool propto,
22  typename T_y, typename T_loc, typename T_scale,
23  class Policy>
25  double_exponential_log(const T_y& y, const T_loc& mu, const T_scale& sigma,
26  const Policy&) {
27  static const char* function
28  = "stan::prob::double_exponential_log(%1%)";
29 
36  using std::log;
37  using std::fabs;
38 
39  // check if any vectors are zero length
40  if (!(stan::length(y)
41  && stan::length(mu)
42  && stan::length(sigma)))
43  return 0.0;
44 
45  // set up return value accumulator
46  double logp(0.0);
47  if(!check_finite(function, y, "Random variable", &logp, Policy()))
48  return logp;
49  if(!check_finite(function, mu, "Location parameter",
50  &logp, Policy()))
51  return logp;
52  if(!check_finite(function, sigma, "Scale parameter",
53  &logp, Policy()))
54  return logp;
55  if(!check_positive(function, sigma, "Scale parameter",
56  &logp, Policy()))
57  return logp;
58  if (!(check_consistent_sizes(function,
59  y,mu,sigma,
60  "Random variable","Location parameter","Shape parameter",
61  &logp, Policy())))
62  return logp;
63 
64  // check if no variables are involved and prop-to
66  return 0.0;
67 
68  // set up template expressions wrapping scalars into vector views
69  VectorView<const T_y> y_vec(y);
70  VectorView<const T_loc> mu_vec(mu);
71  VectorView<const T_scale> sigma_vec(sigma);
72  size_t N = max_size(y, mu, sigma);
73  agrad::OperandsAndPartials<T_y,T_loc,T_scale> operands_and_partials(y, mu, sigma);
74 
76  inv_sigma(length(sigma));
78  inv_sigma_squared(length(sigma));
80  log_sigma(length(sigma));
81  for (size_t i = 0; i < length(sigma); i++) {
82  const double sigma_dbl = value_of(sigma_vec[i]);
84  inv_sigma[i] = 1.0 / sigma_dbl;
86  log_sigma[i] = log(value_of(sigma_vec[i]));
88  inv_sigma_squared[i] = inv_sigma[i] * inv_sigma[i];
89  }
90 
91 
92  for (size_t n = 0; n < N; n++) {
93  const double y_dbl = value_of(y_vec[n]);
94  const double mu_dbl = value_of(mu_vec[n]);
95 
96  // reusable subexpressions values
97  const double y_m_mu = y_dbl - mu_dbl;
98  const double fabs_y_m_mu = fabs(y_m_mu);
99 
100  // log probability
102  logp += NEG_LOG_TWO;
104  logp -= log_sigma[n];
106  logp -= fabs_y_m_mu * inv_sigma[n];
107 
108  // gradients
109  double sign_y_m_mu_times_inv_sigma(0);
111  sign_y_m_mu_times_inv_sigma = sign(y_m_mu) * inv_sigma[n];
113  operands_and_partials.d_x1[n] -= sign_y_m_mu_times_inv_sigma;
114  }
116  operands_and_partials.d_x2[n] += sign_y_m_mu_times_inv_sigma;
117  }
119  operands_and_partials.d_x3[n] += -inv_sigma[n] + fabs_y_m_mu * inv_sigma_squared[n];
120  }
121  return operands_and_partials.to_var(logp);
122  }
123 
124 
125  template <bool propto,
126  typename T_y, typename T_loc, typename T_scale>
128  double_exponential_log(const T_y& y, const T_loc& mu,
129  const T_scale& sigma) {
130  return double_exponential_log<propto>(y,mu,sigma,
132  }
133 
134 
135  template <typename T_y, typename T_loc, typename T_scale,
136  class Policy>
138  double_exponential_log(const T_y& y, const T_loc& mu, const T_scale& sigma,
139  const Policy&) {
140  return double_exponential_log<false>(y,mu,sigma,Policy());
141  }
142 
143  template <typename T_y, typename T_loc, typename T_scale>
145  double_exponential_log(const T_y& y, const T_loc& mu,
146  const T_scale& sigma) {
147  return double_exponential_log<false>(y,mu,sigma,
149  }
150 
165  template <typename T_y, typename T_loc, typename T_scale,
166  class Policy>
168  double_exponential_cdf(const T_y& y, const T_loc& mu, const T_scale& sigma,
169  const Policy&) {
170  static const char* function
171  = "stan::prob::double_exponential_cdf(%1%)";
172 
175  using boost::math::tools::promote_args;
176 
177  typename promote_args<T_y,T_loc,T_scale>::type lp(0.0);
178  if(!check_finite(function, y, "Random variable", &lp, Policy()))
179  return lp;
180  if(!check_finite(function, mu, "Location parameter",
181  &lp, Policy()))
182  return lp;
183  if(!check_finite(function, sigma, "Scale parameter",
184  &lp, Policy()))
185  return lp;
186  if(!check_positive(function, sigma, "Scale parameter",
187  &lp, Policy()))
188  return lp;
189 
190  if (y < mu)
191  return exp((y-mu)/sigma)/2;
192  else
193  return 1 - exp((mu-y)/sigma)/2;
194  }
195 
196  template <typename T_y, typename T_loc, typename T_scale>
197  typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
198  double_exponential_cdf(const T_y& y, const T_loc& mu, const T_scale& sigma) {
200  }
201 
202  }
203 }
204 #endif

     [ Stan Home Page ] © 2011–2013, Stan Development Team.