flintlib / arb

Arb has been merged into FLINT -- use https://github.com/flintlib/flint/ instead
http://arblib.org/
GNU Lesser General Public License v2.1
456 stars 137 forks source link

Uniformly distributed random numbers #365

Closed albinahlback closed 3 years ago

albinahlback commented 3 years ago

Arb doesn't seem to have this functionality (which is natural given its number theoretic orientation), so I added the functionality for it (and hopefully correctly).

Please have in mind that this is basically my first time doing something in C, so let me know if something is wrong or could be improved.

fredrik-johansson commented 3 years ago

I agree this is a very useful feature, but the implementation needs work:

I think what you really want to do here is (in principle) sample a uniformly random real number from [0, 1), in the case of arf_t round to the nearest floating-point number in the prescribed rounding mode, and in the case of arb_t return an enclosure (which in practice always will be nonexact since exact dyadic numbers have measure zero). It's a bit tricky to do this in a mathematically rigorous way. You can have a look at how MPFR does it.

In practice, I'd perhaps just generate a uniformly random integer n with prec+128 bits and arf_set_round or arb_set_round the result to n*2^(-prec-128) with a precision of prec bits. This isn't theoretically perfectly uniform, but the deviation from ideal randomness would be completely negligible.

albinahlback commented 3 years ago

Thank you for your comments, Fredrik!

Yes, after some writing on paper, I now think that I understand how one can derive the proper distribution for such a random number (even though I did not write down an explicit formula for the mantissa). It seems like your suggested would be faster in either case, so I revised the code accordingly.

fredrik-johansson commented 3 years ago

I don't see the utility of arb_randtest_uniform returning a ball with random midpoint in [0,1) and random radius in [0,1). Do you have a use case for this? What I meant was to use exactly the same algorithm as arf_randtest_uniform but with arb_set_round_fmpz instead of arf_set_round_fmpz, so that you get an accurate ball representing a random real number in [0,1).

More comments:

peteroupc commented 3 years ago

My notes on uniformly distributed random numbers:

There is a closely related concept to arbitrary-precision uniform random numbers. Specifically, these numbers represent uniformly distributed random variates with an arbitrary number of fractional digits that are sampled on demand.

They were called "u-rands" by C.F.F. Karney in "Sampling exactly from a normal distribution", 2016, as well as the "geometric bag" by Flajolet et al., "On Buffon machines and numbers", 2010/2011. I call them "partially-sampled random numbers".

For example, take the following number: [2, [1, 3, 8]]. This represents a random number in the interval [2.138, 2.139]. As the need arises, we can sample additional digits uniformly at random, so that, for example, the number can become [2, [1, 3, 8, 7, 5]], bringing the number in the interval [2.13875, 2.13876]. Karney's paper, for example, uses this format in an algorithm to sample normally distributed variates to arbitrary precision and without calculating any transcendental functions.

albinahlback commented 3 years ago

Thanks for the patience, Fredrik.

I made a test for the arb one, which seems to pass. The current test should fail if it goes beyond one percent deviation from the "supposed" mean value 1/2 and variance 1/12.

fredrik-johansson commented 3 years ago

Thanks for keeping up the work :-)

albinahlback commented 3 years ago
* Put your own name instead of mine in the copyright notices in the new files

Are you sure? I have changed it in the new files, but unlike you I was not blessed with an ASCII-compatible Swedish name haha.

fredrik-johansson commented 3 years ago

At least your name is googleable. I share mine with death metal singers, bandy players, and at least two other scientists ;-)

All right, this looks good enough to merge. I will maybe make some minor changes later.