Hello everyone, I’m trying to fit a new model with a custom likelihood. I’m sharing a toy example to get some tips on improving efficiency.
- Is there a more efficient way to have a different likelihood for each chosen option rather than using “if”?
- Is my usage of the complex number is the way to go?
Thanks a lot!
Ido
functions {
real custom_likelihood(real rt, real lambda, real d, real sigma,
real theta, int choice) {
real P_L = 1 - normal_cdf(lambda - d | 0, sigma);
real P_S = normal_cdf(-lambda - d | 0, sigma);
real P_C = 1 - P_L - P_S;
real result;
complex z = 0 + 1i;
if (choice == 1) {
result = get_real((P_S / (theta * sqrt(P_C))) * exp(-rt / theta)
* ((exp(rt * sqrt(P_C) / theta))
- cos(z * rt * sqrt(P_C) / theta)));
} else if (choice == 2) {
result = get_real((P_L / (theta * sqrt(P_C))) * exp(-rt / theta)
* ((exp(rt * sqrt(P_C) / theta))
- cos(z * rt * sqrt(P_C) / theta)));
} else {
return 0; // Default return in case choice is invalid
}
return result;
}
}
data {
int<lower=1> Nsubjects; //number of subjects
int<lower=1> Nblocks;
int<lower=1> Ntrials; // Number of observations
array[Nsubjects, Ntrials] real<lower=0> rts; // Response times
array[Nsubjects, Ntrials] real<lower=0> d; // Constant d
array[Nsubjects, Ntrials] real<lower=0> sigma; // Constant sigma
array[Nsubjects, Ntrials] real<lower=0> theta; // Constant theta
array[Nsubjects, Ntrials] int<lower=1, upper=2> choices; // Choice array (1 or 2 for each observation)
}
parameters {
array[Nsubjects] real<lower=0> lambda; // Parameter to estimate
}
model {
lambda ~ uniform(0, 4);
for (subject in 1 : Nsubjects) {
for (trial in 1 : Ntrials) {
target += custom_likelihood(rts[subject, trial], lambda[subject],
d[subject, trial], sigma[subject, trial],
theta[subject, trial],
choices[subject, trial]);
}
}
}