Home | History | Annotate | Download | only in utils
      1 /*
      2  * Copyright 2006 The Android Open Source Project
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkRandom_DEFINED
      9 #define SkRandom_DEFINED
     10 
     11 #include "SkScalar.h"
     12 
     13 /** \class SkLCGRandom
     14 
     15     Utility class that implements pseudo random 32bit numbers using a fast
     16     linear equation. Unlike rand(), this class holds its own seed (initially
     17     set to 0), so that multiple instances can be used with no side-effects.
     18 */
     19 class SkLCGRandom {
     20 public:
     21     SkLCGRandom() : fSeed(0) {}
     22     SkLCGRandom(uint32_t seed) : fSeed(seed) {}
     23 
     24     /** Return the next pseudo random number as an unsigned 32bit value.
     25     */
     26     uint32_t nextU() { uint32_t r = fSeed * kMul + kAdd; fSeed = r; return r; }
     27 
     28     /** Return the next pseudo random number as a signed 32bit value.
     29     */
     30     int32_t nextS() { return (int32_t)this->nextU(); }
     31 
     32     /** Return the next pseudo random number as an unsigned 16bit value.
     33     */
     34     U16CPU nextU16() { return this->nextU() >> 16; }
     35 
     36     /** Return the next pseudo random number as a signed 16bit value.
     37     */
     38     S16CPU nextS16() { return this->nextS() >> 16; }
     39 
     40     /**
     41      *  Returns value [0...1) as a float
     42      */
     43     float nextF() {
     44         // const is 1 / (2^32 - 1)
     45         return (float)(this->nextU() * 2.32830644e-10);
     46     }
     47 
     48     /**
     49      *  Returns value [min...max) as a float
     50      */
     51     float nextRangeF(float min, float max) {
     52         return min + this->nextF() * (max - min);
     53     }
     54 
     55     /** Return the next pseudo random number, as an unsigned value of
     56         at most bitCount bits.
     57         @param bitCount The maximum number of bits to be returned
     58     */
     59     uint32_t nextBits(unsigned bitCount) {
     60         SkASSERT(bitCount > 0 && bitCount <= 32);
     61         return this->nextU() >> (32 - bitCount);
     62     }
     63 
     64     /** Return the next pseudo random unsigned number, mapped to lie within
     65         [min, max] inclusive.
     66     */
     67     uint32_t nextRangeU(uint32_t min, uint32_t max) {
     68         SkASSERT(min <= max);
     69         uint32_t range = max - min + 1;
     70         if (0 == range) {
     71             return this->nextU();
     72         } else {
     73             return min + this->nextU() % range;
     74         }
     75     }
     76 
     77     /** Return the next pseudo random unsigned number, mapped to lie within
     78         [0, count).
     79      */
     80     uint32_t nextULessThan(uint32_t count) {
     81         SkASSERT(count > 0);
     82         return this->nextRangeU(0, count - 1);
     83     }
     84 
     85     /** Return the next pseudo random number expressed as an unsigned SkFixed
     86         in the range [0..SK_Fixed1).
     87     */
     88     SkFixed nextUFixed1() { return this->nextU() >> 16; }
     89 
     90     /** Return the next pseudo random number expressed as a signed SkFixed
     91         in the range (-SK_Fixed1..SK_Fixed1).
     92     */
     93     SkFixed nextSFixed1() { return this->nextS() >> 15; }
     94 
     95     /** Return the next pseudo random number expressed as a SkScalar
     96         in the range [0..SK_Scalar1).
     97     */
     98     SkScalar nextUScalar1() { return SkFixedToScalar(this->nextUFixed1()); }
     99 
    100     /** Return the next pseudo random number expressed as a SkScalar
    101         in the range [min..max).
    102     */
    103     SkScalar nextRangeScalar(SkScalar min, SkScalar max) {
    104         return this->nextUScalar1() * (max - min) + min;
    105     }
    106 
    107     /** Return the next pseudo random number expressed as a SkScalar
    108         in the range (-SK_Scalar1..SK_Scalar1).
    109     */
    110     SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); }
    111 
    112     /** Return the next pseudo random number as a bool.
    113     */
    114     bool nextBool() { return this->nextU() >= 0x80000000; }
    115 
    116     /** A biased version of nextBool().
    117      */
    118     bool nextBiasedBool(SkScalar fractionTrue) {
    119         SkASSERT(fractionTrue >= 0 && fractionTrue <= SK_Scalar1);
    120         return this->nextUScalar1() <= fractionTrue;
    121     }
    122 
    123     /**
    124      *  Return the next pseudo random number as a signed 64bit value.
    125      */
    126     int64_t next64() {
    127         int64_t hi = this->nextS();
    128         return (hi << 32) | this->nextU();
    129     }
    130 
    131     /**
    132      *  Return the current seed. This allows the caller to later reset to the
    133      *  same seed (using setSeed) so it can generate the same sequence.
    134      */
    135     int32_t getSeed() const { return fSeed; }
    136 
    137     /** Set the seed of the random object. The seed is initialized to 0 when the
    138         object is first created, and is updated each time the next pseudo random
    139         number is requested.
    140     */
    141     void setSeed(int32_t seed) { fSeed = (uint32_t)seed; }
    142 
    143 private:
    144     //  See "Numerical Recipes in C", 1992 page 284 for these constants
    145     enum {
    146         kMul = 1664525,
    147         kAdd = 1013904223
    148     };
    149     uint32_t fSeed;
    150 };
    151 
    152 /** \class SkRandom
    153 
    154  Utility class that implements pseudo random 32bit numbers using Marsaglia's
    155  multiply-with-carry "mother of all" algorithm. Unlike rand(), this class holds
    156  its own state, so that multiple instances can be used with no side-effects.
    157 
    158  Has a large period and all bits are well-randomized.
    159  */
    160 class SkRandom {
    161 public:
    162     SkRandom() { init(0); }
    163     SkRandom(uint32_t seed) { init(seed); }
    164     SkRandom(const SkRandom& rand) : fK(rand.fK), fJ(rand.fJ) {}
    165 
    166     SkRandom& operator=(const SkRandom& rand) {
    167         fK = rand.fK;
    168         fJ = rand.fJ;
    169 
    170         return *this;
    171     }
    172 
    173     /** Return the next pseudo random number as an unsigned 32bit value.
    174      */
    175     uint32_t nextU() {
    176         fK = kKMul*(fK & 0xffff) + (fK >> 16);
    177         fJ = kJMul*(fJ & 0xffff) + (fJ >> 16);
    178         return (((fK << 16) | (fK >> 16)) + fJ);
    179     }
    180 
    181     /** Return the next pseudo random number as a signed 32bit value.
    182      */
    183     int32_t nextS() { return (int32_t)this->nextU(); }
    184 
    185     /** Return the next pseudo random number as an unsigned 16bit value.
    186      */
    187     U16CPU nextU16() { return this->nextU() >> 16; }
    188 
    189     /** Return the next pseudo random number as a signed 16bit value.
    190      */
    191     S16CPU nextS16() { return this->nextS() >> 16; }
    192 
    193     /**
    194      *  Returns value [0...1) as an IEEE float
    195      */
    196     float nextF() {
    197         unsigned int floatint = 0x3f800000 | (this->nextU() >> 9);
    198         float f = SkBits2Float(floatint) - 1.0f;
    199         return f;
    200     }
    201 
    202     /**
    203      *  Returns value [min...max) as a float
    204      */
    205     float nextRangeF(float min, float max) {
    206         return min + this->nextF() * (max - min);
    207     }
    208 
    209     /** Return the next pseudo random number, as an unsigned value of
    210      at most bitCount bits.
    211      @param bitCount The maximum number of bits to be returned
    212      */
    213     uint32_t nextBits(unsigned bitCount) {
    214         SkASSERT(bitCount > 0 && bitCount <= 32);
    215         return this->nextU() >> (32 - bitCount);
    216     }
    217 
    218     /** Return the next pseudo random unsigned number, mapped to lie within
    219      [min, max] inclusive.
    220      */
    221     uint32_t nextRangeU(uint32_t min, uint32_t max) {
    222         SkASSERT(min <= max);
    223         uint32_t range = max - min + 1;
    224         if (0 == range) {
    225             return this->nextU();
    226         } else {
    227             return min + this->nextU() % range;
    228         }
    229     }
    230 
    231     /** Return the next pseudo random unsigned number, mapped to lie within
    232      [0, count).
    233      */
    234     uint32_t nextULessThan(uint32_t count) {
    235         SkASSERT(count > 0);
    236         return this->nextRangeU(0, count - 1);
    237     }
    238 
    239     /** Return the next pseudo random number expressed as an unsigned SkFixed
    240      in the range [0..SK_Fixed1).
    241      */
    242     SkFixed nextUFixed1() { return this->nextU() >> 16; }
    243 
    244     /** Return the next pseudo random number expressed as a signed SkFixed
    245      in the range (-SK_Fixed1..SK_Fixed1).
    246      */
    247     SkFixed nextSFixed1() { return this->nextS() >> 15; }
    248 
    249     /** Return the next pseudo random number expressed as a SkScalar
    250      in the range [0..SK_Scalar1).
    251      */
    252     SkScalar nextUScalar1() { return SkFixedToScalar(this->nextUFixed1()); }
    253 
    254     /** Return the next pseudo random number expressed as a SkScalar
    255      in the range [min..max).
    256      */
    257     SkScalar nextRangeScalar(SkScalar min, SkScalar max) {
    258         return this->nextUScalar1() * (max - min) + min;
    259     }
    260 
    261     /** Return the next pseudo random number expressed as a SkScalar
    262      in the range (-SK_Scalar1..SK_Scalar1).
    263      */
    264     SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); }
    265 
    266     /** Return the next pseudo random number as a bool.
    267      */
    268     bool nextBool() { return this->nextU() >= 0x80000000; }
    269 
    270     /** A biased version of nextBool().
    271      */
    272     bool nextBiasedBool(SkScalar fractionTrue) {
    273         SkASSERT(fractionTrue >= 0 && fractionTrue <= SK_Scalar1);
    274         return this->nextUScalar1() <= fractionTrue;
    275     }
    276 
    277     /**
    278      *  Return the next pseudo random number as a signed 64bit value.
    279      */
    280     int64_t next64() {
    281         int64_t hi = this->nextS();
    282         return (hi << 32) | this->nextU();
    283     }
    284 
    285     /** Reset the random object.
    286      */
    287     void setSeed(uint32_t seed) { init(seed); }
    288 
    289 private:
    290     // Initialize state variables with LCG.
    291     // We must ensure that both J and K are non-zero, otherwise the
    292     // multiply-with-carry step will forevermore return zero.
    293     void init(uint32_t seed) {
    294         fK = NextLCG(seed);
    295         if (0 == fK) {
    296             fK = NextLCG(fK);
    297         }
    298         fJ = NextLCG(fK);
    299         if (0 == fJ) {
    300             fJ = NextLCG(fJ);
    301         }
    302         SkASSERT(0 != fK && 0 != fJ);
    303     }
    304     static uint32_t NextLCG(uint32_t seed) { return kMul*seed + kAdd; }
    305 
    306     //  See "Numerical Recipes in C", 1992 page 284 for these constants
    307     //  For the LCG that sets the initial state from a seed
    308     enum {
    309         kMul = 1664525,
    310         kAdd = 1013904223
    311     };
    312     // Constants for the multiply-with-carry steps
    313     enum {
    314         kKMul = 30345,
    315         kJMul = 18000,
    316     };
    317 
    318     uint32_t fK;
    319     uint32_t fJ;
    320 };
    321 
    322 #endif
    323