Skip to content

std::rand: implement the Gamma distribution #10223

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 2, 2013
Merged

Conversation

huonw
Copy link
Member

@huonw huonw commented Nov 1, 2013

Implements the Gamma distribution, using the algorithm described by Marsaglia & Tsang 2000[1]. I added tests checking that the mean and variance of this implementation is as expected for a range of values of the parameters in huonw/random-tests@5d87c00 (they pass locally, but obviously won't even build on Travis until this is merged).

Also, moves std::rand::distributions to a subfolder, and performs a minor clean-up of the benchmarking (makes the number of iterations shared by the whole std::rand subtree).

[1]: George Marsaglia and Wai Wan Tsang. 2000. "A Simple Method for Generating Gamma Variables" ACM Trans. Math. Softw. 26, 3 (September 2000), 363-372. DOI:10.1145/358407.358414.

@huonw
Copy link
Member Author

huonw commented Nov 1, 2013

The Gamma distribution is pretty fundamental, and it actually opens the way for extremely short implementations of a variety of other reasonably common distributions (for most, the actual sampling implementation is a line or two of arithmetic, so the largest part of the code will be the documentation & tests). Such distributions include:

  • Chi-squared
  • F
  • Beta
  • Student's t

I'm not sure how many of these are desired to be in libstd, but as some points of reference: C++11 (and Boost) has all of the above but Beta, and Python's stdlib has only Beta. (Personally, I'd say all, since they are literally some simple arithmetic done to one or two of the other distributions (once this lands) in std::rand::distributions.)

bors added a commit that referenced this pull request Nov 2, 2013
Implements the [Gamma distribution](https://en.wikipedia.org/wiki/Gamma_distribution), using the algorithm described by Marsaglia & Tsang 2000[1]. I added tests checking that the mean and variance of this implementation is as expected for a range of values of the parameters in huonw/random-tests@5d87c00 (they pass locally, but obviously won't even build on Travis until this is merged).

Also, moves `std::rand::distributions` to a subfolder, and performs a minor clean-up of the benchmarking (makes the number of iterations shared by the whole `std::rand` subtree).

[1]: George Marsaglia and Wai Wan Tsang. 2000. "A Simple Method for Generating Gamma Variables" *ACM Trans. Math. Softw.* 26, 3 (September 2000), 363-372. DOI:[10.1145/358407.358414](http://doi.acm.org/10.1145/358407.358414).
@bors bors closed this Nov 2, 2013
@bors bors merged commit 3c25baa into rust-lang:master Nov 2, 2013
@huonw huonw deleted the gamma branch November 2, 2013 02:49
assert!(scale > 0.0, "Gamma::new called with scale <= 0");

match shape {
1.0 => One(Exp::new(1.0 / scale)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you do equality testing on a floating point value like this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, floats can be compared for equality, it just doesn't give exactly the answer one would expect in every situation, but it still gives sane & deterministic results, e.g.:

>>> 1 + 0.1 - 1 == 0.1
False
>>> 1.0 == 1.0
True

However, in this case this optimisation is only valid when shape is exactly 1, i.e. it will be triggered by a call like Gamma::new(1.0, 2.0), so this is fine (doing an approximation like if (shape - 1.0).abs() < 1e-5 would mean that Gamma::new(1.000001, 1.0) does not have the Gamma(1.000001, 1) distribution, i.e. it is incorrect).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants