• Skip to content
  • Skip to link menu
KDE 4.7 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KDECore

krandomsequence.cpp
Go to the documentation of this file.
00001 /*
00002   This file is part of the KDE libraries
00003   Copyright (c) 1999 Sean Harmer <sh@astro.keele.ac.uk>
00004 
00005   This library is free software; you can redistribute it and/or
00006   modify it under the terms of the GNU Library General Public
00007   License as published by the Free Software Foundation; either
00008   version 2 of the License, or (at your option) any later version.
00009 
00010   This library is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013   Library General Public License for more details.
00014 
00015   You should have received a copy of the GNU Library General Public License
00016   along with this library; see the file COPYING.LIB.  If not, write to
00017   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018   Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "krandomsequence.h"
00022 #include "krandom.h"
00023 
00024 static const int s_nShuffleTableSize = 32;
00025 
00026 class KRandomSequence::Private
00027 {
00028 public:
00029   // Generate the random number
00030   void draw();
00031 
00032   long lngSeed1;
00033   long lngSeed2;
00034   long lngShufflePos;
00035   long shuffleArray[s_nShuffleTableSize];
00036 };
00037 
00039 //  Construction / Destruction
00041 
00042 KRandomSequence::KRandomSequence( long lngSeed1 ) : d(new Private)
00043 {
00044   // Seed the generator
00045   setSeed( lngSeed1 );
00046 }
00047 
00048 KRandomSequence::~KRandomSequence()
00049 {
00050    delete d;
00051 }
00052 
00053 KRandomSequence::KRandomSequence(const KRandomSequence &a) : d(new Private)
00054 {
00055     *d = *a.d;
00056 }
00057 
00058 KRandomSequence & KRandomSequence::operator=(const KRandomSequence &a)
00059 {
00060     if ( this != &a ) {
00061         *d = *a.d;
00062     }
00063     return *this;
00064 }
00065 
00066 
00068 //  Member Functions
00070 
00071 void KRandomSequence::setSeed( long lngSeed1 )
00072 {
00073   // Convert the positive seed number to a negative one so that the draw()
00074   // function can intialise itself the first time it is called. We just have
00075   // to make sure that the seed used != 0 as zero perpetuates itself in a
00076   // sequence of random numbers.
00077   if ( lngSeed1 < 0 )
00078   {
00079     d->lngSeed1 = -1;
00080   }
00081   else if (lngSeed1 == 0)
00082   {
00083     d->lngSeed1 = -((KRandom::random() & ~1)+1);
00084   }
00085   else
00086   {
00087     d->lngSeed1 = -lngSeed1;
00088   }
00089 }
00090 
00091 static const long sMod1           = 2147483563;
00092 static const long sMod2           = 2147483399;
00093 
00094 void KRandomSequence::Private::draw()
00095 {
00096   static const long sMM1            = sMod1 - 1;
00097   static const long sA1             = 40014;
00098   static const long sA2             = 40692;
00099   static const long sQ1             = 53668;
00100   static const long sQ2             = 52774;
00101   static const long sR1             = 12211;
00102   static const long sR2             = 3791;
00103   static const long sDiv            = 1 + sMM1 / s_nShuffleTableSize;
00104 
00105   // Long period (>2 * 10^18) random number generator of L'Ecuyer with
00106   // Bayes-Durham shuffle and added safeguards. Returns a uniform random
00107   // deviate between 0.0 and 1.0 (exclusive of the endpoint values). Call
00108   // with a negative number to initialize; thereafter, do not alter idum
00109   // between successive deviates in a sequence. RNMX should approximate
00110   // the largest floating point value that is less than 1.
00111 
00112   int j; // Index for the shuffle table
00113   long k;
00114 
00115   // Initialise
00116   if ( lngSeed1 <= 0 )
00117   {
00118     lngSeed2 = lngSeed1;
00119 
00120     // Load the shuffle table after 8 warm-ups
00121     for ( j = s_nShuffleTableSize + 7; j >= 0; --j )
00122     {
00123       k = lngSeed1 / sQ1;
00124       lngSeed1 = sA1 * ( lngSeed1 - k*sQ1) - k*sR1;
00125       if ( lngSeed1 < 0 )
00126       {
00127         lngSeed1 += sMod1;
00128       }
00129 
00130       if ( j < s_nShuffleTableSize )
00131       {
00132     shuffleArray[j] = lngSeed1;
00133       }
00134     }
00135 
00136     lngShufflePos = shuffleArray[0];
00137   }
00138 
00139   // Start here when not initializing
00140 
00141   // Compute lngSeed1 = ( lngIA1*lngSeed1 ) % lngIM1 without overflows
00142   // by Schrage's method
00143   k = lngSeed1 / sQ1;
00144   lngSeed1 = sA1 * ( lngSeed1 - k*sQ1 ) - k*sR1;
00145   if ( lngSeed1 < 0 )
00146   {
00147     lngSeed1 += sMod1;
00148   }
00149 
00150   // Compute lngSeed2 = ( lngIA2*lngSeed2 ) % lngIM2 without overflows
00151   // by Schrage's method
00152   k = lngSeed2 / sQ2;
00153   lngSeed2 = sA2 * ( lngSeed2 - k*sQ2 ) - k*sR2;
00154   if ( lngSeed2 < 0 )
00155   {
00156     lngSeed2 += sMod2;
00157   }
00158 
00159   j = lngShufflePos / sDiv;
00160   lngShufflePos = shuffleArray[j] - lngSeed2;
00161   shuffleArray[j] = lngSeed1;
00162 
00163   if ( lngShufflePos < 1 )
00164   {
00165     lngShufflePos += sMM1;
00166   }
00167 }
00168 
00169 void
00170 KRandomSequence::modulate(int i)
00171 {
00172   d->lngSeed2 -= i;
00173   if ( d->lngSeed2 < 0 )
00174   {
00175     d->lngShufflePos += sMod2;
00176   }
00177   d->draw();
00178   d->lngSeed1 -= i;
00179   if ( d->lngSeed1 < 0 )
00180   {
00181     d->lngSeed1 += sMod1;
00182   }
00183   d->draw();
00184 }
00185 
00186 double
00187 KRandomSequence::getDouble()
00188 {
00189   static const double finalAmp         = 1.0 / double( sMod1 );
00190   static const double epsilon          = 1.2E-7;
00191   static const double maxRand          = 1.0 - epsilon;
00192   double temp;
00193   d->draw();
00194   // Return a value that is not one of the endpoints
00195   if ( ( temp = finalAmp * d->lngShufflePos ) > maxRand )
00196   {
00197     // We don't want to return 1.0
00198     return maxRand;
00199   }
00200   else
00201   {
00202     return temp;
00203   }
00204 }
00205 
00206 unsigned long
00207 KRandomSequence::getLong(unsigned long max)
00208 {
00209   d->draw();
00210 
00211   return max ? (((unsigned long) d->lngShufflePos) % max) : 0;
00212 }
00213 
00214 bool
00215 KRandomSequence::getBool()
00216 {
00217   d->draw();
00218 
00219   return (((unsigned long) d->lngShufflePos) & 1);
00220 }

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.5
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal