1 #ifndef STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CAUCHY_HPP
2 #define STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CAUCHY_HPP
4 #include <boost/random/cauchy_distribution.hpp>
5 #include <boost/random/variate_generator.hpp>
39 template <
bool propto,
40 typename T_y,
typename T_loc,
typename T_scale>
41 typename return_type<T_y,T_loc,T_scale>::type
42 cauchy_log(
const T_y& y,
const T_loc& mu,
const T_scale& sigma) {
43 static const char*
function =
"stan::prob::cauchy_log(%1%)";
67 "Random variable",
"Location parameter",
88 for (
size_t i = 0; i <
length(sigma); i++) {
89 const double sigma_dbl =
value_of(sigma_vec[i]);
90 inv_sigma[i] = 1.0 / sigma_dbl;
91 sigma_squared[i] = sigma_dbl * sigma_dbl;
93 log_sigma[i] =
log(sigma_dbl);
99 for (
size_t n = 0; n < N; n++) {
101 const double y_dbl =
value_of(y_vec[n]);
102 const double mu_dbl =
value_of(mu_vec[n]);
105 const double y_minus_mu
107 const double y_minus_mu_squared
108 = y_minus_mu * y_minus_mu;
109 const double y_minus_mu_over_sigma
110 = y_minus_mu * inv_sigma[n];
111 const double y_minus_mu_over_sigma_squared
112 = y_minus_mu_over_sigma * y_minus_mu_over_sigma;
118 logp -= log_sigma[n];
120 logp -=
log1p(y_minus_mu_over_sigma_squared);
124 operands_and_partials.
d_x1[n] -= 2 * y_minus_mu / (sigma_squared[n] + y_minus_mu_squared);
126 operands_and_partials.
d_x2[n] += 2 * y_minus_mu / (sigma_squared[n] + y_minus_mu_squared);
128 operands_and_partials.
d_x3[n] += (y_minus_mu_squared - sigma_squared[n]) * inv_sigma[n] / (sigma_squared[n] + y_minus_mu_squared);
130 return operands_and_partials.
to_var(logp);
133 template <
typename T_y,
typename T_loc,
typename T_scale>
136 cauchy_log(
const T_y& y,
const T_loc& mu,
const T_scale& sigma) {
137 return cauchy_log<false>(y,mu,sigma);
156 template <
typename T_y,
typename T_loc,
typename T_scale>
158 cauchy_cdf(
const T_y& y,
const T_loc& mu,
const T_scale& sigma) {
165 static const char*
function =
"stan::prob::cauchy_cdf(%1%)";
171 using boost::math::tools::promote_args;
180 "Random variable",
"Location parameter",
191 operands_and_partials(y, mu, sigma);
196 if (
value_of(y_vec[i]) == -std::numeric_limits<double>::infinity())
197 return operands_and_partials.
to_var(0.0);
205 for (
size_t n = 0; n < N; n++) {
209 if (
value_of(y_vec[n]) == std::numeric_limits<double>::infinity()) {
214 const double y_dbl =
value_of(y_vec[n]);
215 const double mu_dbl =
value_of(mu_vec[n]);
216 const double sigma_inv_dbl = 1.0 /
value_of(sigma_vec[n]);
218 const double z = (y_dbl - mu_dbl) * sigma_inv_dbl;
221 const double Pn =
atan(z) /
pi() + 0.5;
226 operands_and_partials.
d_x1[n]
227 += sigma_inv_dbl / (
pi() * (1.0 + z * z) * Pn);
229 operands_and_partials.
d_x2[n]
230 += - sigma_inv_dbl / (
pi() * (1.0 + z * z) * Pn);
232 operands_and_partials.
d_x3[n]
233 += - z * sigma_inv_dbl / (
pi() * (1.0 + z * z) * Pn);
239 operands_and_partials.
d_x1[n] *= P;
243 operands_and_partials.
d_x2[n] *= P;
247 operands_and_partials.
d_x3[n] *= P;
250 return operands_and_partials.
to_var(P);
253 template <
typename T_y,
typename T_loc,
typename T_scale>
262 static const char*
function =
"stan::prob::cauchy_cdf(%1%)";
268 using boost::math::tools::promote_args;
274 check_finite(
function, mu,
"Location parameter", &cdf_log);
277 "Random variable",
"Location parameter",
278 "Scale Parameter", &cdf_log);
287 operands_and_partials(y, mu, sigma);
294 for (
size_t n = 0; n < N; n++) {
297 const double y_dbl =
value_of(y_vec[n]);
298 const double mu_dbl =
value_of(mu_vec[n]);
299 const double sigma_inv_dbl = 1.0 /
value_of(sigma_vec[n]);
300 const double sigma_dbl =
value_of(sigma_vec[n]);
302 const double z = (y_dbl - mu_dbl) * sigma_inv_dbl;
305 const double Pn =
atan(z) /
pi() + 0.5;
308 const double rep_deriv = 1.0 / (
pi() * Pn
309 * (z * z * sigma_dbl + sigma_dbl));
311 operands_and_partials.
d_x1[n] += rep_deriv;
313 operands_and_partials.
d_x2[n] -= rep_deriv;
315 operands_and_partials.
d_x3[n] -= rep_deriv * z;
317 return operands_and_partials.
to_var(cdf_log);
320 template <
typename T_y,
typename T_loc,
typename T_scale>
329 static const char*
function =
"stan::prob::cauchy_cdf(%1%)";
335 using boost::math::tools::promote_args;
338 double ccdf_log(0.0);
341 check_finite(
function, mu,
"Location parameter", &ccdf_log);
344 "Random variable",
"Location parameter",
345 "Scale Parameter", &ccdf_log);
354 operands_and_partials(y, mu, sigma);
361 for (
size_t n = 0; n < N; n++) {
364 const double y_dbl =
value_of(y_vec[n]);
365 const double mu_dbl =
value_of(mu_vec[n]);
366 const double sigma_inv_dbl = 1.0 /
value_of(sigma_vec[n]);
367 const double sigma_dbl =
value_of(sigma_vec[n]);
368 const double z = (y_dbl - mu_dbl) * sigma_inv_dbl;
371 const double Pn = 0.5 -
atan(z) /
pi();
374 const double rep_deriv = 1.0 / (Pn *
pi()
375 * (z * z * sigma_dbl + sigma_dbl));
377 operands_and_partials.
d_x1[n] -= rep_deriv;
379 operands_and_partials.
d_x2[n] += rep_deriv;
381 operands_and_partials.
d_x3[n] += rep_deriv * z;
383 return operands_and_partials.
to_var(ccdf_log);
391 using boost::variate_generator;
392 using boost::random::cauchy_distribution;
394 static const char*
function =
"stan::prob::cauchy_rng(%1%)";
399 check_finite(
function, mu,
"Location parameter", (
double*)0);
402 variate_generator<RNG&, cauchy_distribution<> >
403 cauchy_rng(rng, cauchy_distribution<>(mu, sigma));
T square(const T x)
Return the square of the specified argument.
double cauchy_rng(const double mu, const double sigma, RNG &rng)
boost::math::tools::promote_args< T >::type log1p(const T x)
Return the natural logarithm of one plus the specified value.
T_return_type to_var(double logp)
bool check_positive_finite(const char *function, const T_y &y, const char *name, T_result *result)
DoubleVectorView allocates double values to be used as intermediate values.
bool check_finite(const char *function, const T_y &y, const char *name, T_result *result)
Checks if the variable y is finite.
return_type< T_y, T_loc, T_scale >::type cauchy_cdf_log(const T_y &y, const T_loc &mu, const T_scale &sigma)
T value_of(const fvar< T > &v)
Return the value of the specified variable.
A variable implementation that stores operands and derivatives with respect to the variable...
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
fvar< T > atan(const fvar< T > &x)
Metaprogram to determine if a type has a base scalar type that can be assigned to type double...
double value_of(const T x)
Return the value of the specified scalar argument converted to a double value.
Template metaprogram to calculate whether a summand needs to be included in a proportional (log) prob...
VectorView< double *, is_vector< T2 >::value, is_constant_struct< T2 >::value > d_x2
return_type< T_y, T_loc, T_scale >::type cauchy_ccdf_log(const T_y &y, const T_loc &mu, const T_scale &sigma)
bool check_consistent_sizes(const char *function, const T1 &x1, const T2 &x2, const char *name1, const char *name2, T_result *result)
size_t max_size(const T1 &x1, const T2 &x2)
return_type< T_y, T_loc, T_scale >::type cauchy_log(const T_y &y, const T_loc &mu, const T_scale &sigma)
The log of the Cauchy density for the specified scalar(s) given the specified location parameter(s) a...
bool check_not_nan(const char *function, const T_y &y, const char *name, T_result *result)
Checks if the variable y is nan.
VectorView< double *, is_vector< T1 >::value, is_constant_struct< T1 >::value > d_x1
VectorView< double *, is_vector< T3 >::value, is_constant_struct< T3 >::value > d_x3
double pi()
Return the value of pi.
fvar< T > log(const fvar< T > &x)
VectorView is a template metaprogram that takes its argument and allows it to be used like a vector...
fvar< T > log1p(const fvar< T > &x)
return_type< T_y, T_loc, T_scale >::type cauchy_cdf(const T_y &y, const T_loc &mu, const T_scale &sigma)
Calculates the cauchy cumulative distribution function for the given variate, location, and scale.