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>
13 using boost::math::tools::promote_args;
29 template <
typename T_theta,
typename T_lambda1,
typename T_lambda2,
int N>
32 const T_lambda1& lambda1,
33 const T_lambda2& lambda2,
35 promote_args<T_theta, T_lambda1, T_lambda2>::type
36 (&partials_array)[N]) {
37 typedef typename promote_args<T_theta, T_lambda1, T_lambda2>::type
41 typename promote_args<T_lambda1, T_lambda2>::type lam2_m_lam1
43 typename promote_args<T_lambda1, T_lambda2>::type exp_lam2_m_lam1
45 typename promote_args<T_lambda1, T_lambda2>::type one_m_exp_lam2_m_lam1
46 = 1.0 - exp_lam2_m_lam1;
47 typename promote_args<double, T_theta>::type one_m_t = 1.0 - theta;
48 partial_return_type one_m_t_prod_exp_lam2_m_lam1
49 = one_m_t * exp_lam2_m_lam1;
50 partial_return_type t_plus_one_m_t_prod_exp_lam2_m_lam1
51 = theta + one_m_t_prod_exp_lam2_m_lam1;
52 partial_return_type one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1
53 = 1.0 / t_plus_one_m_t_prod_exp_lam2_m_lam1;
55 unsigned int offset = 0;
56 if (is_same<T_theta, partial_return_type>::value) {
57 partials_array[offset]
58 = one_m_exp_lam2_m_lam1
59 * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
62 if (is_same<T_lambda1, partial_return_type>::value) {
63 partials_array[offset]
64 = theta * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
67 if (is_same<T_lambda2, partial_return_type>::value) {
68 partials_array[offset]
69 = one_m_t_prod_exp_lam2_m_lam1
70 * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
113 template <
typename T>
122 fvar<T> partial_deriv_array[3];
126 + lambda1.
d_ *
value_of(partial_deriv_array[1])
127 + lambda2.
d_ *
value_of(partial_deriv_array[2]));
129 fvar<T> partial_deriv_array[3];
131 partial_deriv_array);
134 + lambda1.
d_ *
value_of(partial_deriv_array[2])
135 + lambda2.
d_ *
value_of(partial_deriv_array[1]));
139 template <
typename T>
143 const double lambda2) {
147 if (lambda1.
val_ > lambda2) {
148 fvar<T> partial_deriv_array[2];
150 partial_deriv_array);
153 + lambda1.
d_ *
value_of(partial_deriv_array[1]));
155 fvar<T> partial_deriv_array[2];
157 partial_deriv_array);
160 + lambda1.
d_ *
value_of(partial_deriv_array[1]));
172 if (lambda1 > lambda2.
val_) {
173 fvar<T> partial_deriv_array[2];
175 partial_deriv_array);
178 + lambda2.
d_ *
value_of(partial_deriv_array[1]));
180 fvar<T> partial_deriv_array[2];
182 partial_deriv_array);
185 + lambda2.
d_ *
value_of(partial_deriv_array[1]));
198 fvar<T> partial_deriv_array[2];
202 + lambda2.
d_ *
value_of(partial_deriv_array[1]));
204 fvar<T> partial_deriv_array[2];
206 partial_deriv_array);
209 + lambda2.
d_ *
value_of(partial_deriv_array[0]));
220 if (lambda1 > lambda2) {
221 fvar<T> partial_deriv_array[1];
226 fvar<T> partial_deriv_array[1];
228 partial_deriv_array);
230 -theta.
d_ *
value_of(partial_deriv_array[0]));
241 if (lambda1.
val_ > lambda2) {
242 fvar<T> partial_deriv_array[1];
245 lambda1.
d_ *
value_of(partial_deriv_array[0]));
247 fvar<T> partial_deriv_array[1];
249 partial_deriv_array);
251 lambda1.
d_ *
value_of(partial_deriv_array[0]));
262 if (lambda1 > lambda2.
val_) {
263 fvar<T> partial_deriv_array[1];
266 lambda2.
d_ *
value_of(partial_deriv_array[0]));
268 fvar<T> partial_deriv_array[1];
270 partial_deriv_array);
272 lambda2.
d_ *
value_of(partial_deriv_array[0]));
void log_mix_partial_helper(const T_theta &theta, const T_lambda1 &lambda1, const T_lambda2 &lambda2, typename promote_args< T_theta, T_lambda1, T_lambda2 >::type(&partials_array)[N])
T value_of(const fvar< T > &v)
Return the value of the specified variable.
fvar< T > exp(const fvar< T > &x)
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 ...