Stan  1.0
probability, sampling & optimization
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 #include <boost/math/special_functions/sign.hpp>
11 
12 namespace stan {
13 
14  namespace prob {
15 
16  // DoubleExponential(y|mu,sigma) [sigma > 0]
17  // FIXME: add documentation
18  template <bool propto,
19  typename T_y, typename T_loc, typename T_scale,
20  class Policy>
22  double_exponential_log(const T_y& y, const T_loc& mu, const T_scale& sigma,
23  const Policy&) {
24  static const char* function
25  = "stan::prob::double_exponential_log(%1%)";
26 
33  using std::log;
34  using std::fabs;
35  using boost::math::sign;
36 
37 
38  // check if any vectors are zero length
39  if (!(stan::length(y)
40  && stan::length(mu)
41  && stan::length(sigma)))
42  return 0.0;
43 
44  // set up return value accumulator
45  double logp(0.0);
46  if(!check_finite(function, y, "Random variable", &logp, Policy()))
47  return logp;
48  if(!check_finite(function, mu, "Location parameter",
49  &logp, Policy()))
50  return logp;
51  if(!check_finite(function, sigma, "Scale parameter",
52  &logp, Policy()))
53  return logp;
54  if(!check_positive(function, sigma, "Scale parameter",
55  &logp, Policy()))
56  return logp;
57  if (!(check_consistent_sizes(function,
58  y,mu,sigma,
59  "Random variable","Location parameter","Shape parameter",
60  &logp, Policy())))
61  return logp;
62 
63  // check if no variables are involved and prop-to
65  return 0.0;
66 
67  // set up template expressions wrapping scalars into vector views
68  VectorView<const T_y> y_vec(y);
69  VectorView<const T_loc> mu_vec(mu);
70  VectorView<const T_scale> sigma_vec(sigma);
71  size_t N = max_size(y, mu, sigma);
72  agrad::OperandsAndPartials<T_y,T_loc,T_scale> operands_and_partials(y, mu, sigma);
73 
75  inv_sigma(length(sigma));
77  inv_sigma_squared(length(sigma));
79  log_sigma(length(sigma));
80  for (size_t i = 0; i < length(sigma); i++) {
81  const double sigma_dbl = value_of(sigma_vec[i]);
83  inv_sigma[i] = 1.0 / sigma_dbl;
85  log_sigma[i] = log(value_of(sigma_vec[i]));
87  inv_sigma_squared[i] = inv_sigma[i] * inv_sigma[i];
88  }
89 
90 
91  for (size_t n = 0; n < N; n++) {
92  const double y_dbl = value_of(y_vec[n]);
93  const double mu_dbl = value_of(mu_vec[n]);
94 
95  // reusable subexpressions values
96  const double y_m_mu = y_dbl - mu_dbl;
97  const double fabs_y_m_mu = fabs(y_m_mu);
98 
99  // log probability
101  logp += NEG_LOG_TWO;
103  logp -= log_sigma[n];
105  logp -= fabs_y_m_mu * inv_sigma[n];
106 
107  // gradients
108  double sign_y_m_mu_times_inv_sigma(0);
110  sign_y_m_mu_times_inv_sigma = sign(y_m_mu) * inv_sigma[n];
112  operands_and_partials.d_x1[n] -= sign_y_m_mu_times_inv_sigma;
113  }
115  operands_and_partials.d_x2[n] += sign_y_m_mu_times_inv_sigma;
116  }
118  operands_and_partials.d_x3[n] += -inv_sigma[n] + fabs_y_m_mu * inv_sigma_squared[n];
119  }
120  return operands_and_partials.to_var(logp);
121  }
122 
123 
124  template <bool propto,
125  typename T_y, typename T_loc, typename T_scale>
127  double_exponential_log(const T_y& y, const T_loc& mu,
128  const T_scale& sigma) {
129  return double_exponential_log<propto>(y,mu,sigma,
131  }
132 
133 
134  template <typename T_y, typename T_loc, typename T_scale,
135  class Policy>
137  double_exponential_log(const T_y& y, const T_loc& mu, const T_scale& sigma,
138  const Policy&) {
139  return double_exponential_log<false>(y,mu,sigma,Policy());
140  }
141 
142  template <typename T_y, typename T_loc, typename T_scale>
144  double_exponential_log(const T_y& y, const T_loc& mu,
145  const T_scale& sigma) {
146  return double_exponential_log<false>(y,mu,sigma,
148  }
149 
164  template <typename T_y, typename T_loc, typename T_scale,
165  class Policy>
167  double_exponential_cdf(const T_y& y, const T_loc& mu, const T_scale& sigma,
168  const Policy&) {
169  static const char* function
170  = "stan::prob::double_exponential_cdf(%1%)";
171 
174  using boost::math::tools::promote_args;
175 
176  typename promote_args<T_y,T_loc,T_scale>::type lp(0.0);
177  if(!check_finite(function, y, "Random variable", &lp, Policy()))
178  return lp;
179  if(!check_finite(function, mu, "Location parameter",
180  &lp, Policy()))
181  return lp;
182  if(!check_finite(function, sigma, "Scale parameter",
183  &lp, Policy()))
184  return lp;
185  if(!check_positive(function, sigma, "Scale parameter",
186  &lp, Policy()))
187  return lp;
188 
189  if (y < mu)
190  return exp((y-mu)/sigma)/2;
191  else
192  return 1 - exp((mu-y)/sigma)/2;
193  }
194 
195  template <typename T_y, typename T_loc, typename T_scale>
196  typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
197  double_exponential_cdf(const T_y& y, const T_loc& mu, const T_scale& sigma) {
199  }
200 
201  }
202 }
203 #endif
var fabs(const var &a)
Return the absolute value of the variable (cmath).
Definition: agrad.hpp:2023
double value_of(const agrad::var &v)
Return the value of the specified variable.
var log(const var &a)
Return the natural log of the specified variable (cmath).
Definition: agrad.hpp:1730
var exp(const var &a)
Return the exponentiation of the specified variable (cmath).
Definition: agrad.hpp:1716
double value_of(T x)
Return the value of the specified scalar argument converted to a double value.
bool check_consistent_sizes(const char *function, const T1 &x1, const T2 &x2, const char *name1, const char *name2, T_result *result, const Policy &)
bool check_positive(const char *function, const T_y &y, const char *name, T_result *result, const Policy &)
bool check_finite(const char *function, const T_y &y, const char *name, T_result *result, const Policy &)
Checks if the variable y is finite.
boost::math::policies::policy default_policy
Default error-handling policy from Boost.
return_type< T_y, T_loc, T_scale >::type double_exponential_log(const T_y &y, const T_loc &mu, const T_scale &sigma, const Policy &)
return_type< T_y, T_loc, T_scale >::type double_exponential_cdf(const T_y &y, const T_loc &mu, const T_scale &sigma, const Policy &)
Calculates the double exponential cumulative density function.
Probability, optimization and sampling library.
Definition: agrad.cpp:6
size_t length(const T &x)
Definition: traits.hpp:111
size_t max_size(const T1 &x1, const T2 &x2)
Definition: traits.hpp:148
A variable implementation that stores operands and derivatives with respect to the variable.
VectorView< double *, is_vector< T1 >::value > d_x1
VectorView< double *, is_vector< T2 >::value > d_x2
T_return_type to_var(double logp)
VectorView< double *, is_vector< T3 >::value > d_x3
Metaprogram to determine if a type has a base scalar type that can be assigned to type double.
Definition: traits.hpp:39
Template metaprogram to calculate whether a summand needs to be included in a proportional (log) prob...
Definition: traits.hpp:33
boost::math::tools::promote_args< typename scalar_type< T1 >::type, typename scalar_type< T2 >::type, typename scalar_type< T3 >::type, typename scalar_type< T4 >::type, typename scalar_type< T5 >::type, typename scalar_type< T6 >::type >::type type
Definition: traits.hpp:368

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