VectorBuilder and int types

[edit] Can’t instantiate this template:

template int bernoulli_logit_rng(const double&);

for function signature

int bernoulli_logit_rng(real)

I was on the wrong track below. But still wondering how VectorBuilder works - why can’t this function return an int?

I think it’s interesting (and neat if annoying for my current task) that our bernoulli_logit_rng(const double&) returns a short (and can’t be made to return an int despite the signature in the manual stating its signature is int bernoulli_logit_rng(real)). I can’t find how that happens in the code - it seems to return typename VectorBuilder<true, int, T_t>::type. In fact, the word short only appears 4 times in our code, and two of those are in comments.

Anyone know how this works?

[edit] I just realized that I should have said how I figured this out, because maybe that is where I’m going wrong. After compiling a model using this, you can inspect it with nm to see which symbols it exports:

00000001000519b0 unsigned short stan::VectorBuilder<true, int, double, double, double, double, double, double>::type stan::math::bernoulli_logit_rng<double, boost::random::additive_combine_engine<boost::random::linear_congruential_engine<unsigned int, 40014u, 0u, 2147483563u>, boost::random::linear_congruential_engine<unsigned int, 40692u, 0u, 2147483399u> > >(double const&, boost::random::additive_combine_engine<boost::random::linear_congruential_engine<unsigned int, 40014u, 0u, 2147483563u>, boost::random::linear_congruential_engine<unsigned int, 40692u, 0u, 2147483399u> >&)

So I suppose the compiler could be making this optimization somehow. But I also can’t get an explicit template instantiation to compile for this signature:

math.cpp:1059:14: error: explicit instantiation of 'bernoulli_logit_rng' does not refer to a function
      template, variable template, member function, member class, or static data member
template int bernoulli_logit_rng(const double&);
             ^
lib/stan_math/stan/math/prim/scal/prob/bernoulli_logit_rng.hpp:30:53: note: candidate template
      ignored: failed template argument deduction
inline typename VectorBuilder<true, int, T_t>::type bernoulli_logit_rng(
    const T_t& t, RNG& rng) {

[edit 2] - that “unsigned short” actually seems spurious!

@bbbales Do you know what VectorBuilder is for? I see most of the RNG’s use it and not much else uses it for return values at least.

My two cents can explain only some of this.

Most of the RNGs can now take non-scalar arguments, bernoulli_logit_rng included. When they do take any non-scalar arguments they return an array matching the size of the non-scalar arguments. VectorBuilder matches the return type dependent on the argument size and type.

unsigned short is still a mystery to me, especially since I feel like I can follow that int from VectorBuilder<true, int, T_t>::type all the way down.

Are you referencing an old manual? In functions-reference of the stan-dev/stan:develop branch the signature’s documentation should read

R bernoulli_logit_rng(reals alpha).

R is explained in Section 10.8.3.

I think the short was spurious - output from nm that was not really relevant to the mission. My bad.

I think I see what’s going on, thanks for the pointer to R! This is super helpful - I think I can use the file where R is used instead of the other one I was generating for type signatures and get a lot more out of it. Thanks!

Thanks for the explanation, @er.

VectorBuilder is used for intermediate values in our _lpdf functions—see, e.g., normal_lpdf.

We should never be generating unsigned short types from the Stan language (other than maybe internally inside functions).