Stan Math Library  2.20.0
reverse mode automatic differentiation
log_mix.hpp
Go to the documentation of this file.
1 #ifndef STAN_MATH_REV_SCAL_FUN_LOG_MIX_HPP
2 #define STAN_MATH_REV_SCAL_FUN_LOG_MIX_HPP
3 
4 #include <stan/math/rev/meta.hpp>
8 #include <cmath>
9 
10 namespace stan {
11 namespace math {
12 
13 /* Computes shared terms in log_mix partial derivative calculations
14  *
15  * @param[in] theta_val value of mixing proportion theta.
16  * @param[in] lambda1_val value of log density multiplied by theta.
17  * @param[in] lambda2_val value of log density multiplied by 1 - theta.
18  * @param[out] one_m_exp_lam2_m_lam1 shared term in deriv calculation.
19  * @param[out] one_m_t_prod_exp_lam2_m_lam1 shared term in deriv calculation.
20  * @param[out] one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1 shared term in deriv
21  * calculation.
22  */
24  double theta_val, double lambda1_val, double lambda2_val,
25  double& one_m_exp_lam2_m_lam1, double& one_m_t_prod_exp_lam2_m_lam1,
26  double& one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1) {
27  using std::exp;
28  double lam2_m_lam1 = lambda2_val - lambda1_val;
29  double exp_lam2_m_lam1 = exp(lam2_m_lam1);
30  one_m_exp_lam2_m_lam1 = 1 - exp_lam2_m_lam1;
31  double one_m_t = 1 - theta_val;
32  one_m_t_prod_exp_lam2_m_lam1 = one_m_t * exp_lam2_m_lam1;
33  one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1
34  = 1 / (theta_val + one_m_t_prod_exp_lam2_m_lam1);
35 }
36 
76 template <typename T_theta, typename T_lambda1, typename T_lambda2>
78  const T_theta& theta, const T_lambda1& lambda1, const T_lambda2& lambda2) {
79  using std::log;
80 
82  theta, lambda1, lambda2);
83 
84  double theta_double = value_of(theta);
85  const double lambda1_double = value_of(lambda1);
86  const double lambda2_double = value_of(lambda2);
87 
88  double log_mix_function_value
89  = log_mix(theta_double, lambda1_double, lambda2_double);
90 
91  double one_m_exp_lam2_m_lam1(0.0);
92  double one_m_t_prod_exp_lam2_m_lam1(0.0);
93  double one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1(0.0);
94 
95  if (lambda1 > lambda2) {
96  log_mix_partial_helper(theta_double, lambda1_double, lambda2_double,
97  one_m_exp_lam2_m_lam1, one_m_t_prod_exp_lam2_m_lam1,
98  one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1);
99  } else {
100  log_mix_partial_helper(1.0 - theta_double, lambda2_double, lambda1_double,
101  one_m_exp_lam2_m_lam1, one_m_t_prod_exp_lam2_m_lam1,
102  one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1);
103  one_m_exp_lam2_m_lam1 = -one_m_exp_lam2_m_lam1;
104  theta_double = one_m_t_prod_exp_lam2_m_lam1;
105  one_m_t_prod_exp_lam2_m_lam1 = 1.0 - value_of(theta);
106  }
107 
109  ops_partials.edge1_.partials_[0]
110  = one_m_exp_lam2_m_lam1 * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
112  ops_partials.edge2_.partials_[0]
113  = theta_double * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
115  ops_partials.edge3_.partials_[0]
116  = one_m_t_prod_exp_lam2_m_lam1
117  * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
118 
119  return ops_partials.build(log_mix_function_value);
120 }
121 
122 } // namespace math
123 } // namespace stan
124 #endif
T value_of(const fvar< T > &v)
Return the value of the specified variable.
Definition: value_of.hpp:17
Extends std::true_type when instantiated with zero or more template parameters, all of which extend t...
Definition: conjunction.hpp:14
fvar< T > log(const fvar< T > &x)
Definition: log.hpp:12
This template builds partial derivatives with respect to a set of operands.
boost::math::tools::promote_args< double, typename scalar_type< T >::type, typename return_type< Types_pack... >::type >::type type
Definition: return_type.hpp:36
fvar< T > exp(const fvar< T > &x)
Definition: exp.hpp:11
T_return_type build(double value)
Build the node to be stored on the autodiff graph.
internal::ops_partials_edge< double, Op2 > edge2_
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])
Definition: log_mix.hpp:29
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 ...
Definition: log_mix.hpp:107
internal::ops_partials_edge< double, Op3 > edge3_
internal::ops_partials_edge< double, Op1 > edge1_

     [ Stan Home Page ] © 2011–2018, Stan Development Team.