1 #ifndef STAN__PROB__DISTRIBUTIONS__FRECHET_HPP
2 #define STAN__PROB__DISTRIBUTIONS__FRECHET_HPP
4 #include <boost/random/weibull_distribution.hpp>
5 #include <boost/random/variate_generator.hpp>
21 template <
bool propto,
22 typename T_y,
typename T_shape,
typename T_scale>
23 typename return_type<T_y,T_shape,T_scale>::type
24 frechet_log(
const T_y& y,
const T_shape& alpha,
const T_scale& sigma) {
25 static const char*
function =
"stan::prob::frechet_log(%1%)";
47 "Random variable",
"Shape parameter",
58 size_t N =
max_size(y, alpha, sigma);
62 for (
size_t i = 0; i <
length(alpha); i++)
68 for (
size_t i = 0; i <
length(y); i++)
74 for (
size_t i = 0; i <
length(sigma); i++)
80 for (
size_t i = 0; i <
length(y); i++)
86 sigma_div_y_pow_alpha(N);
87 for (
size_t i = 0; i < N; i++)
89 const double alpha_dbl =
value_of(alpha_vec[i]);
94 for (
size_t n = 0; n < N; n++) {
95 const double alpha_dbl =
value_of(alpha_vec[n]);
99 logp -= (alpha_dbl+1.0)*log_y[n];
101 logp += alpha_dbl*log_sigma[n];
103 logp -= sigma_div_y_pow_alpha[n];
106 const double inv_y_dbl =
value_of(inv_y[n]);
107 operands_and_partials.
d_x1[n]
108 += -(alpha_dbl+1.0) * inv_y_dbl
109 + alpha_dbl * sigma_div_y_pow_alpha[n] * inv_y_dbl;
112 operands_and_partials.
d_x2[n]
114 + (1.0 - sigma_div_y_pow_alpha[n]) * (log_sigma[n] - log_y[n]);
116 operands_and_partials.
d_x3[n]
117 += alpha_dbl /
value_of(sigma_vec[n]) * (1 - sigma_div_y_pow_alpha[n]);
119 return operands_and_partials.
to_var(logp);
122 template <
typename T_y,
typename T_shape,
typename T_scale>
125 frechet_log(
const T_y& y,
const T_shape& alpha,
const T_scale& sigma) {
126 return frechet_log<false>(y,alpha,sigma);
129 template <
typename T_y,
typename T_shape,
typename T_scale>
131 frechet_cdf(
const T_y& y,
const T_shape& alpha,
const T_scale& sigma) {
133 static const char*
function =
"stan::prob::frechet_cdf(%1%)";
138 using boost::math::tools::promote_args;
153 operands_and_partials(y, alpha, sigma);
158 size_t N =
max_size(y, sigma, alpha);
159 for (
size_t n = 0; n < N; n++) {
160 const double y_dbl =
value_of(y_vec[n]);
161 const double sigma_dbl =
value_of(sigma_vec[n]);
162 const double alpha_dbl =
value_of(alpha_vec[n]);
163 const double pow_ =
pow(sigma_dbl / y_dbl, alpha_dbl);
164 const double cdf_ =
exp(-pow_);
171 operands_and_partials.
d_x1[n] += pow_ * alpha_dbl / y_dbl;
173 operands_and_partials.
d_x2[n] += pow_ *
log(y_dbl / sigma_dbl);
175 operands_and_partials.
d_x3[n] -= pow_ * alpha_dbl / sigma_dbl;
180 operands_and_partials.
d_x1[n] *= cdf;
183 operands_and_partials.
d_x2[n] *= cdf;
186 operands_and_partials.
d_x3[n] *= cdf;
188 return operands_and_partials.
to_var(cdf);
191 template <
typename T_y,
typename T_shape,
typename T_scale>
195 static const char*
function =
"stan::prob::frechet_cdf_log(%1%)";
200 using boost::math::tools::promote_args;
215 operands_and_partials(y, alpha, sigma);
220 size_t N =
max_size(y, sigma, alpha);
221 for (
size_t n = 0; n < N; n++) {
222 const double y_dbl =
value_of(y_vec[n]);
223 const double sigma_dbl =
value_of(sigma_vec[n]);
224 const double alpha_dbl =
value_of(alpha_vec[n]);
225 const double pow_ =
pow(sigma_dbl / y_dbl, alpha_dbl);
232 operands_and_partials.
d_x1[n] += pow_ * alpha_dbl / y_dbl;
234 operands_and_partials.
d_x2[n] += pow_ *
log(y_dbl / sigma_dbl);
236 operands_and_partials.
d_x3[n] -= pow_ * alpha_dbl / sigma_dbl;
239 return operands_and_partials.
to_var(cdf_log);
242 template <
typename T_y,
typename T_shape,
typename T_scale>
246 static const char*
function =
"stan::prob::frechet_ccdf_log(%1%)";
251 using boost::math::tools::promote_args;
260 double ccdf_log(0.0);
266 operands_and_partials(y, alpha, sigma);
271 size_t N =
max_size(y, sigma, alpha);
272 for (
size_t n = 0; n < N; n++) {
273 const double y_dbl =
value_of(y_vec[n]);
274 const double sigma_dbl =
value_of(sigma_vec[n]);
275 const double alpha_dbl =
value_of(alpha_vec[n]);
276 const double pow_ =
pow(sigma_dbl / y_dbl, alpha_dbl);
277 const double exp_ =
exp(-pow_);
280 ccdf_log +=
log(1 - exp_);
283 const double rep_deriv_ = pow_ / ( 1.0 / exp_ - 1 );
285 operands_and_partials.
d_x1[n] -= alpha_dbl / y_dbl * rep_deriv_;
287 operands_and_partials.
d_x2[n] -=
log(y_dbl / sigma_dbl) * rep_deriv_;
289 operands_and_partials.
d_x3[n] += alpha_dbl / sigma_dbl * rep_deriv_;
292 return operands_and_partials.
to_var(ccdf_log);
300 using boost::variate_generator;
301 using boost::random::weibull_distribution;
303 static const char*
function =
"stan::prob::frechet_rng(%1%)";
309 check_finite(
function, alpha,
"Shape parameter", (
double*)0);
311 check_not_nan(
function, sigma,
"Scale parameter", (
double*)0);
314 variate_generator<RNG&, weibull_distribution<> >
315 weibull_rng(rng, weibull_distribution<>(alpha, 1.0/sigma));
double weibull_rng(const double alpha, const double sigma, RNG &rng)
return_type< T_y, T_shape, T_scale >::type frechet_ccdf_log(const T_y &y, const T_shape &alpha, const T_scale &sigma)
T_return_type to_var(double logp)
bool check_positive_finite(const char *function, const T_y &y, const char *name, T_result *result)
fvar< T > pow(const fvar< T > &x1, const fvar< T > &x2)
boost::math::tools::promote_args< T_a, T_b >::type multiply_log(const T_a a, const T_b b)
Calculated the value of the first argument times log of the second argument while behaving properly w...
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.
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
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.
return_type< T_y, T_shape, T_scale >::type frechet_log(const T_y &y, const T_shape &alpha, const T_scale &sigma)
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
bool check_nonnegative(const char *function, const T_y &y, const char *name, T_result *result)
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)
bool check_positive(const char *function, const T_y &y, const char *name, T_result *result)
return_type< T_y, T_shape, T_scale >::type frechet_cdf(const T_y &y, const T_shape &alpha, const T_scale &sigma)
bool check_not_nan(const char *function, const T_y &y, const char *name, T_result *result)
Checks if the variable y is nan.
double frechet_rng(const double alpha, const double sigma, RNG &rng)
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
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 > exp(const fvar< T > &x)
return_type< T_y, T_shape, T_scale >::type frechet_cdf_log(const T_y &y, const T_shape &alpha, const T_scale &sigma)