I am trying to adapt some of Kruschke’s code into Stan and cannot reproduce the following.
# JAGS code
for ( i in 1:NxBetweenLvl ) {
for ( j in 1:NxWithinLvl ) {
mBxW[i,j] <- ( sum( mSxBxW[1:NxSubjectLvl,i,j] ) / sum( mSxBxW[1:NxSubjectLvl,i,j]!=0 ) )
}
}
Note that mSxBxW[,,]
is a three-dimentional array defined upstream.
What does the function in the loop do? Is it "sum of cells 1:NxSubectLvl
in dimensions i
and j
in array mSxBxW[,,]
divided by sum of the total number of non-zero cells across cells 1:NxSubectLvl
in dimension i
and j
? Is that right?
And how would i reproduce this in Stan?
If I use this code in the same place in my Stan script…
// Stan Code
for (i in 1:nGroup) {
for (j in 1:nCond) {
mGxC[i,j] = sum(mSxCxG[1:nSubj,i,j]) / sum( mSxCxG[1:nSubj,i,j]!=0 );
}
}
… it throws the error
Binary infix operator != with functional interpretation logical_neq requires arguments or primitive type (int or real), found left type=real[], right arg type=int;
Which means nothing to me, other than there is something about the !=
operator that works in JAGS but not in Stan.
Hey!
I think the error basically means, that the != operator is not “vectorized” in the way it is in R for example (or apparently in JAGS). Note that is says that it found real[]
but requires on both sides int
or real
– notice that the brackets are missing, implying that it doesn’t know what to do with an array of reals.
Hm… probably not the most elegant thing, but does something like this work?
real temp_sum = 0.0;
for (i in 1:nGroup) {
for (j in 1:nCond) {
for (n in 1:nSubj) {
temp_sum += mGxC[n,i,j] != 0 ? 1.0 : 0.0; // loop over nSubj and add 1 to temp_sum if its != 0
}
mGxC[i,j] = sum(mSxCxG[1:nSubj,i,j]) / temp_sum;
temp_sum = 0.0; // reset for next iteration
}
}
1 Like
Thank you so much for the suggestions @Max_Mantel. Can you explain to me what you are doing here? Like what is happening in the temp_sum
line? And what do the +=
and ?
do? These are very Stan-specific operators and I don’t really understand them yet.
Sure. Nothing really special here. The +=
operator is quite common I think, but it’s not in R. It is basically short hand for a = a + b
which becomes a += b
. Since the !=
operator is not “vectorized” we need to loop. And the sum operation is basically just addition, when using a loop. However, we need some place to store the intermediate values when summing (adding) inside the loop: I’ve just called that temp_sum
because it temporarily saves the sum of non zero entries. We need to initialize that temporary variable with a zero, though, because otherwise the first +=
wouldn’t know what to do (a = a + b
is kinda meaningless if you don’t know a
).
The condition ? true : false
syntax is also just a short-hand for a more mundane ifelse.
Hope that this clarifies everything. Sorry for not being as precise in my first post.
2 Likes