Stan  1.3
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
normal.hpp
Go to the documentation of this file.
1 #ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__NORMAL_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__NORMAL_HPP__
3 
4 #include <boost/random/normal_distribution.hpp>
5 #include <boost/random/variate_generator.hpp>
6 
7 #include <stan/agrad.hpp>
8 #include <stan/math.hpp>
10 #include <stan/meta/traits.hpp>
11 #include <stan/prob/constants.hpp>
12 #include <stan/prob/traits.hpp>
13 
14 namespace stan {
15 
16  namespace prob {
17 
36  template <bool propto,
37  typename T_y, typename T_loc, typename T_scale,
38  class Policy>
39  typename return_type<T_y,T_loc,T_scale>::type
40  normal_log(const T_y& y, const T_loc& mu, const T_scale& sigma,
41  const Policy& /*policy*/) {
42  static const char* function = "stan::prob::normal_log(%1%)";
43 
44  using std::log;
52 
53  // check if any vectors are zero length
54  if (!(stan::length(y)
55  && stan::length(mu)
56  && stan::length(sigma)))
57  return 0.0;
58 
59  // set up return value accumulator
60  double logp(0.0);
61 
62  // validate args (here done over var, which should be OK)
63  if (!check_not_nan(function, y, "Random variable", &logp, Policy()))
64  return logp;
65  if (!check_finite(function, mu, "Location parameter",
66  &logp, Policy()))
67  return logp;
68  if (!check_positive(function, sigma, "Scale parameter",
69  &logp, Policy()))
70  return logp;
71  if (!(check_consistent_sizes(function,
72  y,mu,sigma,
73  "Random variable","Location parameter","Scale parameter",
74  &logp, Policy())))
75  return logp;
76 
77  // check if no variables are involved and prop-to
79  return 0.0;
80 
81  // set up template expressions wrapping scalars into vector views
82  agrad::OperandsAndPartials<T_y, T_loc, T_scale> operands_and_partials(y, mu, sigma);
83 
84  VectorView<const T_y> y_vec(y);
85  VectorView<const T_loc> mu_vec(mu);
86  VectorView<const T_scale> sigma_vec(sigma);
87  size_t N = max_size(y, mu, sigma);
88 
91  for (size_t i = 0; i < length(sigma); i++) {
92  inv_sigma[i] = 1.0 / value_of(sigma_vec[i]);
94  log_sigma[i] = log(value_of(sigma_vec[i]));
95  }
96 
97  for (size_t n = 0; n < N; n++) {
98  // pull out values of arguments
99  const double y_dbl = value_of(y_vec[n]);
100  const double mu_dbl = value_of(mu_vec[n]);
101 
102  // reusable subexpression values
103  const double y_minus_mu_over_sigma
104  = (y_dbl - mu_dbl) * inv_sigma[n];
105  const double y_minus_mu_over_sigma_squared
106  = y_minus_mu_over_sigma * y_minus_mu_over_sigma;
107 
108  static double NEGATIVE_HALF = - 0.5;
109 
110  // log probability
112  logp += NEG_LOG_SQRT_TWO_PI;
114  logp -= log_sigma[n];
116  logp += NEGATIVE_HALF * y_minus_mu_over_sigma_squared;
117 
118  // gradients
119  double scaled_diff = inv_sigma[n] * y_minus_mu_over_sigma;
121  operands_and_partials.d_x1[n] -= scaled_diff;
123  operands_and_partials.d_x2[n] += scaled_diff;
125  operands_and_partials.d_x3[n]
126  += -inv_sigma[n] + inv_sigma[n] * y_minus_mu_over_sigma_squared;
127  }
128  return operands_and_partials.to_var(logp);
129  }
130 
131 
132  template <bool propto,
133  typename T_y, typename T_loc, typename T_scale>
134  inline
136  normal_log(const T_y& y, const T_loc& mu, const T_scale& sigma) {
137  return normal_log<propto>(y,mu,sigma,stan::math::default_policy());
138  }
139 
140  template <typename T_y, typename T_loc, typename T_scale,
141  class Policy>
142  inline
144  normal_log(const T_y& y, const T_loc& mu, const T_scale& sigma,
145  const Policy&) {
146  return normal_log<false>(y,mu,sigma,Policy());
147  }
148 
149  template <typename T_y, typename T_loc, typename T_scale>
150  inline
152  normal_log(const T_y& y, const T_loc& mu, const T_scale& sigma) {
153  return normal_log<false>(y,mu,sigma,stan::math::default_policy());
154  }
155 
156 
175  template <typename T_y, typename T_loc, typename T_scale,
176  class Policy>
178  normal_cdf(const T_y& y, const T_loc& mu, const T_scale& sigma,
179  const Policy&) {
180  static const char* function = "stan::prob::normal_cdf(%1%)";
181 
186 
187 
189  // check if any vectors are zero length
190  if (!(stan::length(y)
191  && stan::length(mu)
192  && stan::length(sigma)))
193  return cdf;
194 
195  if (!check_not_nan(function, y, "Random variable", &cdf, Policy()))
196  return cdf;
197  if (!check_finite(function, mu, "Location parameter", &cdf, Policy()))
198  return cdf;
199  if (!check_not_nan(function, sigma, "Scale parameter",
200  &cdf, Policy()))
201  return cdf;
202  if (!check_positive(function, sigma, "Scale parameter",
203  &cdf, Policy()))
204  return cdf;
205  if (!(check_consistent_sizes(function,
206  y,mu,sigma,
207  "Random variable","Location parameter","Scale parameter",
208  &cdf, Policy())))
209  return cdf;
210 
211  VectorView<const T_y> y_vec(y);
212  VectorView<const T_loc> mu_vec(mu);
213  VectorView<const T_scale> sigma_vec(sigma);
214  size_t N = max_size(y, mu, sigma);
215 
216  for (size_t n = 0; n < N; n++) {
217  cdf *= 0.5 + 0.5 * erf((y_vec[n] - mu_vec[n]) / (sigma_vec[n] * SQRT_2));
218  }
219  return cdf;
220  }
221 
222  template <typename T_y, typename T_loc, typename T_scale>
223  inline
225  normal_cdf(const T_y& y, const T_loc& mu, const T_scale& sigma) {
226  return normal_cdf(y,mu,sigma,stan::math::default_policy());
227  }
228 
229 
230  template <class RNG>
231  inline double
232  normal_rng(const double mu,
233  const double sigma,
234  RNG& rng) {
235  using boost::variate_generator;
236  using boost::normal_distribution;
237  variate_generator<RNG&, normal_distribution<> >
238  norm_rng(rng, normal_distribution<>(mu, sigma));
239  return norm_rng();
240  }
241  }
242 }
243 #endif

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