On 3/28/13 4:59 PM, Michael Betancourt wrote:
> The breaking up the files was also on my mind. Do we want to keep to a strict one class/one file schema or can I put VERY related classes together. The only example I can think of right now would be unit_metric_hmc and adapt_unit_metric_hmc, since the latter is only a small extension of the first.
Now that we've started doing it elsewhere, I like one
class per file. (Maybe it's my java background.) It makes
the arrangement of dependencies and testing easier and it's
easier to browse.
>> Michael is using a very different coding style than the
>> rest of Stan -- how much do we care about this kind of
>> thing? I'd volunteer to restyle it, but I don't want to
>> just do that unilaterally.
>
> Which elements of the style? I tried to stay consistent with the style in the rest of the files,
You've mostly got rid of the open-paren-only lines (thanks!), but there are
still some left.
There was also a big ///// Fortran-style comment
> save for some sparse white space here and there which I had to throw in to quickly identify different blocks of code, and I'm happy to fix things up.
Yes, lots of vertical whitespace, and then
some one-liners like:
ps_point(int n, int m): q(n), r(m), p(Eigen::VectorXd::Zero(n)) {};
I think you're also the only one who starts argument lists on the
next line even when there's plenty of horizontal space left:
hmc_base<M, P, H, I, BaseRNG>::hmc_base(
M &m,
BaseRNG& rng)
Overall, our style hasn't been very consistent. So there's not much
of a target.
I sort of like the way you lay out constructors with the
semicolon on the previous line.
> I did shed a tear every time I had to delete a linebreak between a if/for and the opening brace.
It saved me just as many, so thanks.
>> What's the acceptance statistic and why is it part of a sample?
>> Isn't acceptance a property of a proposal sample relative to
>> a previous sample?
>
> If we think of each "sample" as actually a transition in a Markov chain then the acceptance statistic (acceptance probability in the Metropolis case, tree-sampling probability in the NUTS case) is an important element of the sample. On a more practical side, it's important to pass along for adaptation and helpful for diagnostics (for example right now we only implicitly use the mean of this statistic, assuming that the stepsize adaptation has converged, but the variance can also be useful in diagnosing wacky geometries).
That's what I suspected.
Conceptually, I don't think an acceptance probability is
part of a sample per se. As you point out, its interpretation
and contents is going to be very sampler specific. If we
had an exact sampler then there wouldn't even be an acceptance
statistic.
In Metropolis, accept probability is a relation between two
parameter configurations.
There's also the issue of "sample" vs. potential sample.
And we wound up standardizing on "draw" in the external doc
because of the exact vs. MCMC sampling and the notion of
effective sample size.
If everything we have now has some use for it and it's easy
enough to generalize, we can always refactor later. I'd
actually rather wait until we have a need to refactor than
to do it on spec in the hopes of anticipating something we
haven't implemented yet.
>> I'm ok with using "cont"/"disc" instead of "real"/"int",
>> but it should be consistent. (Yes, I realize it's all discrete
>> floating point reps underneath for reals, but Andrew 1 didn't
>> like "double", which is how I originally had it.)
>
> cont/disc seemed much more natural without adding too many characters. Was there anywhere in the mcmc code that I failed to keep things consistent, or are you referring to the model code?
Just the model code. No, the MCMC code's consistent.
It's not a huge problem if it doesn't match the other
code. I had inconsistencies in the code because we
changed the original "double" to "real" at some point,
so a lot of the internals still say "double". I always
find it a bit confusing. But no big deal.
>> Would it be useful to generalize away from teh normal
>> distribution for generating momenta? (I realize a fatter
>> tailed proposal doesn't help much, but it seems an easy
>> thing to generalize if it'll ever be needed for eval, etc.)
>
> This was one place where I compromised because I didn't fully understand Boost's RNG and I couldn't imagine anyone trying non-quadratic kinetic energies anytime soon. I'd like to keep the Hamiltonians stateless, so would this be acceptable?
Sure. See above -- we can always generalize later if
we need it. Boost's RNG isn't object oriented, it's
concept oriented, which is why you have to always template
out the RNG rather than provide some kind of base class
reference argument type.
> - Pass the rand_int to sample_p by reference.
> - Create the random distribution on the fly to generate variates inline.
>
> The only issue is how expensive the random distribution construction is.
You pay a constructor overhead, but it's cheap because there's
not much data -- just the parameters of the distribution. They
do check bounds on the parameters, though (like that variance is
positive and the mean is finite).
>> What's the purpose of defining templated member functions
>> outside of the class? (And I didn't mean that question
>> rhetorically --- I'm genuinely curious.)
>
> Just habit from the h/cpp days. I can put them back in if that's at all preferable.
We might as well do them all one way or the other. Some were
defined in the classes and some outside. I like them inside,
but I think that's another Java holdover for me. I can see
the elegance of just having the header part defined. It's just
with templates we can't really separate the declarations and
definitions.
I have been thinking about compile efficiency. For that,
with templated code, we need explicit instantiations to compile
and link against and header files to include. But let's worry
about that after this refactor because it's orthogonal functionally.
>> mcmc/chains.hpp
>> ---------------
>> This doesn't look like it's changed much, but we should get rid of
>> that block of comments at the bottom. If they're to-do items,
>> they should go on the to-do list.
>
> Didn't actually touch this guy yet, but I'll clean it up.
>
>> Do you really need setters or could you get away with a rich
>> constructor? I'd greatly prefer the latter because it's easier
>> to reason about the consistency of state with immutable objects.
>> Then you can get rid of the setters and make the member variables
>> private. If you do allow setters, there needs to be a check on
>> consistent values (such as some of these values being required
>> to be finite and positive).
>
> Personally I prefer clear constructors and settings because I prefer using the objects in a create/tweak schema.
> But here I'd actually fight for explicit setters, as it would allow for multi-stage adaptation
> without creating new instances.
New instances are cheap. Managing state's a headache.
Whatever you think's best here.
If you keep the mutable desgin, please add checks for consistency
on any public setters. You can provide extra methods for friends
if you need to. We really need to do this in other places in the code.
- Bob