xref: /netbsd-src/external/lgpl3/mpfr/dist/src/random_deviate.c (revision cef8759bd76c1b621f8eab8faa6f208faabc2e15)
1 /* random_deviate routines for mpfr_erandom and mpfr_nrandom.
2 
3 Copyright 2013-2018 Free Software Foundation, Inc.
4 Contributed by Charles Karney <charles@karney.com>, SRI International.
5 
6 This file is part of the GNU MPFR Library.
7 
8 The GNU MPFR Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 The GNU MPFR Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16 License for more details.
17 
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22 
23 /*
24  * A mpfr_random_deviate represents the initial portion e bits of a random
25  * deviate uniformly distributed in (0,1) as
26  *
27  *  typedef struct {
28  *    unsigned long e;            // bits in the fraction
29  *    unsigned long h;            // the high W bits of the fraction
30  *    mpz_t f;                    // the rest of the fraction
31  *  } mpfr_random_deviate_t[1];
32  *
33  * e is always a multiple of RANDOM_CHUNK.  The first RANDOM_CHUNK bits, the
34  * high fraction, are held in an unsigned long, h, and the rest are held in an
35  * mpz_t, f.  The data in h is undefined if e == 0 and, similarly the data in f
36  * is undefined if e <= RANDOM_CHUNK.
37  */
38 
39 #define MPFR_NEED_LONGLONG_H
40 #include "random_deviate.h"
41 
42 /*
43  * RANDOM_CHUNK can be picked in the range 1 <= RANDOM_CHUNK <= 64.  Low values
44  * of RANDOM_CHUNK are good for testing, since they are more likely to make
45  * bugs obvious.  For portability, pick RANDOM_CHUNK <= 32 (since an unsigned
46  * long may only hold 32 bits).  For reproducibility across platforms,
47  * standardize on RANDOM_CHUNK = 32.
48  *
49  * When RANDOM_CHUNK = 32, this representation largely avoids manipulating
50  * mpz's (until the final cast to an mpfr is done).  In addition
51  * mpfr_random_deviate_less usually entails just a single comparison of
52  * unsigned longs.  In this way, we can stick with the published interface for
53  * extracting portions of an mpz (namely through mpz_tstbit) without hurting
54  * efficiency.
55  */
56 #if !defined(RANDOM_CHUNK)
57 /* note: for MPFR, we could use RANDOM_CHUNK = 32 or 64 according to the
58    number of bits per limb, but we use 32 everywhere to get reproducible
59    results on 32-bit and 64-bit computers */
60 #define RANDOM_CHUNK 32     /* Require 1 <= RANDOM_CHUNK <= 32; recommend 32 */
61 #endif
62 
63 #define W RANDOM_CHUNK         /* W is just an shorter name for RANDOM_CHUNK */
64 
65 /* allocate and set to (0,1) */
66 void
67 mpfr_random_deviate_init (mpfr_random_deviate_t x)
68 {
69   mpz_init (x->f);
70   x->e = 0;
71 }
72 
73 /* reset to (0,1) */
74 void
75 mpfr_random_deviate_reset (mpfr_random_deviate_t x)
76 {
77   x->e = 0;
78 }
79 
80 /* deallocate */
81 void
82 mpfr_random_deviate_clear (mpfr_random_deviate_t x)
83 {
84   mpz_clear (x->f);
85 }
86 
87 /* swap two random deviates */
88 void
89 mpfr_random_deviate_swap (mpfr_random_deviate_t x, mpfr_random_deviate_t y)
90 {
91   mpfr_random_size_t s;
92   unsigned long t;
93 
94   /* swap x->e and y->e */
95   s = x->e;
96   x->e = y->e;
97   y->e = s;
98 
99   /* swap x->h and y->h */
100   t = x->h;
101   x->h = y->h;
102   y->h = t;
103 
104   /* swap x->f and y->f */
105   mpz_swap (x->f, y->f);
106 }
107 
108 /* ensure x has at least k bits */
109 static void
110 random_deviate_generate (mpfr_random_deviate_t x, mpfr_random_size_t k,
111                          gmp_randstate_t r, mpz_t t)
112 {
113   /* Various compile time checks on mprf_random_deviate_t */
114 
115   /* Check that the h field of a mpfr_random_deviate_t can hold W bits */
116   MPFR_STAT_STATIC_ASSERT (W > 0 && W <= sizeof (unsigned long) * CHAR_BIT);
117 
118   /* Check mpfr_random_size_t can hold 32 bits and a mpfr_uprec_t.  This
119    * ensures that max(mpfr_random_size_t) exceeds MPFR_PREC_MAX by at least
120    * 2^31 because mpfr_prec_t is a signed version of mpfr_uprec_t.  This allows
121    * random deviates with many leading zeros in the fraction to be handled
122    * correctly. */
123   MPFR_STAT_STATIC_ASSERT (sizeof (mpfr_random_size_t) * CHAR_BIT >= 32 &&
124                            sizeof (mpfr_random_size_t) >=
125                            sizeof (mpfr_uprec_t));
126 
127   /* Finally, at runtime, check that k is not too big.  e is set to ceil(k/W)*W
128    * and we require that this allows x->e + 1 in random_deviate_leading_bit to
129    * be computed without overflow. */
130   MPFR_ASSERTN (k <= (mpfr_random_size_t)(-((int) W + 1)));
131 
132   /* if t is non-null, it is used as a temporary */
133   if (x->e >= k)
134     return;
135 
136   if (x->e == 0)
137     {
138       x->h = gmp_urandomb_ui (r, W); /* Generate the high fraction */
139       x->e = W;
140       if (x->e >= k)
141         return;    /* Maybe that's it? */
142     }
143 
144   if (t)
145     {
146       /* passed a mpz_t so compute needed bits in one call to mpz_urandomb */
147       k = ((k + (W-1)) / W) * W;  /* Round up to multiple of W */
148       k -= x->e;                  /* The number of new bits */
149       mpz_urandomb (x->e == W ? x->f : t, r, k); /* Copy directly to x->f? */
150       if (x->e > W)
151         {
152           mpz_mul_2exp (x->f, x->f, k);
153           mpz_add (x->f, x->f, t);
154         }
155       x->e += k;
156     }
157   else
158     {
159       /* no mpz_t so compute the bits W at a time via gmp_urandomb_ui */
160       while (x->e < k)
161         {
162           unsigned long w = gmp_urandomb_ui (r, W);
163           if (x->e == W)
164             mpz_set_ui (x->f, w);
165           else
166             {
167               mpz_mul_2exp (x->f, x->f, W);
168               mpz_add_ui (x->f, x->f, w);
169             }
170           x->e += W;
171         }
172     }
173 }
174 
175 /*
176  * return index [-1..127] of highest bit set.  Return -1 if x = 0, 2 if x = 4,
177  * etc.  (From Algorithms for programmers by Joerg Arndt.)
178  */
179 static int
180 highest_bit_idx_alt (unsigned long x)
181 {
182   int r = 0;
183 
184   if (x == 0)
185     return -1;
186   MPFR_ASSERTN (sizeof (unsigned long) * CHAR_BIT <= 128);
187   if (sizeof (unsigned long) * CHAR_BIT > 64)
188     {
189       /* handle 128-bit unsigned longs avoiding compiler warnings */
190       unsigned long y = x >> 16; y >>= 24; y >>= 24;
191       if (y) { x = y; r += 64;}
192     }
193   if (x & ~0xffffffffUL) { x >>= 16; x >>= 16; r +=32; }
194   if (x &  0xffff0000UL) { x >>= 16; r += 16; }
195   if (x &  0x0000ff00UL) { x >>=  8; r +=  8; }
196   if (x &  0x000000f0UL) { x >>=  4; r +=  4; }
197   if (x &  0x0000000cUL) { x >>=  2; r +=  2; }
198   if (x &  0x00000002UL) {           r +=  1; }
199   return r;
200 }
201 
202 /*
203  * return index [-1..63] of highest bit set.
204  * Return -1 if x = 0, 63 is if x = ~0 (for 64-bit unsigned long).
205  * See highest_bit_idx_alt too.
206  */
207 static int
208 highest_bit_idx (unsigned long x)
209 {
210   /* this test should be evaluated at compile time */
211   if (sizeof (mp_limb_t) >= sizeof (unsigned long))
212     {
213       int cnt;
214 
215       if (x == 0)
216         return -1;
217       count_leading_zeros (cnt, (mp_limb_t) x);
218       MPFR_ASSERTD (cnt <= GMP_NUMB_BITS - 1);
219       return GMP_NUMB_BITS - 1 - cnt;
220     }
221   else
222     return highest_bit_idx_alt (x);
223 }
224 
225 /* return position of leading bit, counting from 1 */
226 static mpfr_random_size_t
227 random_deviate_leading_bit (mpfr_random_deviate_t x, gmp_randstate_t r)
228 {
229   mpfr_random_size_t l;
230   random_deviate_generate (x, W, r, 0);
231   if (x->h)
232     return W - highest_bit_idx (x->h);
233   random_deviate_generate (x, 2 * W, r, 0);
234   while (mpz_sgn (x->f) == 0)
235     random_deviate_generate (x, x->e + 1, r, 0);
236   l = x->e + 1 - mpz_sizeinbase (x->f, 2);
237   /* Guard against a ridiculously long string of leading zeros in the fraction;
238    * probability of this happening is 2^(-2^31).  In particular ensure that
239    * p + 1 + l in mpfr_random_deviate_value doesn't overflow with p =
240    * MPFR_PREC_MAX. */
241   MPFR_ASSERTN (l + 1 < (mpfr_random_size_t)(-MPFR_PREC_MAX));
242   return l;
243 }
244 
245 /* return kth bit of fraction, representing 2^-k */
246 int
247 mpfr_random_deviate_tstbit (mpfr_random_deviate_t x, mpfr_random_size_t k,
248                             gmp_randstate_t r)
249 {
250   if (k == 0)
251     return 0;
252   random_deviate_generate (x, k, r, 0);
253   if (k <= W)
254     return (x->h >> (W - k)) & 1UL;
255   return mpz_tstbit (x->f, x->e - k);
256 }
257 
258 /* compare two random deviates, x < y */
259 int
260 mpfr_random_deviate_less (mpfr_random_deviate_t x, mpfr_random_deviate_t y,
261                           gmp_randstate_t r)
262 {
263   mpfr_random_size_t k = 1;
264 
265   if (x == y)
266     return 0;
267   random_deviate_generate (x, W, r, 0);
268   random_deviate_generate (y, W, r, 0);
269   if (x->h != y->h)
270     return x->h < y->h; /* Compare the high fractions */
271   k += W;
272   for (; ; ++k)
273     {             /* Compare the rest of the fraction bit by bit */
274       int a = mpfr_random_deviate_tstbit (x, k, r);
275       int b = mpfr_random_deviate_tstbit (y, k, r);
276       if (a != b)
277         return a < b;
278     }
279 }
280 
281 /* set mpfr_t z = (neg ? -1 : 1) * (n + x) */
282 int
283 mpfr_random_deviate_value (int neg, unsigned long n,
284                            mpfr_random_deviate_t x, mpfr_t z,
285                            gmp_randstate_t r, mpfr_rnd_t rnd)
286 {
287   /* r is used to add as many bits as necessary to match the precision of z */
288   int s;
289   mpfr_random_size_t l;                     /* The leading bit is 2^(s*l) */
290   mpfr_random_size_t p = mpfr_get_prec (z); /* Number of bits in result */
291   mpz_t t;
292   int inex;
293 
294   if (n == 0)
295     {
296       s = -1;
297       l = random_deviate_leading_bit (x, r); /* l > 0 */
298     }
299   else
300     {
301       s = 1;
302       l = highest_bit_idx (n); /* l >= 0 */
303     }
304 
305   /*
306    * Leading bit is 2^(s*l); thus the trailing bit in result is 2^(s*l-p+1) =
307    * 2^-(p-1-s*l).  For the sake of illustration, take l = 0 and p = 4, thus
308    * bits through the 1/8 position need to be generated; assume that these bits
309    * are 1.010 = 10/8 which represents a deviate in the range (10,11)/8.
310    *
311    * If the rounding mode is one of RNDZ, RNDU, RNDD, RNDA, we add a 1 bit to
312    * the result to give 1.0101 = (10+1/2)/8.  When this is converted to a MPFR
313    * the result is rounded to 10/8, 11/8, 10/8, 11/8, respectively, and the
314    * inexact flag is set to -1, 1, -1, 1.
315    *
316    * If the rounding mode is RNDN, an additional random bit must be generated
317    * to determine if the result is in (10,10+1/2)/8 or (10+1/2,11)/8.  Assume
318    * that this random bit is 0, so the result is 1.0100 = (10+0/2)/8.  Then an
319    * additional 1 bit is added to give 1.010101 = (10+1/4)/8.  This last bit
320    * avoids the "round ties to even rule" (because there are no ties) and sets
321    * the inexact flag so that the result is 10/8 with the inexact flag = 1.
322    *
323    * Here we always generate at least 2 additional random bits, so that bit
324    * position 2^-(p+1-s*l) is generated.  (The result often contains more
325    * random bits than this because random bits are added in batches of W and
326    * because additional bits may have been required in the process of
327    * generating the random deviate.)  The integer and all the bits in the
328    * fraction are then copied into an mpz, the least significant bit is
329    * unconditionally set to 1, the sign is set, and the result together with
330    * the exponent -x->e is used to generate an mpfr using mpfr_set_z_2exp.
331    *
332    * If random bits were very expensive, we would only need to generate to the
333    * 2^-(p-1-s*l) bit (no extra bits) for the RNDZ, RNDU, RNDD, RNDA modes and
334    * to the 2^-(p-s*l) bit (1 extra bit) for RNDN.  By always generating 2 bits
335    * we save on some bit shuffling when formed the mpz to be converted to an
336    * mpfr.  The implementation of the RandomNumber class in RandomLib
337    * illustrates the more parsimonious approach (which was taken to allow
338    * accurate counts of the number of random digits to be made).
339    */
340   mpz_init (t);
341   /*
342    * This is the only call to random_deviate_generate where a mpz_t is passed
343    * (because an arbitrarily large number of bits may need to be generated).
344    */
345   if ((s > 0 && p + 1 > l) ||
346       (s < 0 && p + 1 + l > 0))
347     random_deviate_generate (x, s > 0 ? p + 1 - l : p + 1 + l, r, t);
348   if (n == 0)
349     {
350       /* Since the minimum prec is 2 we know that x->h has been generated. */
351       mpz_set_ui (t, x->h);        /* Set high fraction */
352     }
353   else
354     {
355       mpz_set_ui (t, n);           /* The integer part */
356       if (x->e > 0)
357         {
358           mpz_mul_2exp (t, t, W);    /* Shift to allow for high fraction */
359           mpz_add_ui (t, t, x->h);   /* Add high fraction */
360         }
361     }
362   if (x->e > W)
363     {
364       mpz_mul_2exp (t, t, x->e - W); /* Shift to allow for low fraction */
365       mpz_add (t, t, x->f);          /* Add low fraction */
366     }
367   /*
368    * We could trim off any excess bits here by shifting rightward.  This is an
369    * unnecessary complication.
370    */
371   mpz_setbit (t, 0);     /* Set the trailing bit so result is always inexact */
372   if (neg)
373     mpz_neg (t, t);
374   /* Is -x->e representable as a mpfr_exp_t? */
375   MPFR_ASSERTN (x->e <= (mpfr_uexp_t)(-1) >> 1);
376   /*
377    * Let mpfr_set_z_2exp do all the work of rounding to the requested
378    * precision, setting overflow/underflow flags, and returning the right
379    * inexact value.
380    */
381   inex = mpfr_set_z_2exp (z, t, -x->e, rnd);
382   mpz_clear (t);
383   return inex;
384 }
385