1 #ifndef STAN_MATH_FWD_SCAL_FUN_LOG_MIX_HPP
2 #define STAN_MATH_FWD_SCAL_FUN_LOG_MIX_HPP
7 #include <boost/math/tools/promotion.hpp>
27 template <
typename T_theta,
typename T_lambda1,
typename T_lambda2,
int N>
30 const T_lambda1& lambda1,
31 const T_lambda2& lambda2,
33 boost::math::tools::promote_args<
34 T_theta, T_lambda1, T_lambda2>::type
35 (&partials_array)[N]) {
38 using boost::math::tools::promote_args;
39 typedef typename promote_args<T_theta, T_lambda1, T_lambda2>::type
42 typename promote_args<T_lambda1, T_lambda2>::type lam2_m_lam1
44 typename promote_args<T_lambda1, T_lambda2>::type exp_lam2_m_lam1
46 typename promote_args<T_lambda1, T_lambda2>::type one_m_exp_lam2_m_lam1
47 = 1.0 - exp_lam2_m_lam1;
48 typename promote_args<double, T_theta>::type one_m_t = 1.0 - theta;
49 partial_return_type one_m_t_prod_exp_lam2_m_lam1
50 = one_m_t * exp_lam2_m_lam1;
51 partial_return_type t_plus_one_m_t_prod_exp_lam2_m_lam1
52 = theta + one_m_t_prod_exp_lam2_m_lam1;
53 partial_return_type one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1
54 = 1.0 / t_plus_one_m_t_prod_exp_lam2_m_lam1;
56 unsigned int offset = 0;
57 if (is_same<T_theta, partial_return_type>::value) {
58 partials_array[offset]
59 = one_m_exp_lam2_m_lam1
60 * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
63 if (is_same<T_lambda1, partial_return_type>::value) {
64 partials_array[offset]
65 = theta * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
68 if (is_same<T_lambda2, partial_return_type>::value) {
69 partials_array[offset]
70 = one_m_t_prod_exp_lam2_m_lam1
71 * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
114 template <
typename T>
123 fvar<T> partial_deriv_array[3];
127 + lambda1.
d_ *
value_of(partial_deriv_array[1])
128 + lambda2.
d_ *
value_of(partial_deriv_array[2]));
130 fvar<T> partial_deriv_array[3];
132 partial_deriv_array);
135 + lambda1.
d_ *
value_of(partial_deriv_array[2])
136 + lambda2.
d_ *
value_of(partial_deriv_array[1]));
140 template <
typename T>
144 const double lambda2) {
148 if (lambda1.
val_ > lambda2) {
149 fvar<T> partial_deriv_array[2];
151 partial_deriv_array);
154 + lambda1.
d_ *
value_of(partial_deriv_array[1]));
156 fvar<T> partial_deriv_array[2];
158 partial_deriv_array);
161 + lambda1.
d_ *
value_of(partial_deriv_array[1]));
173 if (lambda1 > lambda2.
val_) {
174 fvar<T> partial_deriv_array[2];
176 partial_deriv_array);
179 + lambda2.
d_ *
value_of(partial_deriv_array[1]));
181 fvar<T> partial_deriv_array[2];
183 partial_deriv_array);
186 + lambda2.
d_ *
value_of(partial_deriv_array[1]));
199 fvar<T> partial_deriv_array[2];
203 + lambda2.
d_ *
value_of(partial_deriv_array[1]));
205 fvar<T> partial_deriv_array[2];
207 partial_deriv_array);
210 + lambda2.
d_ *
value_of(partial_deriv_array[0]));
221 if (lambda1 > lambda2) {
222 fvar<T> partial_deriv_array[1];
227 fvar<T> partial_deriv_array[1];
229 partial_deriv_array);
231 -theta.
d_ *
value_of(partial_deriv_array[0]));
242 if (lambda1.
val_ > lambda2) {
243 fvar<T> partial_deriv_array[1];
246 lambda1.
d_ *
value_of(partial_deriv_array[0]));
248 fvar<T> partial_deriv_array[1];
250 partial_deriv_array);
252 lambda1.
d_ *
value_of(partial_deriv_array[0]));
263 if (lambda1 > lambda2.
val_) {
264 fvar<T> partial_deriv_array[1];
267 lambda2.
d_ *
value_of(partial_deriv_array[0]));
269 fvar<T> partial_deriv_array[1];
271 partial_deriv_array);
273 lambda2.
d_ *
value_of(partial_deriv_array[0]));
T value_of(const fvar< T > &v)
Return the value of the specified variable.
fvar< T > exp(const fvar< T > &x)
void log_mix_partial_helper(const T_theta &theta, const T_lambda1 &lambda1, const T_lambda2 &lambda2, typename boost::math::tools::promote_args< T_theta, T_lambda1, T_lambda2 >::type(&partials_array)[N])
fvar< T > log_mix(const fvar< T > &theta, const fvar< T > &lambda1, const fvar< T > &lambda2)
Return the log mixture density with specified mixing proportion and log densities and its derivative ...