| Stan Math Library 2.12.0 reverse mode automatic differentiation

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

log_mix.hpp
Go to the documentation of this file.
1 #ifndef STAN_MATH_FWD_SCAL_FUN_LOG_MIX_HPP
2 #define STAN_MATH_FWD_SCAL_FUN_LOG_MIX_HPP
3
4 #include <stan/math/fwd/core.hpp>
5 #include <stan/math/prim/scal/fun/value_of.hpp>
6 #include <stan/math/prim/scal/fun/log_mix.hpp>
7 #include <boost/math/tools/promotion.hpp>
8 #include <cmath>
9
10 namespace stan {
11 namespace math {
12
13 /* Returns an array of size N with partials of log_mix wrt to its
14 * parameters instantiated as fvar<T>
15 *
16 * @tparam T_theta theta scalar type
17 * @tparam T_lambda1 lambda_1 scalar type
18 * @tparam T_lambda2 lambda_2 scalar type
19 *
20 * @param[in] N output array size
21 * @param[in] theta_d mixing proportion theta
22 * @param[in] lambda1_d log_density with mixing proportion theta
23 * @param[in] lambda2_d log_density with mixing proportion 1.0 - theta
24 * @param[out] partials_array array of partials derivatives
25 */
26 template <typename T_theta, typename T_lambda1, typename T_lambda2, int N>
27 inline void
28 log_mix_partial_helper(const T_theta& theta,
29 const T_lambda1& lambda1,
30 const T_lambda2& lambda2,
31 typename
32 boost::math::tools::promote_args<
33 T_theta, T_lambda1, T_lambda2>::type
34 (&partials_array)[N]) {
35 using std::exp;
36 using boost::is_same;
37 using boost::math::tools::promote_args;
38 typedef typename promote_args<T_theta, T_lambda1, T_lambda2>::type
39 partial_return_type;
40
41 typename promote_args<T_lambda1, T_lambda2>::type lam2_m_lam1
42 = lambda2 - lambda1;
43 typename promote_args<T_lambda1, T_lambda2>::type exp_lam2_m_lam1
44 = 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;
54
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;
60 ++offset;
61 }
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;
65 ++offset;
66 }
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;
71 }
72 }
73
113 template <typename T>
114 inline
115 fvar<T>
116 log_mix(const fvar<T>& theta, const fvar<T>& lambda1,
117 const fvar<T>& lambda2) {
118 if (lambda1.val_ > lambda2.val_) {
119 fvar<T> partial_deriv_array[3];
120 log_mix_partial_helper(theta, lambda1, lambda2, partial_deriv_array);
121 return fvar<T>(log_mix(theta.val_, lambda1.val_, lambda2.val_),
122 theta.d_ * value_of(partial_deriv_array[0])
123 + lambda1.d_ * value_of(partial_deriv_array[1])
124 + lambda2.d_ * value_of(partial_deriv_array[2]));
125 } else {
126 fvar<T> partial_deriv_array[3];
127 log_mix_partial_helper(1.0 - theta, lambda2, lambda1,
128 partial_deriv_array);
129 return fvar<T>(log_mix(theta.val_, lambda1.val_, lambda2.val_),
130 -theta.d_ * value_of(partial_deriv_array[0])
131 + lambda1.d_ * value_of(partial_deriv_array[2])
132 + lambda2.d_ * value_of(partial_deriv_array[1]));
133 }
134 }
135
136 template <typename T>
137 inline
138 fvar<T>
139 log_mix(const fvar<T>& theta, const fvar<T>& lambda1,
140 const double lambda2) {
141 if (lambda1.val_ > lambda2) {
142 fvar<T> partial_deriv_array[2];
143 log_mix_partial_helper(theta, lambda1, lambda2,
144 partial_deriv_array);
145 return fvar<T>(log_mix(theta.val_, lambda1.val_, lambda2),
146 theta.d_ * value_of(partial_deriv_array[0])
147 + lambda1.d_ * value_of(partial_deriv_array[1]));
148 } else {
149 fvar<T> partial_deriv_array[2];
150 log_mix_partial_helper(1.0 - theta, lambda2, lambda1,
151 partial_deriv_array);
152 return fvar<T>(log_mix(theta.val_, lambda1.val_, lambda2),
153 -theta.d_ * value_of(partial_deriv_array[0])
154 + lambda1.d_ * value_of(partial_deriv_array[1]));
155 }
156 }
157
158 template<typename T>
159 inline
160 fvar<T>
161 log_mix(const fvar<T>& theta, const double lambda1,
162 const fvar<T>& lambda2) {
163 if (lambda1 > lambda2.val_) {
164 fvar<T> partial_deriv_array[2];
165 log_mix_partial_helper(theta, lambda1, lambda2,
166 partial_deriv_array);
167 return fvar<T>(log_mix(theta.val_, lambda1, lambda2.val_),
168 theta.d_ * value_of(partial_deriv_array[0])
169 + lambda2.d_ * value_of(partial_deriv_array[1]));
170 } else {
171 fvar<T> partial_deriv_array[2];
172 log_mix_partial_helper(1.0 - theta, lambda2, lambda1,
173 partial_deriv_array);
174 return fvar<T>(log_mix(theta.val_, lambda1, lambda2.val_),
175 -theta.d_ * value_of(partial_deriv_array[0])
176 + lambda2.d_ * value_of(partial_deriv_array[1]));
177 }
178 }
179
180 template<typename T>
181 inline
182 fvar<T>
183 log_mix(const double theta, const fvar<T>& lambda1,
184 const fvar<T>& lambda2) {
185 if (lambda1.val_ > lambda2.val_) {
186 fvar<T> partial_deriv_array[2];
187 log_mix_partial_helper(theta, lambda1, lambda2, partial_deriv_array);
188 return fvar<T>(log_mix(theta, lambda1.val_, lambda2.val_),
189 lambda1.d_ * value_of(partial_deriv_array[0])
190 + lambda2.d_ * value_of(partial_deriv_array[1]));
191 } else {
192 fvar<T> partial_deriv_array[2];
193 log_mix_partial_helper(1.0 - theta, lambda2, lambda1,
194 partial_deriv_array);
195 return fvar<T>(log_mix(theta, lambda1.val_, lambda2.val_),
196 lambda1.d_ * value_of(partial_deriv_array[1])
197 + lambda2.d_ * value_of(partial_deriv_array[0]));
198 }
199 }
200
201 template<typename T>
202 inline
203 fvar<T>
204 log_mix(const fvar<T>& theta, const double lambda1, const double lambda2) {
205 if (lambda1 > lambda2) {
206 fvar<T> partial_deriv_array[1];
207 log_mix_partial_helper(theta, lambda1, lambda2, partial_deriv_array);
208 return fvar<T>(log_mix(theta.val_, lambda1, lambda2),
209 theta.d_ * value_of(partial_deriv_array[0]));
210 } else {
211 fvar<T> partial_deriv_array[1];
212 log_mix_partial_helper(1.0 - theta, lambda2, lambda1,
213 partial_deriv_array);
214 return fvar<T>(log_mix(theta.val_, lambda1, lambda2),
215 -theta.d_ * value_of(partial_deriv_array[0]));
216 }
217 }
218
219 template<typename T>
220 inline
221 fvar<T>
222 log_mix(const double theta, const fvar<T>& lambda1, const double lambda2) {
223 if (lambda1.val_ > lambda2) {
224 fvar<T> partial_deriv_array[1];
225 log_mix_partial_helper(theta, lambda1, lambda2, partial_deriv_array);
226 return fvar<T>(log_mix(theta, lambda1.val_, lambda2),
227 lambda1.d_ * value_of(partial_deriv_array[0]));
228 } else {
229 fvar<T> partial_deriv_array[1];
230 log_mix_partial_helper(1.0 - theta, lambda2, lambda1,
231 partial_deriv_array);
232 return fvar<T>(log_mix(theta, lambda1.val_, lambda2),
233 lambda1.d_ * value_of(partial_deriv_array[0]));
234 }
235 }
236
237 template<typename T>
238 inline
239 fvar<T>
240 log_mix(const double theta, const double lambda1, const fvar<T>& lambda2) {
241 if (lambda1 > lambda2.val_) {
242 fvar<T> partial_deriv_array[1];
243 log_mix_partial_helper(theta, lambda1, lambda2, partial_deriv_array);
244 return fvar<T>(log_mix(theta, lambda1, lambda2.val_),
245 lambda2.d_ * value_of(partial_deriv_array[0]));
246 } else {
247 fvar<T> partial_deriv_array[1];
248 log_mix_partial_helper(1.0 - theta, lambda2, lambda1,
249 partial_deriv_array);
250 return fvar<T>(log_mix(theta, lambda1, lambda2.val_),
251 lambda2.d_ * value_of(partial_deriv_array[0]));
252 }
253 }
254 }
255 }
256 #endif
core.hpp
stan::math::fvar::d_
T d_
Definition: fvar.hpp:14
stan
Definition: log_sum_exp.hpp:8
stan::math::value_of
T value_of(const fvar< T > &v)
Return the value of the specified variable.
Definition: value_of.hpp:16
stan::math::fvar::val_
T val_
Definition: fvar.hpp:13
stan::math::exp
fvar< T > exp(const fvar< T > &x)
Definition: exp.hpp:10
log_mix.hpp
stan::math::log_mix_partial_helper
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:28
value_of.hpp
stan::math::log_mix
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:116
stan::math::fvar
Definition: fvar.hpp:12

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