Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#8491 closed Bugs (invalid)

boost::random::discrete_distribution ignores the first element

Reported by: astralstorm@… Owned by: No-Maintainer
Milestone: To Be Determined Component: random
Version: Boost 1.53.0 Severity: Showstopper
Keywords: Cc:

Description

It seems that discrete_distribution can set the first item weight to 0, which should not be possible.

Categorical distribution like this must use all supplied items - of course you use actual weight 0 as a marker of "can't happen", which should be documented.

The attached testcase demonstrates the problem. (As well as shows another one that discrete_distribution can't handle negative weights properly.)

Attachments (1)

randoms.cpp (1.5 KB ) - added by astralstorm@… 9 years ago.
discrete_distribution testcase

Download all attachments as: .zip

Change History (6)

by astralstorm@…, 9 years ago

Attachment: randoms.cpp added

discrete_distribution testcase

comment:1 by Steven Watanabe, 9 years ago

Resolution: invalid
Status: newclosed

Negative weights are not allowed. I have no idea what behavior you expect from this.

"... w_k, commonly known as the weights, shall be non-negative, non-NaN, and non-infinity." (C++11 26.5.8.6.1 [rand.dist.samp.discrete])

comment:2 by anonymous, 9 years ago

Resolution: invalid
Status: closedreopened

The weights are not negative in this testcase - the probs array is actually printed out. Please run the testcase. It offsets them so that they become non-negative.

For negative weights, such a normalization should be done within boost anyway I think, but then the special value would have to be -infty instead of 0 to give probability 0, which is an API change.

comment:3 by Steven Watanabe, 9 years ago

Resolution: invalid
Status: reopenedclosed

You're using invalid iterators in the printing loop. distr.probabilities() returns by value.

After I fix that, I get:

Weights: 126 215 260 265 277 340 415
Probabilities: 0.0663857 0.113277 0.136986 0.139621 0.145943 0.179136 0.218651

comment:4 by AstralStorm, 9 years ago

Thanks, nice catch. It is a bit counterintuitive in terms of API though, I can think of no real use for the by-value semantics here.

comment:5 by Steven Watanabe, 9 years ago

by-value is what the standard specifies. In terms of the Boost implementation, it has to be by-value, because it's computed on the fly. The weights aren't actually stored.

Note: See TracTickets for help on using tickets.