- Random123-1.09 Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# Random123/MicroURNG.hpp

Go to the documentation of this file.

    00001 /*
    00002 Copyright 2010-2011, D. E. Shaw Research.
    00003 All rights reserved.
    00004
    00005 Redistribution and use in source and binary forms, with or without
    00006 modification, are permitted provided that the following conditions are
    00007 met:
    00008
    00009 * Redistributions of source code must retain the above copyright
    00010   notice, this list of conditions, and the following disclaimer.
    00011
    00012 * Redistributions in binary form must reproduce the above copyright
    00013   notice, this list of conditions, and the following disclaimer in the
    00014   documentation and/or other materials provided with the distribution.
    00015
    00016 * Neither the name of D. E. Shaw Research nor the names of its
    00017   contributors may be used to endorse or promote products derived from
    00018   this software without specific prior written permission.
    00019
    00020 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    00021 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    00022 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    00023 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    00024 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    00025 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    00026 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    00027 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    00028 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    00029 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    00030 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00031 */
    00032 #ifndef __MicroURNG_dot_hpp__
    00033 #define __MicroURNG_dot_hpp__
    00034
    00035 #include <stdexcept>
    00036 #include <limits>
    00037
    00038 namespace r123{
    00078 template<typename CBRNG>
    00079 class MicroURNG{
    00080     // According to C++0x, a URNG requires only a result_type,
    00081     // operator()(), min() and max() methods.  Everything else
    00082     // (ctr_type, key_type, reset() method, etc.) is "value added"
    00083     // for the benefit of users that "know" that they're dealing with
    00084     // a MicroURNG.
    00085 public:
    00086     typedef CBRNG cbrng_type;
    00087     static const int BITS = 32;
    00088     typedef typename cbrng_type::ctr_type ctr_type;
    00089     typedef typename cbrng_type::key_type key_type;
    00090     typedef typename cbrng_type::ukey_type ukey_type;
    00091     typedef typename ctr_type::value_type result_type;
    00092
    00093     R123_STATIC_ASSERT( std::numeric_limits<result_type>::digits >= BITS, "The result_type must have at least 32 bits" );
    00094
    00095     result_type operator()(){
    00096         if(last_elem == 0){
    00097             // jam n into the high bits of c
    00098             const size_t W = std::numeric_limits<result_type>::digits;
    00099             ctr_type c = c0;
    00100             c[c0.size()-1] |= n<<(W-BITS);
    00101             rdata = b(c,k);
    00102             n++;
    00103             last_elem = rdata.size();
    00104         }
    00105         return rdata[--last_elem];
    00106     }
    00107     MicroURNG(cbrng_type _b, ctr_type _c0, ukey_type _uk) : b(_b), c0(_c0), k(_uk), n(0), last_elem(0) {
    00108         chkhighbits();
    00109     }
    00110     MicroURNG(ctr_type _c0, ukey_type _uk) : b(), c0(_c0), k(_uk), n(0), last_elem(0) {
    00111         chkhighbits();
    00112     }
    00113
    00114     // _Min and _Max work around a bug in the library shipped with MacOS Xcode 4.5.2.
    00115     // See the commment in conventional/Engine.hpp.
    00116     const static result_type _Min = 0;
    00117     const static result_type _Max = ~((result_type)0);
    00118
    00119     static R123_CONSTEXPR result_type min R123_NO_MACRO_SUBST () { return _Min; }
    00120     static R123_CONSTEXPR result_type max R123_NO_MACRO_SUBST () { return _Max; }
    00121     // extra methods:
    00122     const ctr_type& counter() const{ return c0; }
    00123     void reset(ctr_type _c0, ukey_type _uk){
    00124         c0 = _c0;
    00125         chkhighbits();
    00126         k = _uk;
    00127         n = 0;
    00128         last_elem = 0;
    00129     }
    00130
    00131 private:
    00132     cbrng_type b;
    00133     ctr_type c0;
    00134     key_type k;
    00135     R123_ULONG_LONG n;
    00136     size_t last_elem;
    00137     ctr_type rdata;
    00138     void chkhighbits(){
    00139         result_type r = c0[c0.size()-1];
    00140         result_type mask = ((uint64_t)std::numeric_limits<result_type>::max R123_NO_MACRO_SUBST ())>>BITS;
    00141         if((r&mask) != r)
    00142             throw std::runtime_error("MicroURNG: c0, does not have high bits clear");
    00143     }
    00144 };
    00145 } // namespace r123
    00146 #endif

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines