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-06] 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 <cstdlib>
00070 #include <iostream>
00071 #include <vector>
00072 using namespace std;
00073 
00074 #define PI 3.1415926
00075 #define INTEGRALSTEP 1000
00076 #define BigValue 900000000
00077 #define BigValue2 50000
00078 #define NormalizeBase 10  
00079 //if you are generating more than 100,000,000 random number, use randomB 
00080 class Random
00081 {
00082  public:
00083   Random()  : initNum_(0) {}
00084   ~Random() {}
00085 
00086     // Initialize with a negative integer. Call this only once.
00087   void init(const long& initNum)
00088   {    
00089     if (initNum_ < 0)
00090     {
00091       cout << "WARNING: you can only call Random::init() once. Ignoring call."
00092            << endl;
00093       return;
00094     }
00095 
00096     if (initNum >= 0) 
00097     { 
00098       cout << "Random::init() expects a negative number but is given " 
00099            << initNum << endl;
00100       exit(-1);
00101     }
00102 
00103     initNum_ = initNum;
00104     
00105 
00106     num2_ = 123456789;
00107     a_ = 0;
00108 
00109     randomA(&initNum_);
00110     //randomB(&initNum_);
00111   }
00112   
00113 
00114     //0 < number returned < 1
00115   double random() 
00116   {
00117     return randomA(&initNum_);
00118     //return randomB(&initNum_);
00119   }
00120 
00121 
00122   int randomOneOf(const int& a) { return (int) (a * random()); }
00123 
00124 
00125  private:
00126   double randomA(long* initNum)
00127   {
00128     int c;
00129     long d;
00130     double tmp;
00131     
00132     if (*initNum <= 0 || !a_) 
00133     {
00134       if (-(*initNum) < 1) 
00135         *initNum = 1;
00136       else 
00137         *initNum = -(*initNum);
00138       
00139       for (c = 32+7; c >= 0; c--) 
00140       {
00141         d = (*initNum)/127773;
00142         *initNum = 16807 * (*initNum - d*127773) - 2836*d;
00143         
00144         if (*initNum < 0) 
00145           *initNum += 2147483647;
00146         
00147         if (c < 32)
00148           b_[c] = *initNum;
00149       }
00150       a_ = b_[0];
00151     }
00152     d = (*initNum)/127773;
00153     *initNum = 16807 * (*initNum - d*127773) - 2836*d;
00154     if (*initNum < 0) 
00155       *initNum += 2147483647;
00156     c = a_ / (1 + (2147483647-1)/ 32);
00157     a_ = b_[c];
00158     b_[c] = *initNum;
00159     if ((tmp = (1.0/2147483647)*a_) > (1.0 - 1.2e-7)) 
00160       return (1.0 - 1.2e-7);
00161     else 
00162       return tmp;
00163   }
00164 
00165 
00166   double randomB(long* initNum)
00167   {
00168     int c;
00169     long d;
00170     double tmp;
00171     
00172     if (*initNum <= 0) 
00173     {
00174       if (-(*initNum) < 1) 
00175         *initNum = 1;
00176       else 
00177         *initNum = -(*initNum);
00178       
00179       num2_ = (*initNum);
00180       
00181       for (c = 32+7; c >= 0; c--) 
00182       {
00183         d = (*initNum)/53668;
00184         *initNum = 40014 * (*initNum-d*53668) - d*12211;
00185         
00186         if (*initNum < 0) 
00187           *initNum += 2147483563;
00188         
00189         if (c < 32) 
00190           b_[c] = *initNum;
00191       }
00192       a_ = b_[0];
00193     }
00194     
00195     d = (*initNum)/53668;
00196     *initNum = 40014 * (*initNum-d*53668) - d*12211;
00197     if (*initNum < 0) *initNum += 2147483563;
00198     d = num2_/52774;
00199     num2_ = 40692 * (num2_-d*52774) - d*3791;
00200     if (num2_ < 0) 
00201       num2_ += 2147483399;
00202     c = a_ / (1 + (2147483563-1)/32);
00203    a_ = b_[c] - num2_;
00204    b_[c] = *initNum;
00205    if (a_ < 1) a_ += (2147483563-1);
00206    if ((tmp = (1.0/2147483563)*a_) > (1.0 - 1.2e-7)) 
00207      return (1.0 - 1.2e-7);
00208    else 
00209      return tmp;
00210   }
00211 
00212   
00213  private:
00214   long initNum_;
00215   long num2_;
00216   long a_;
00217   long b_[32];
00218 
00219 };
00220 
00221 class ExtRandom
00222 {
00223 public:
00224 
00225         // Generate random numbers uniform distribution in [0,1] -U[0,1]
00226         static double uniformRandom();
00227 
00228         // Generate Gaussian Random Numbers with mean 'mu' and standard deviation 'sd'
00229         static double gaussRandom(double mu, double sd);
00230 
00231         // Generate Exponential Random Numbers with parameter of 'lambda'.
00232         static double expRandom(double lambda);
00233 
00234         // compute gaussian value at x with mu and sigma
00235         static double ComputeGauss(double mu, double sigma, double x);
00236 
00237         // compute log-gaussian value at x with mu and sigam
00238         static double ComputeLnGauss(double mu, double sigma, double v1, double v2, double x);
00239 
00240         // compute integration on [v1,v2] with mu and sigma
00241         static double GaussianIntegral(double mu, double sigma, double v1, double v2);
00242 
00243         // train gaussian parameters
00244         static void GaussianParaLearning(double &mu, double &sigma, double &v1, double &v2, vector<double> Tdata);
00245 
00246 
00247 private:
00248         static bool deviate_available;
00249         static double second_deviate;
00250 };
00251 
00252 
00253 #endif

Generated on Sun Jun 7 11:55:21 2009 for Alchemy by  doxygen 1.5.1