On 10/18/12 9:08 PM, Marcus Brubaker wrote:
> My general belief is that if the behaviour of a function can be consistently well defined then there's no need to throw
> an exception. In most cases in stan there are no practical differences between the two cases for the domain of PDFs,
> but throwing exceptions reduces flexibility.
Let's say it's differently abled flexibility-wise.
The exception makes it easier to report an edge case
likely arising due to an error. In general, exceptions
are nicely flexible if you want to throw from multiple
functions and have a single catcher higher up.
In effect, our rejection for -inf or NaN values has the
same effect as the catch clause higher up, so the
exceptions aren't buying us much other than error reporting
and early termination (though I haven't looked into how.
The boundary return makes it easier to do arithmetic.
I think the case you give next is a good example!
Returning NaN or -inf should be at least as fast as
try/catch -- I started reading up on try/catch overhead
and quickly got in deeper than I wanted to. I think
the answer is that if the other ops are expensive, try/catch
isn't that expensive if there's no catch, but it is some overhead
in tracking state.
> For instance, consider trying implement a mixture model where the
> components of the mixture have different supports. E.G.,
>
> p(x) = w_0 N(x|mu,sigma) + w_1 Beta(x|a,b) + w_3 Uniform(x|-1,0)
>
> I'm not saying this is a common use case, but if a call to beta_log(x,a,b) throws an exception when x is outside of
> [0,1] then it would be hard (if not impossible) to implement it without a lot of extra work. In contrast if beta_log
> returns -inf then it could be done in a relatively straightforward manner.
This is a good example of where you can go to infinity and
back again:
log_sum_exp( log(w_0) + normal_log(x,mu,sigma),
log(w_1) + beta_log(x,a,b),
log(w_3) + uniform_log(x|-1,0) );
If any of the terms to log_sum_exp is -inf, it just gets
dropped, becase exp(-inf) = 0.
> For distribution parameters I think exceptions make more sense because you could inadvertently get an improper prior in
> some cases and in many cases it's hard if not impossible to define things consistently.
This is where Matt was arguing before we should have symmetry
between the errors thrown by:
normal_log(y, mu, sigma)
normal_log(0, y - mu, sigma);
normal_log(0, (y - mu)/sigma, 1);
- Bob