Dear All,
We have simulated datasets of log-normally distributed response times that are assumed to be the sum of two latent response time components that are also log-normally distributed, i.e. rt = rt_{1} + rt_{2}. Therefore, I have implemented the Fenton-Wilkinson-Approximation as a custom function (see code below). The custom function is based on Eq. 3-6 in Pirinen (2003) and adapted from a Python implementation by Nakamura (2015). The approximation works, and the whole model converges more often than not, in reasonable time (90 minutes for I = 20 items and J = 500 persons). Nevertheless, profiling the model shows that most of the time is spent in the custom function.
The custom function has to inputs: (1) a vector of two means and (2) a vector of two standard deviations, that are calculated/sampled in the model, and (3) an integer value specifying the number of response time components. My question is as follows: are there any possibilities to make the custom function more efficient, for instance by vectorizing it?
Here is the function:
fenton_stan <- "
functions {
row_vector fenton1(vector m, vector s, int D) {
matrix[D,D] term1;
matrix[D,D] term2;
row_vector[2] out;
for(i in 1:D) {
for(j in 1:D) {
term1[i,j] = m[i] + m[j];
term2[i,j] = s[i] + s[j];
}
}
out = [2*log_sum_exp(m + 0.5 * s)-0.5*log_sum_exp(term1 + 0.5 * term2 + diag_matrix(s)),
sqrt(log_sum_exp(term1 + 0.5 * term2 + diag_matrix(s))-2*log_sum_exp(m + 0.5 * s))];
return(out);
}
}
"
rstan::expose_stan_functions(rstan::stanc(model_code = fenton1_stan))
example in Cobb & Rumi (2012); result is correct!
fenton1(m = c(rep(0.69,5)), s = c(rep(1.074^2,5)), D = 5)
The loop is essentially equivalent to outer(m, m, FUN = '+')
in R.
Any help/suggestions appreciated. If you need more information, please let me know.
Best wishes
Chris