Stan Math Library: stan/math/prim/scal/prob/wiener_log.hpp Source File

| Stan Math Library 2.10.0 reverse mode automatic differentiation

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

wiener_log.hpp
Go to the documentation of this file.
1 // Copyright (c) 2013, Joachim Vandekerckhove.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted
6 // provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright notice,
9 // * this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright notice,
11 // * this list of conditions and the following disclaimer in the
12 // * documentation and/or other materials provided with the distribution.
13 // * Neither the name of the University of California, Irvine nor the names
14 // * of its contributors may be used to endorse or promote products derived
15 // * from this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 // THE POSSIBILITY OF SUCH DAMAGE.
28
29 #ifndef STAN_MATH_PRIM_MAT_PROB_WIENER_LOG_HPP
30 #define STAN_MATH_PRIM_MAT_PROB_WIENER_LOG_HPP
31
32 #include <stan/math/prim/scal/fun/constants.hpp>
33 #include <stan/math/prim/scal/fun/square.hpp>
34 #include <stan/math/prim/scal/fun/value_of.hpp>
35 #include <stan/math/prim/scal/err/check_consistent_sizes.hpp>
36 #include <stan/math/prim/scal/err/check_bounded.hpp>
37 #include <stan/math/prim/scal/err/check_finite.hpp>
38 #include <stan/math/prim/scal/err/check_not_nan.hpp>
39 #include <stan/math/prim/scal/err/check_positive.hpp>
40 #include <stan/math/prim/scal/meta/return_type.hpp>
41 #include <stan/math/prim/scal/meta/include_summand.hpp>
42 #include <boost/math/distributions.hpp>
43 #include <cmath>
44 #include <algorithm> // for max
45
46 namespace stan {
47
48 namespace math {
49
68 template <bool propto,
69 typename T_y, typename T_alpha, typename T_tau,
70 typename T_beta, typename T_delta>
71 typename return_type<T_y, T_alpha, T_tau, T_beta, T_delta>::type
72 wiener_log(const T_y& y, const T_alpha& alpha, const T_tau& tau,
73 const T_beta& beta, const T_delta& delta) {
74 static const char* function("stan::math::wiener_log(%1%)");
75
76 using boost::math::tools::promote_args;
77 using boost::math::isinf;
78 using boost::math::isfinite;
79 using std::log;
80 using std::exp;
81 using std::pow;
82
83 static const double WIENER_ERR = 0.000001;
84 static const double PI_TIMES_WIENER_ERR = pi() * WIENER_ERR;
85 static const double LOG_PI_LOG_WIENER_ERR =
86 LOG_PI + log(WIENER_ERR);
87 static const double
88 TWO_TIMES_SQRT_2_TIMES_SQRT_PI_TIMES_WIENER_ERR =
89 2.0 * SQRT_2_TIMES_SQRT_PI * WIENER_ERR;
90 static const double LOG_TWO_OVER_TWO_PLUS_LOG_SQRT_PI =
91 LOG_TWO / 2 + LOG_SQRT_PI;
92 static const double SQUARE_PI_OVER_TWO = square(pi()) * 0.5;
93 static const double TWO_TIMES_LOG_SQRT_PI = 2.0 * LOG_SQRT_PI;
94
95 if (!(stan::length(y)
96 && stan::length(alpha)
97 && stan::length(beta)
98 && stan::length(tau)
99 && stan::length(delta)))
100 return 0.0;
101
102 typedef typename return_type<T_y, T_alpha, T_tau,
103 T_beta, T_delta>::type T_return_type;
104 T_return_type lp(0.0);
105
106 check_not_nan(function, "Random variable", y);
107 check_not_nan(function, "Boundary separation", alpha);
108 check_not_nan(function, "A-priori bias", beta);
109 check_not_nan(function, "Nondecision time", tau);
110 check_not_nan(function, "Drift rate", delta);
111 check_finite(function, "Boundary separation", alpha);
112 check_finite(function, "A-priori bias", beta);
113 check_finite(function, "Nondecision time", tau);
114 check_finite(function, "Drift rate", delta);
115 check_positive(function, "Random variable", y);
116 check_positive(function, "Boundary separation", alpha);
117 check_positive(function, "Nondecision time", tau);
118 check_bounded(function, "A-priori bias", beta , 0, 1);
119 check_consistent_sizes(function,
120 "Random variable", y,
121 "Boundary separation", alpha,
122 "A-priori bias", beta,
123 "Nondecision time", tau,
124 "Drift rate", delta);
125
126 size_t N =
127 std::max(max_size(y, alpha, beta), max_size(tau, delta));
128 if (!N)
129 return 0.0;
130 VectorView<const T_y> y_vec(y);
131 VectorView<const T_alpha> alpha_vec(alpha);
132 VectorView<const T_beta> beta_vec(beta);
133 VectorView<const T_tau> tau_vec(tau);
134 VectorView<const T_delta> delta_vec(delta);
135
136 if (!include_summand<propto, T_y, T_alpha, T_tau,
137 T_beta, T_delta>::value) {
138 return 0;
139 }
140
141 for (size_t i = 0; i < N; i++)
142 if (y_vec[i] < tau_vec[i]) {
143 lp = stan::math::negative_infinity();
144 return lp;
145 }
146
147 for (size_t i = 0; i < N; i++) {
148 typename scalar_type<T_beta>::type one_minus_beta
149 = 1.0 - beta_vec[i];
150 typename scalar_type<T_alpha>::type alpha2
151 = square(alpha_vec[i]);
152 T_return_type x = y_vec[i];
153 T_return_type kl, ks, tmp = 0;
154 T_return_type k, K;
155
156
157 x = x - tau_vec[i]; // remove non-decision time from x
158 x = x / alpha2; // convert t to normalized time tt
159 T_return_type sqrt_x = sqrt(x);
160 T_return_type log_x = log(x);
161 T_return_type one_over_pi_times_sqrt_x = 1.0 / pi() * sqrt_x;
162
163 // calculate number of terms needed for large t:
164 // if error threshold is set low enough
165 if (PI_TIMES_WIENER_ERR * x < 1) {
166 // compute bound
167 kl = sqrt(-2.0 * SQRT_PI *
168 (LOG_PI_LOG_WIENER_ERR + log_x)) /
169 sqrt_x;
170 // ensure boundary conditions met
171 kl = (kl > one_over_pi_times_sqrt_x) ?
172 kl : one_over_pi_times_sqrt_x;
173 } else { // if error threshold set too high
174 kl = one_over_pi_times_sqrt_x; // set to boundary condition
175 }
176 // calculate number of terms needed for small t:
177 // if error threshold is set low enough
178 T_return_type tmp_expr0
179 = TWO_TIMES_SQRT_2_TIMES_SQRT_PI_TIMES_WIENER_ERR * sqrt_x;
180 if (tmp_expr0 < 1) {
181 // compute bound
182 ks = 2.0 + sqrt_x * sqrt(-2 * log(tmp_expr0));
183 // ensure boundary conditions are met
184 T_return_type sqrt_x_plus_one = sqrt_x + 1.0;
185 ks = (ks > sqrt_x_plus_one) ? ks : sqrt_x_plus_one;
186 } else { // if error threshold was set too high
187 ks = 2.0; // minimal kappa for that case
188 }
189 // compute density: f(tt|0,1,w)
190 if (ks < kl) { // if small t is better (i.e., lambda<0)
191 K = ceil(ks); // round to smallest integer meeting error
192 T_return_type tmp_expr1 = (K - 1.0) / 2.0;
193 T_return_type tmp_expr2 = ceil(tmp_expr1);
194 for (k = -floor(tmp_expr1); k <= tmp_expr2; k++)
195 // increment sum
196 tmp += (one_minus_beta + 2.0 * k) *
197 exp(-(square(one_minus_beta + 2.0 * k)) * 0.5 / x);
198 // add constant term
199 tmp = log(tmp) -
200 LOG_TWO_OVER_TWO_PLUS_LOG_SQRT_PI - 1.5 * log_x;
201 } else { // if large t is better...
202 K = ceil(kl); // round to smallest integer meeting error
203 for (k = 1; k <= K; k++)
204 // increment sum
205 tmp += k * exp(-(square(k)) *
206 (SQUARE_PI_OVER_TWO * x)) *
207 sin(k * pi() * one_minus_beta);
208 tmp = log(tmp) +
209 TWO_TIMES_LOG_SQRT_PI; // add constant term
210 }
211
212 // convert to f(t|v,a,w) and return result
213 lp += delta_vec[i] * alpha_vec[i] * one_minus_beta -
214 square(delta_vec[i]) * x * alpha2 / 2.0 -
215 log(alpha2) + tmp;
216 }
217
218 return lp;
219 }
220
221 template <typename T_y, typename T_alpha, typename T_tau,
222 typename T_beta, typename T_delta>
223 inline
224 typename return_type<T_y, T_alpha, T_tau, T_beta, T_delta>::type
225 wiener_log(const T_y& y, const T_alpha& alpha, const T_tau& tau,
226 const T_beta& beta, const T_delta& delta) {
227 return wiener_log<false>(y, alpha, tau, beta, delta);
228 }
229 }
230 }
231 #endif
check_not_nan.hpp
stan::math::wiener_log
return_type< T_y, T_alpha, T_tau, T_beta, T_delta >::type wiener_log(const T_y &y, const T_alpha &alpha, const T_tau &tau, const T_beta &beta, const T_delta &delta)
The log of the first passage time density function for a (Wiener) drift diffusion model for the given...
Definition: wiener_log.hpp:72
boost::math::isfinite
bool isfinite(const stan::math::var &v)
Checks if the given number has finite value.
Definition: boost_isfinite.hpp:22
stan::math::sqrt
fvar< T > sqrt(const fvar< T > &x)
Definition: sqrt.hpp:15
stan::math::check_not_nan
bool check_not_nan(const char *function, const char *name, const T_y &y)
Return true if y is not NaN.
Definition: check_not_nan.hpp:63
check_positive.hpp
stan
Definition: log_sum_exp.hpp:8
stan::math::LOG_PI
const double LOG_PI
Definition: constants.hpp:170
stan::math::log
fvar< T > log(const fvar< T > &x)
Definition: log.hpp:15
square.hpp
stan::math::LOG_SQRT_PI
const double LOG_SQRT_PI
Definition: constants.hpp:173
stan::length
size_t length(const std::vector< T > &x)
Definition: length.hpp:10
stan::math::check_bounded
bool check_bounded(const char *function, const char *name, const T_y &y, const T_low &low, const T_high &high)
Return true if the value is between the low and high values, inclusively.
Definition: check_bounded.hpp:95
stan::return_type
Metaprogram to calculate the base scalar return type resulting from promoting all the scalar types of...
Definition: return_type.hpp:19
stan::scalar_type::type
scalar_type_helper< is_vector< T >::value, T >::type type
Definition: scalar_type.hpp:35
return_type.hpp
stan::math::include_summand
Template metaprogram to calculate whether a summand needs to be included in a proportional (log) prob...
Definition: include_summand.hpp:36
stan::return_type::type
boost::math::tools::promote_args< typename scalar_type< T1 >::type, typename scalar_type< T2 >::type, typename scalar_type< T3 >::type, typename scalar_type< T4 >::type, typename scalar_type< T5 >::type, typename scalar_type< T6 >::type >::type type
Definition: return_type.hpp:27
stan::math::square
fvar< T > square(const fvar< T > &x)
Definition: square.hpp:15
stan::math::LOG_TWO
const double LOG_TWO
Definition: constants.hpp:177
include_summand.hpp
stan::math::SQRT_2_TIMES_SQRT_PI
const double SQRT_2_TIMES_SQRT_PI
Definition: constants.hpp:158
boost::math::isinf
bool isinf(const stan::math::var &v)
Checks if the given number is infinite.
Definition: boost_isinf.hpp:22
stan::math::sin
fvar< T > sin(const fvar< T > &x)
Definition: sin.hpp:14
stan::math::exp
fvar< T > exp(const fvar< T > &x)
Definition: exp.hpp:10
stan::math::check_positive
bool check_positive(const char *function, const char *name, const T_y &y)
Return true if y is positive.
Definition: check_positive.hpp:68
stan::max_size
size_t max_size(const T1 &x1, const T2 &x2)
Definition: max_size.hpp:9
stan::math::max
int max(const std::vector< int > &x)
Returns the maximum coefficient in the specified column vector.
Definition: max.hpp:21
check_bounded.hpp
stan::math::check_finite
bool check_finite(const char *function, const char *name, const T_y &y)
Return true if y is finite.
Definition: check_finite.hpp:62
constants.hpp
stan::math::floor
fvar< T > floor(const fvar< T > &x)
Definition: floor.hpp:11
stan::math::check_consistent_sizes
bool check_consistent_sizes(const char *function, const char *name1, const T1 &x1, const char *name2, const T2 &x2)
Return true if the dimension of x1 is consistent with x2.
Definition: check_consistent_sizes.hpp:31
check_finite.hpp
stan::math::pi
double pi()
Return the value of pi.
Definition: constants.hpp:86
stan::math::pow
fvar< T > pow(const fvar< T > &x1, const fvar< T > &x2)
Definition: pow.hpp:18
value_of.hpp
stan::VectorView
VectorView is a template expression that is constructed with a container or scalar, which it then allows to be used as an array using operator[].
Definition: VectorView.hpp:48
check_consistent_sizes.hpp
stan::math::SQRT_PI
const double SQRT_PI
Definition: constants.hpp:156
stan::math::ceil
fvar< T > ceil(const fvar< T > &x)
Definition: ceil.hpp:11
stan::math::negative_infinity
double negative_infinity()
Return negative infinity.
Definition: constants.hpp:132

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