MonteCarloMeasurements.jl icon indicating copy to clipboard operation
MonteCarloMeasurements.jl copied to clipboard

Using Particles{Bool,N} in a conditional

Open millerjoey opened this issue 3 years ago • 5 comments

Thanks for the great package that Chad Scherrer introduced me to!

Currently,

julia> Bernoulli(Particles(10, Uniform()))
ERROR: TypeError: non-boolean (Particles{Bool,10}) used in boolean context

is an error due to the check_args call. You can get around this with Bernoulli(Particles(10, Uniform()), check_args=false), but it would be nice if that weren't needed. Would it be dangerous/too special-cased if a Particles{Bool} with all 1s behaved like a true in a conditional?

millerjoey avatar Aug 13 '20 14:08 millerjoey

Hey! If all of them are true I guess it's safe to let the comparison evaluate to true. I already do that for the < > <= >= operators so it's probably an oversight that == doesn't.

I can draw you attention to the relevant part of the docs that describe the different comparison modes https://baggepinnen.github.io/MonteCarloMeasurements.jl/latest/#Comparison-mode-1 and the perhaps somewhat related PR https://github.com/baggepinnen/MonteCarloMeasurements.jl/pull/78

baggepinnen avatar Aug 13 '20 17:08 baggepinnen

Ah, if it appears as the type Particles in a conditional, I can't make it behave like a boolean without making use of a compiler pass, using Cassette.jl or Irtools. Something has to turn it into a boolean before it appears in the boolean context.

Even more context available in this discussion https://github.com/baggepinnen/MonteCarloMeasurements.jl/issues/22#issuecomment-506769238

baggepinnen avatar Aug 13 '20 17:08 baggepinnen

Oh haha, Chad already ran into this exact issue. I see. I'm not expert enough to mess around with Cassette.jl, but I appreciate how it's not possible without that, or modifying Distributions.jl. I'll have to read #22 more slowly until the rest sinks in. Thanks!

millerjoey avatar Aug 13 '20 17:08 millerjoey

Hi @millerjoey , not sure if we've talked about this before, but lots of Distributions have a check_args keyword argument. From a PPL perspective, it's a bit annoying because it's very hit or miss. But in this case you can do

julia> b = Bernoulli(Particles(Uniform()); check_args=false)
Bernoulli{Particles{Float64,2000}}(
p: 0.5 ± 0.29
)

Note that this works fine:

julia> logpdf(b, true)
Particles{Float64,2000}
 -0.999827 ± 0.999

but rand is no longer systematic:

julia> rand.(b)
Particles{Bool,2000}
 0.136 ± 0.343

The method that's being called here is

rand(rng::AbstractRNG, d::Bernoulli) = rand(rng) <= succprob(d)

so a single random value is tested against each of the ps.

cscherrer avatar Sep 15 '20 21:09 cscherrer

Yeah, I ended up using check_args; I just double-checked and didn't need rand, but thanks for the caveat!

millerjoey avatar Sep 15 '20 21:09 millerjoey