random.h

00001 /*
00002  * All of the documentation and software included in the
00003  * Alchemy Software is copyrighted by Stanley Kok, Parag
00004  * Singla, Matthew Richardson, Pedro Domingos, Marc
00005  * Sumner and Hoifung Poon.
00006  * 
00007  * Copyright [2004-07] Stanley Kok, Parag Singla, Matthew
00008  * Richardson, Pedro Domingos, Marc Sumner and Hoifung
00009  * Poon. All rights reserved.
00010  * 
00011  * Contact: Pedro Domingos, University of Washington
00012  * (pedrod@cs.washington.edu).
00013  * 
00014  * Redistribution and use in source and binary forms, with
00015  * or without modification, are permitted provided that
00016  * the following conditions are met:
00017  * 
00018  * 1. Redistributions of source code must retain the above
00019  * copyright notice, this list of conditions and the
00020  * following disclaimer.
00021  * 
00022  * 2. Redistributions in binary form must reproduce the
00023  * above copyright notice, this list of conditions and the
00024  * following disclaimer in the documentation and/or other
00025  * materials provided with the distribution.
00026  * 
00027  * 3. All advertising materials mentioning features or use
00028  * of this software must display the following
00029  * acknowledgment: "This product includes software
00030  * developed by Stanley Kok, Parag Singla, Matthew
00031  * Richardson, Pedro Domingos, Marc Sumner and Hoifung
00032  * Poon in the Department of Computer Science and
00033  * Engineering at the University of Washington".
00034  * 
00035  * 4. Your publications acknowledge the use or
00036  * contribution made by the Software to your research
00037  * using the following citation(s): 
00038  * Stanley Kok, Parag Singla, Matthew Richardson and
00039  * Pedro Domingos (2005). "The Alchemy System for
00040  * Statistical Relational AI", Technical Report,
00041  * Department of Computer Science and Engineering,
00042  * University of Washington, Seattle, WA.
00043  * http://www.cs.washington.edu/ai/alchemy.
00044  * 
00045  * 5. Neither the name of the University of Washington nor
00046  * the names of its contributors may be used to endorse or
00047  * promote products derived from this software without
00048  * specific prior written permission.
00049  * 
00050  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF WASHINGTON
00051  * AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00052  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00053  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00054  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY
00055  * OF WASHINGTON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00056  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00057  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00058  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00059  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00060  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00061  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00062  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00063  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00064  * 
00065  */
00066 #ifndef RANDOM_H_JUN_21_2005
00067 #define RANDOM_H_JUN_21_2005
00068 
00069 #include <iostream>
00070 using namespace std;
00071 
00072   //if you are generating more than 100,000,000 random number, use randomB 
00073 class Random
00074 {
00075  public:
00076   Random()  : initNum_(0) {}
00077   ~Random() {}
00078 
00079     // Initialize with a negative integer. Call this only once.
00080   void init(const long& initNum)
00081   {    
00082     if (initNum_ < 0)
00083     {
00084       cout << "WARNING: you can only call Random::init() once. Ignoring call."
00085            << endl;
00086       return;
00087     }
00088 
00089     if (initNum >= 0) 
00090     { 
00091       cout << "Random::init() expects a negative number but is given " 
00092            << initNum << endl;
00093       exit(-1);
00094     }
00095 
00096     initNum_ = initNum;
00097     
00098 
00099     num2_ = 123456789;
00100     a_ = 0;
00101 
00102     randomA(&initNum_);
00103     //randomB(&initNum_);
00104   }
00105   
00106 
00107     //0 < number returned < 1
00108   float random() 
00109   {
00110     return randomA(&initNum_);
00111     //return randomB(&initNum_);
00112   }
00113 
00114 
00115   int randomOneOf(const int& a) { return (int) (a * random()); }
00116 
00117 
00118  private:
00119   float randomA(long* initNum)
00120   {
00121     int c;
00122     long d;
00123     float tmp;
00124     
00125     if (*initNum <= 0 || !a_) 
00126     {
00127       if (-(*initNum) < 1) 
00128         *initNum = 1;
00129       else 
00130         *initNum = -(*initNum);
00131       
00132       for (c = 32+7; c >= 0; c--) 
00133       {
00134         d = (*initNum)/127773;
00135         *initNum = 16807 * (*initNum - d*127773) - 2836*d;
00136         
00137         if (*initNum < 0) 
00138           *initNum += 2147483647;
00139         
00140         if (c < 32)
00141           b_[c] = *initNum;
00142       }
00143       a_ = b_[0];
00144     }
00145     d = (*initNum)/127773;
00146     *initNum = 16807 * (*initNum - d*127773) - 2836*d;
00147     if (*initNum < 0) 
00148       *initNum += 2147483647;
00149     c = a_ / (1 + (2147483647-1)/ 32);
00150     a_ = b_[c];
00151     b_[c] = *initNum;
00152     if ((tmp = (1.0/2147483647)*a_) > (1.0 - 1.2e-7)) 
00153       return (1.0 - 1.2e-7);
00154     else 
00155       return tmp;
00156   }
00157 
00158 
00159   float randomB(long* initNum)
00160   {
00161     int c;
00162     long d;
00163     float tmp;
00164     
00165     if (*initNum <= 0) 
00166     {
00167       if (-(*initNum) < 1) 
00168         *initNum = 1;
00169       else 
00170         *initNum = -(*initNum);
00171       
00172       num2_ = (*initNum);
00173       
00174       for (c = 32+7; c >= 0; c--) 
00175       {
00176         d = (*initNum)/53668;
00177         *initNum = 40014 * (*initNum-d*53668) - d*12211;
00178         
00179         if (*initNum < 0) 
00180           *initNum += 2147483563;
00181         
00182         if (c < 32) 
00183           b_[c] = *initNum;
00184       }
00185       a_ = b_[0];
00186     }
00187     
00188     d = (*initNum)/53668;
00189     *initNum = 40014 * (*initNum-d*53668) - d*12211;
00190     if (*initNum < 0) *initNum += 2147483563;
00191     d = num2_/52774;
00192     num2_ = 40692 * (num2_-d*52774) - d*3791;
00193     if (num2_ < 0) 
00194       num2_ += 2147483399;
00195     c = a_ / (1 + (2147483563-1)/32);
00196    a_ = b_[c] - num2_;
00197    b_[c] = *initNum;
00198    if (a_ < 1) a_ += (2147483563-1);
00199    if ((tmp = (1.0/2147483563)*a_) > (1.0 - 1.2e-7)) 
00200      return (1.0 - 1.2e-7);
00201    else 
00202      return tmp;
00203   }
00204 
00205   
00206  private:
00207   long initNum_;
00208   long num2_;
00209   long a_;
00210   long b_[32];
00211 
00212 };
00213 
00214 
00215 #endif

Generated on Tue Jan 16 05:30:05 2007 for Alchemy by  doxygen 1.5.1