1 #ifndef STAN_MATH_FWD_SCAL_FUN_LOG_MIX_HPP 2 #define STAN_MATH_FWD_SCAL_FUN_LOG_MIX_HPP 8 #include <boost/math/tools/promotion.hpp> 10 #include <type_traits> 28 template <
typename T_theta,
typename T_lambda1,
typename T_lambda2,
int N>
30 const T_theta& theta,
const T_lambda1& lambda1,
const T_lambda2& lambda2,
31 typename boost::math::tools::promote_args<
32 T_theta, T_lambda1, T_lambda2>::type (&partials_array)[N]) {
33 using boost::math::tools::promote_args;
35 typedef typename promote_args<T_theta, T_lambda1, T_lambda2>::type
38 typename promote_args<T_lambda1, T_lambda2>::type lam2_m_lam1
40 typename promote_args<T_lambda1, T_lambda2>::type exp_lam2_m_lam1
42 typename promote_args<T_lambda1, T_lambda2>::type one_m_exp_lam2_m_lam1
43 = 1.0 - exp_lam2_m_lam1;
44 typename promote_args<double, T_theta>::type one_m_t = 1.0 - theta;
45 partial_return_type one_m_t_prod_exp_lam2_m_lam1 = one_m_t * exp_lam2_m_lam1;
46 partial_return_type t_plus_one_m_t_prod_exp_lam2_m_lam1
47 = theta + one_m_t_prod_exp_lam2_m_lam1;
48 partial_return_type one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1
49 = 1.0 / t_plus_one_m_t_prod_exp_lam2_m_lam1;
51 unsigned int offset = 0;
52 if (std::is_same<T_theta, partial_return_type>::value) {
53 partials_array[offset]
54 = one_m_exp_lam2_m_lam1 * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
57 if (std::is_same<T_lambda1, partial_return_type>::value) {
58 partials_array[offset] = theta * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
61 if (std::is_same<T_lambda2, partial_return_type>::value) {
62 partials_array[offset] = one_m_t_prod_exp_lam2_m_lam1
63 * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
106 template <
typename T>
110 fvar<T> partial_deriv_array[3];
114 + lambda1.
d_ *
value_of(partial_deriv_array[1])
115 + lambda2.
d_ *
value_of(partial_deriv_array[2]));
117 fvar<T> partial_deriv_array[3];
121 + lambda1.
d_ *
value_of(partial_deriv_array[2])
122 + lambda2.
d_ *
value_of(partial_deriv_array[1]));
126 template <
typename T>
129 if (lambda1.
val_ > lambda2) {
130 fvar<T> partial_deriv_array[2];
134 + lambda1.
d_ *
value_of(partial_deriv_array[1]));
136 fvar<T> partial_deriv_array[2];
140 + lambda1.
d_ *
value_of(partial_deriv_array[1]));
144 template <
typename T>
147 if (lambda1 > lambda2.
val_) {
148 fvar<T> partial_deriv_array[2];
152 + lambda2.
d_ *
value_of(partial_deriv_array[1]));
154 fvar<T> partial_deriv_array[2];
158 + lambda2.
d_ *
value_of(partial_deriv_array[1]));
162 template <
typename T>
166 fvar<T> partial_deriv_array[2];
170 + lambda2.
d_ *
value_of(partial_deriv_array[1]));
172 fvar<T> partial_deriv_array[2];
176 + lambda2.
d_ *
value_of(partial_deriv_array[0]));
180 template <
typename T>
182 if (lambda1 > lambda2) {
183 fvar<T> partial_deriv_array[1];
188 fvar<T> partial_deriv_array[1];
191 -theta.
d_ *
value_of(partial_deriv_array[0]));
195 template <
typename T>
197 if (lambda1.
val_ > lambda2) {
198 fvar<T> partial_deriv_array[1];
201 lambda1.
d_ *
value_of(partial_deriv_array[0]));
203 fvar<T> partial_deriv_array[1];
206 lambda1.
d_ *
value_of(partial_deriv_array[0]));
210 template <
typename T>
212 if (lambda1 > lambda2.
val_) {
213 fvar<T> partial_deriv_array[1];
216 lambda2.
d_ *
value_of(partial_deriv_array[0]));
218 fvar<T> partial_deriv_array[1];
221 lambda2.
d_ *
value_of(partial_deriv_array[0]));
T d_
The tangent (derivative) of this variable.
T value_of(const fvar< T > &v)
Return the value of the specified variable.
T val_
The value of this 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 ...
This template class represents scalars used in forward-mode automatic differentiation, which consist of values and directional derivatives of the specified template type.