| Stan Math Library 2.6.3 probability, sampling & optimization

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros
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
12 namespace math {
13 using boost::math::tools::promote_args;
14 using boost::is_same;
15
16 /* Returns an array of size N with partials of log_mix wrt to its
17 * parameters instantiated as fvar<T>
18 *
19 * @tparam T_theta theta scalar type
20 * @tparam T_lambda1 lambda_1 scalar type
21 * @tparam T_lambda2 lambda_2 scalar type
22 *
23 * @param[in] N output array size
24 * @param[in] theta_d mixing proportion theta
25 * @param[in] lambda1_d log_density with mixing proportion theta
26 * @param[in] lambda2_d log_density with mixing proportion 1.0 - theta
27 * @param[out] partials_array array of partials derivatives
28 */
29 template <typename T_theta, typename T_lambda1, typename T_lambda2, int N>
30 inline void
31 log_mix_partial_helper(const T_theta& theta,
32 const T_lambda1& lambda1,
33 const T_lambda2& lambda2,
34 typename
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
38 partial_return_type;
39 using std::exp;
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 using stan::math::log_mix;
119 using stan::math::value_of;
120
121 if (lambda1.val_ > lambda2.val_) {
122 fvar<T> partial_deriv_array[3];
123 log_mix_partial_helper(theta, lambda1, lambda2, partial_deriv_array);
124 return fvar<T>(log_mix(theta.val_, lambda1.val_, lambda2.val_),
125 theta.d_ * value_of(partial_deriv_array[0])
126 + lambda1.d_ * value_of(partial_deriv_array[1])
127 + lambda2.d_ * value_of(partial_deriv_array[2]));
128 } else {
129 fvar<T> partial_deriv_array[3];
130 log_mix_partial_helper(1.0 - theta, lambda2, lambda1,
131 partial_deriv_array);
132 return fvar<T>(log_mix(theta.val_, lambda1.val_, lambda2.val_),
133 -theta.d_ * value_of(partial_deriv_array[0])
134 + lambda1.d_ * value_of(partial_deriv_array[2])
135 + lambda2.d_ * value_of(partial_deriv_array[1]));
136 }
137 }
138
139 template <typename T>
140 inline
141 fvar<T>
142 log_mix(const fvar<T>& theta, const fvar<T>& lambda1,
143 const double lambda2) {
144 using stan::math::log_mix;
145 using stan::math::value_of;
146
147 if (lambda1.val_ > lambda2) {
148 fvar<T> partial_deriv_array[2];
149 log_mix_partial_helper(theta, lambda1, lambda2,
150 partial_deriv_array);
151 return fvar<T>(log_mix(theta.val_, lambda1.val_, lambda2),
152 theta.d_ * value_of(partial_deriv_array[0])
153 + lambda1.d_ * value_of(partial_deriv_array[1]));
154 } else {
155 fvar<T> partial_deriv_array[2];
156 log_mix_partial_helper(1.0 - theta, lambda2, lambda1,
157 partial_deriv_array);
158 return fvar<T>(log_mix(theta.val_, lambda1.val_, lambda2),
159 -theta.d_ * value_of(partial_deriv_array[0])
160 + lambda1.d_ * value_of(partial_deriv_array[1]));
161 }
162 }
163
164 template<typename T>
165 inline
166 fvar<T>
167 log_mix(const fvar<T>& theta, const double lambda1,
168 const fvar<T>& lambda2) {
169 using stan::math::log_mix;
170 using stan::math::value_of;
171
172 if (lambda1 > lambda2.val_) {
173 fvar<T> partial_deriv_array[2];
174 log_mix_partial_helper(theta, lambda1, lambda2,
175 partial_deriv_array);
176 return fvar<T>(log_mix(theta.val_, lambda1, lambda2.val_),
177 theta.d_ * value_of(partial_deriv_array[0])
178 + lambda2.d_ * value_of(partial_deriv_array[1]));
179 } else {
180 fvar<T> partial_deriv_array[2];
181 log_mix_partial_helper(1.0 - theta, lambda2, lambda1,
182 partial_deriv_array);
183 return fvar<T>(log_mix(theta.val_, lambda1, lambda2.val_),
184 -theta.d_ * value_of(partial_deriv_array[0])
185 + lambda2.d_ * value_of(partial_deriv_array[1]));
186 }
187 }
188
189 template<typename T>
190 inline
191 fvar<T>
192 log_mix(const double theta, const fvar<T>& lambda1,
193 const fvar<T>& lambda2) {
194 using stan::math::log_mix;
195 using stan::math::value_of;
196
197 if (lambda1.val_ > lambda2.val_) {
198 fvar<T> partial_deriv_array[2];
199 log_mix_partial_helper(theta, lambda1, lambda2, partial_deriv_array);
200 return fvar<T>(log_mix(theta, lambda1.val_, lambda2.val_),
201 lambda1.d_ * value_of(partial_deriv_array[0])
202 + lambda2.d_ * value_of(partial_deriv_array[1]));
203 } else {
204 fvar<T> partial_deriv_array[2];
205 log_mix_partial_helper(1.0 - theta, lambda2, lambda1,
206 partial_deriv_array);
207 return fvar<T>(log_mix(theta, lambda1.val_, lambda2.val_),
208 lambda1.d_ * value_of(partial_deriv_array[1])
209 + lambda2.d_ * value_of(partial_deriv_array[0]));
210 }
211 }
212
213 template<typename T>
214 inline
215 fvar<T>
216 log_mix(const fvar<T>& theta, const double lambda1, const double lambda2) {
217 using stan::math::log_mix;
218 using stan::math::value_of;
219
220 if (lambda1 > lambda2) {
221 fvar<T> partial_deriv_array[1];
222 log_mix_partial_helper(theta, lambda1, lambda2, partial_deriv_array);
223 return fvar<T>(log_mix(theta.val_, lambda1, lambda2),
224 theta.d_ * value_of(partial_deriv_array[0]));
225 } else {
226 fvar<T> partial_deriv_array[1];
227 log_mix_partial_helper(1.0 - theta, lambda2, lambda1,
228 partial_deriv_array);
229 return fvar<T>(log_mix(theta.val_, lambda1, lambda2),
230 -theta.d_ * value_of(partial_deriv_array[0]));
231 }
232 }
233
234 template<typename T>
235 inline
236 fvar<T>
237 log_mix(const double theta, const fvar<T>& lambda1, const double lambda2) {
238 using stan::math::log_mix;
239 using stan::math::value_of;
240
241 if (lambda1.val_ > lambda2) {
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.val_, lambda2),
245 lambda1.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.val_, lambda2),
251 lambda1.d_ * value_of(partial_deriv_array[0]));
252 }
253 }
254
255 template<typename T>
256 inline
257 fvar<T>
258 log_mix(const double theta, const double lambda1, const fvar<T>& lambda2) {
259 using stan::math::log_mix;
260 using stan::math::value_of;
261
262 if (lambda1 > lambda2.val_) {
263 fvar<T> partial_deriv_array[1];
264 log_mix_partial_helper(theta, lambda1, lambda2, partial_deriv_array);
265 return fvar<T>(log_mix(theta, lambda1, lambda2.val_),
266 lambda2.d_ * value_of(partial_deriv_array[0]));
267 } else {
268 fvar<T> partial_deriv_array[1];
269 log_mix_partial_helper(1.0 - theta, lambda2, lambda1,
270 partial_deriv_array);
271 return fvar<T>(log_mix(theta, lambda1, lambda2.val_),
272 lambda2.d_ * value_of(partial_deriv_array[0]));
273 }
274 }
275 }
276 }
277 #endif
core.hpp
stan::math::fvar::d_
T d_
Definition: fvar.hpp:15
stan::math::log_mix_partial_helper
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])
Definition: log_mix.hpp:31
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:14
stan::math::exp
fvar< T > exp(const fvar< T > &x)
Definition: exp.hpp:10
log_mix.hpp
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:13

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