Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!uwvax!oddjob!gargoyle!ihnp4!inuxc!iuvax!pur-ee!uiucdcs!uiucdcsm!grunwald From: grunwald@uiucdcsm.cs.uiuc.edu Newsgroups: comp.lang.c++ Subject: Re: OOPS Message-ID: <4800007@uiucdcsm> Date: Sat, 21-Nov-87 00:42:00 EST Article-I.D.: uiucdcsm.4800007 Posted: Sat Nov 21 00:42:00 1987 Date-Received: Tue, 24-Nov-87 06:34:46 EST References: <4800004@uiucdcsm> Lines: 1918 Nf-ID: #R:uiucdcsm:4800004:uiucdcsm:4800007:000:40356 Nf-From: uiucdcsm.cs.uiuc.edu!grunwald Nov 20 23:42:00 1987 The following is a 'shar' file containing the random number generators I mentioned. As a word of warning, I've implemented these routines from books and used them to determine that they generate reasonable values. I havn't done any further testing on them (I know, ``don't submit untested code''). The references are Knuth, Vol II and Law & Kelton, "Simulation, Modeling and Analysis". These routines may distributed later in a modified form, or may be available with the OOPS library in the future in a different form. In particular, I hope to some day find the time to document the parameters, although they should be obvious if you know what the distribution is. #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh. # The following files will be created: # localSrc/Makefile # localSrc/Binomial.c # localSrc/Erlang.c # localSrc/Geometric.c # localSrc/HyperGeometric.c # localSrc/LogNormal.c # localSrc/NegativeExpntl.c # localSrc/Normal.c # localSrc/Poisson.c # localSrc/Random.c # localSrc/RandomInterval.c # localSrc/RandomRange.c # localSrc/Thread.c # localSrc/Weibull.c # localSrc/Binomial.h # localSrc/Erlang.h # localSrc/Geometric.h # localSrc/HyperGeometric.h # localSrc/LogNormal.h # localSrc/NegativeExpntl.h # localSrc/Normal.h # localSrc/Poisson.h # localSrc/Random.h # localSrc/RandomInterval.h # localSrc/RandomRange.h # localSrc/Thread.h # localSrc/Weibull.h # This archive created: Fri Nov 20 23:32:54 1987 export PATH; PATH=/bin:$PATH if test -f 'localSrc/Makefile' then echo shar: over-writing existing file "'localSrc/Makefile'" fi cat << \SHAR_EOF > 'localSrc/Makefile' CC = CC I = /usr/include/CC INCL=-I../src CCDEBUG = LIB = liboops CFLAGS = ${CCDEBUG} ${INCL} LFLAGS = ${CCDEBUG} ${OOPSLIB} # Target Directories OOPSLIBDIR = /usr/lib OOPSINCDIR = /usr/include/oops OOPSSRCDIR = /usr/local/src/oops OBJ = Random.o Erlang.o Binomial.o Geometric.o HyperGeometric.o \ LogNormal.o NegativeExpntl.o Normal.o Poisson.o RandomInterval.o \ RandomRange.o Weibull.o SRC = Random.c Erlang.c Binomial.c Geometric.c HyperGeometric.c \ LogNormal.c NegativeExpntl.c Normal.c Poisson.c RandomInterval.c \ RandomRange.c Weibull.c HDR = Random.h Erlang.h Binomial.h Geometric.h HyperGeometric.h \ LogNormal.h NegativeExpntl.h Normal.h Poisson.h RandomInterval.h \ RandomRange.h Weibull.h all: $(OBJ) @echo Done install: ar r ${OOPSLIBDIR}/liboops.a $(OBJ) ranlib ${OOPSLIBDIR}/liboops.a cp $(HDR) $(OOPSINCDIR) depend: makedepend -I/usr/include/CC $(INCL) $(SRC) # DO NOT DELETE THIS LINE -- make depend depends on it. Random.o: Random.h ../src/Object.h /usr/include/CC/stdio.h Random.o: /usr/include/CC/stream.h /usr/include/CC/errors.h ../src/oopsIO.h Random.o: /usr/include/CC/string.h /usr/include/CC/osfcn.h Erlang.o: Erlang.h Random.h ../src/Object.h /usr/include/CC/stdio.h Erlang.o: /usr/include/CC/stream.h /usr/include/CC/errors.h ../src/oopsIO.h Erlang.o: /usr/include/CC/string.h /usr/include/CC/osfcn.h Erlang.o: /usr/include/CC/math.h Binomial.o: Binomial.h Random.h ../src/Object.h /usr/include/CC/stdio.h Binomial.o: /usr/include/CC/stream.h /usr/include/CC/errors.h ../src/oopsIO.h Binomial.o: /usr/include/CC/string.h /usr/include/CC/osfcn.h Binomial.o: /usr/include/CC/math.h Geometric.o: Geometric.h Random.h ../src/Object.h /usr/include/CC/stdio.h Geometric.o: /usr/include/CC/stream.h /usr/include/CC/errors.h Geometric.o: ../src/oopsIO.h /usr/include/CC/string.h /usr/include/CC/osfcn.h Geometric.o: /usr/include/CC/math.h HyperGeometric.o: HyperGeometric.h Random.h ../src/Object.h HyperGeometric.o: /usr/include/CC/stdio.h /usr/include/CC/stream.h HyperGeometric.o: /usr/include/CC/errors.h ../src/oopsIO.h HyperGeometric.o: /usr/include/CC/string.h /usr/include/CC/osfcn.h HyperGeometric.o: /usr/include/CC/math.h LogNormal.o: LogNormal.h Normal.h Random.h ../src/Object.h LogNormal.o: /usr/include/CC/stdio.h /usr/include/CC/stream.h LogNormal.o: /usr/include/CC/errors.h ../src/oopsIO.h LogNormal.o: /usr/include/CC/string.h /usr/include/CC/osfcn.h LogNormal.o: /usr/include/CC/math.h NegativeExpntl.o: NegativeExpntl.h Random.h ../src/Object.h NegativeExpntl.o: /usr/include/CC/stdio.h /usr/include/CC/stream.h NegativeExpntl.o: /usr/include/CC/errors.h ../src/oopsIO.h NegativeExpntl.o: /usr/include/CC/string.h /usr/include/CC/osfcn.h NegativeExpntl.o: /usr/include/CC/math.h Normal.o: Normal.h Random.h ../src/Object.h /usr/include/CC/stdio.h Normal.o: /usr/include/CC/stream.h /usr/include/CC/errors.h ../src/oopsIO.h Normal.o: /usr/include/CC/string.h /usr/include/CC/osfcn.h Normal.o: /usr/include/CC/math.h Poisson.o: Poisson.h Random.h ../src/Object.h /usr/include/CC/stdio.h Poisson.o: /usr/include/CC/stream.h /usr/include/CC/errors.h ../src/oopsIO.h Poisson.o: /usr/include/CC/string.h /usr/include/CC/osfcn.h Poisson.o: /usr/include/CC/math.h RandomInterval.o: RandomInterval.h Random.h ../src/Object.h RandomInterval.o: /usr/include/CC/stdio.h /usr/include/CC/stream.h RandomInterval.o: /usr/include/CC/errors.h ../src/oopsIO.h RandomInterval.o: /usr/include/CC/string.h /usr/include/CC/osfcn.h RandomInterval.o: /usr/include/CC/math.h RandomRange.o: RandomRange.h Random.h ../src/Object.h /usr/include/CC/stdio.h RandomRange.o: /usr/include/CC/stream.h /usr/include/CC/errors.h RandomRange.o: ../src/oopsIO.h /usr/include/CC/string.h RandomRange.o: /usr/include/CC/osfcn.h /usr/include/CC/math.h Weibull.o: Weibull.h Random.h ../src/Object.h /usr/include/CC/stdio.h Weibull.o: /usr/include/CC/stream.h /usr/include/CC/errors.h ../src/oopsIO.h Weibull.o: /usr/include/CC/string.h /usr/include/CC/osfcn.h Weibull.o: /usr/include/CC/math.h SHAR_EOF if test -f 'localSrc/Binomial.c' then echo shar: over-writing existing file "'localSrc/Binomial.c'" fi cat << \SHAR_EOF > 'localSrc/Binomial.c' #include "Binomial.h" #include "oopsIO.h" #include #define THIS Binomial #define BASE Random DEFINE_CLASS(Binomial,Random,1,NULL,NULL); Binomial::Binomial(int nn, double uu, long seed, int size) : (seed, size) { n = nn; u = uu; } Binomial::Binomial(fileDescTy& fd, Binomial& where) : (fd, where) { readBin(fd, n); readBin(fd, u); } Binomial::Binomial(istream& s, Binomial& where) : (s, where) { s >> n; s >> u; } double Binomial::asDouble() { int s = 0; for (int i = 0; i < n; i++) { if (Random::drawDouble() < u) { s++; } } return( double(s) ); } obid Binomial::copy() { return shallowCopy(); } void Binomial::deepenShallowCopy() { } void Binomial::printOn(ostream& s) { s << "[ " ; Random::printOn(s); s << n; s << u; s << "]\n"; } void Binomial::storer(fileDescTy& fd) { Random::storer(fd); storeBin(fd, n); storeBin(fd, u); } void Binomial::storer(ostream& s) { Random::storer(s); s << n; s << u; } SHAR_EOF if test -f 'localSrc/Erlang.c' then echo shar: over-writing existing file "'localSrc/Erlang.c'" fi cat << \SHAR_EOF > 'localSrc/Erlang.c' #include "Erlang.h" #include "oopsIO.h" #include #define THIS Erlang #define BASE Random DEFINE_CLASS(Erlang,Random,1,NULL,NULL); Erlang::Erlang(double mean, double variance, long seed, int size) : (seed, size) { k = int( (mean * mean) / variance + 0.5); k = (k > 0) ? k : 1; a = k/mean; } Erlang::Erlang(fileDescTy& fd, Erlang& where) : (fd, where) { readBin(fd, k); readBin(fd, a); } Erlang::Erlang(istream& s, Erlang& where) : (s, where) { s >> k; s >> a; } double Erlang::asDouble() { double prod = 1.0; for (int i = 0; i < k; i++) { prod *= Random::drawDouble(); } return(-log(prod)/a); } obid Erlang::copy() { return shallowCopy(); } void Erlang::deepenShallowCopy() { } void Erlang::printOn(ostream& s) { s << "[ " ; Random::printOn(s); s << k; s << a; s << "]\n"; } void Erlang::storer(fileDescTy& fd) { Random::storer(fd); storeBin(fd, k); storeBin(fd, a); } void Erlang::storer(ostream& s) { Random::storer(s); s << k; s << a; } SHAR_EOF if test -f 'localSrc/Geometric.c' then echo shar: over-writing existing file "'localSrc/Geometric.c'" fi cat << \SHAR_EOF > 'localSrc/Geometric.c' #include "Geometric.h" #include "oopsIO.h" #include #define THIS Geometric #define BASE Random DEFINE_CLASS(Geometric,Random,1,NULL,NULL); Geometric::Geometric(double xmean, long seed, int size) : (seed, size) { mean = xmean; } Geometric::Geometric(fileDescTy& fd, Geometric& where) : (fd, where) { readBin(fd, mean); } Geometric::Geometric(istream& s, Geometric& where) : (s, where) { s >> mean; } double Geometric::asDouble() { int samples; for (samples = 0; Random::drawDouble() < mean; samples++); return((double) samples); } obid Geometric::copy() { return shallowCopy(); } void Geometric::deepenShallowCopy() { } void Geometric::printOn(ostream& s) { s << "[ " ; Random::printOn(s); s << mean; s << "]\n"; } void Geometric::storer(fileDescTy& fd) { Random::storer(fd); storeBin(fd, mean); } void Geometric::storer(ostream& s) { Random::storer(s); s << mean; } SHAR_EOF if test -f 'localSrc/HyperGeometric.c' then echo shar: over-writing existing file "'localSrc/HyperGeometric.c'" fi cat << \SHAR_EOF > 'localSrc/HyperGeometric.c' #include "HyperGeometric.h" #include "oopsIO.h" #include #define THIS HyperGeometric #define BASE Random DEFINE_CLASS(HyperGeometric,Random,1,NULL,NULL); HyperGeometric::HyperGeometric(double uu, double vv, long seed, int size) : (seed, size) { double z = vv / (uu * uu); u = uu; p = 0.5 * (1.0 - sqrt((z - 1.0) / ( z + 1.0 ))); } HyperGeometric::HyperGeometric(fileDescTy& fd, HyperGeometric& where) : (fd, where) { readBin(fd, u); readBin(fd, p); } HyperGeometric::HyperGeometric(istream& s, HyperGeometric& where) : (s, where) { s >> u; s >> p; } double HyperGeometric::asDouble() { double d = (Random::drawDouble() > p) ? (1.0 - p) : (p); return(-u * log(Random::drawDouble()) / (2.0 * d) ); } obid HyperGeometric::copy() { return shallowCopy(); } void HyperGeometric::deepenShallowCopy() { } void HyperGeometric::printOn(ostream& s) { s << "[ " ; Random::printOn(s); s << u; s << p; s << "]\n"; } void HyperGeometric::storer(fileDescTy& fd) { Random::storer(fd); storeBin(fd, u); storeBin(fd, p); } void HyperGeometric::storer(ostream& s) { Random::storer(s); s << u; s << p; } SHAR_EOF if test -f 'localSrc/LogNormal.c' then echo shar: over-writing existing file "'localSrc/LogNormal.c'" fi cat << \SHAR_EOF > 'localSrc/LogNormal.c' #include "LogNormal.h" #include "oopsIO.h" #include #define THIS LogNormal #define BASE Normal DEFINE_CLASS(LogNormal,Normal,1,NULL,NULL); LogNormal::LogNormal(double xmean, double xvariance, long seed, int size) : (xmean, xvariance, seed, size) { /* * We change the mean & variance for our LogNormal. */ double m2 = xmean * xmean; mean = log( m2 / sqrt(variance + m2) ); variance = log( (variance + m2) / m2 ); } LogNormal::LogNormal(fileDescTy& fd, LogNormal& where) : (fd, where) { } LogNormal::LogNormal(istream& s, LogNormal& where) : (s, where) { } /* * See Simulation, Modelling & Analysis by Law & Kelton, pp260 * */ double LogNormal::asDouble() { return( pow(M_E, Normal::asDouble()) ); } obid LogNormal::copy() { return shallowCopy(); } void LogNormal::deepenShallowCopy() { } void LogNormal::printOn(ostream& s) { s << "[ " ; Random::printOn(s); s << mean; s << variance; s << "]\n"; } void LogNormal::storer(fileDescTy& fd) { Random::storer(fd); storeBin(fd, mean); storeBin(fd, variance); } void LogNormal::storer(ostream& s) { Random::storer(s); s << mean; s << variance; } SHAR_EOF if test -f 'localSrc/NegativeExpntl.c' then echo shar: over-writing existing file "'localSrc/NegativeExpntl.c'" fi cat << \SHAR_EOF > 'localSrc/NegativeExpntl.c' #include "NegativeExpntl.h" #include "oopsIO.h" #include #define THIS NegativeExpntl #define BASE Random DEFINE_CLASS(NegativeExpntl,Random,1,NULL,NULL); NegativeExpntl::NegativeExpntl(double xmean, long seed, int size) : (seed, size) { mean = xmean; } NegativeExpntl::NegativeExpntl(fileDescTy& fd, NegativeExpntl& where) : (fd, where) { readBin(fd, mean); } NegativeExpntl::NegativeExpntl(istream& s, NegativeExpntl& where) : (s, where) { s >> mean; } double NegativeExpntl::asDouble() { return(-mean * log(Random::drawDouble())); } obid NegativeExpntl::copy() { return shallowCopy(); } void NegativeExpntl::deepenShallowCopy() { } void NegativeExpntl::printOn(ostream& s) { s << "[ " ; Random::printOn(s); s << mean; s << "]\n"; } void NegativeExpntl::storer(fileDescTy& fd) { Random::storer(fd); storeBin(fd, mean); } void NegativeExpntl::storer(ostream& s) { Random::storer(s); s << mean; } SHAR_EOF if test -f 'localSrc/Normal.c' then echo shar: over-writing existing file "'localSrc/Normal.c'" fi cat << \SHAR_EOF > 'localSrc/Normal.c' #include "Normal.h" #include "oopsIO.h" #include #define THIS Normal #define BASE Random DEFINE_CLASS(Normal,Random,1,NULL,NULL); Normal::Normal(double xmean, double xvariance, long seed, int size) : (seed, size) { mean = xmean; variance = xvariance; haveCachedNormal = 0; } Normal::Normal(fileDescTy& fd, Normal& where) : (fd, where) { readBin(fd, mean); readBin(fd, variance); readBin(fd, haveCachedNormal); readBin(fd, cachedNormal); } Normal::Normal(istream& s, Normal& where) : (s, where) { s >> mean; s >> variance; s >> haveCachedNormal; s >> cachedNormal; } /* * See Simulation, Modelling & Analysis by Law & Kelton, pp259 * * This is the ``polar'' method. */ double Normal::asDouble() { if (haveCachedNormal == 1) { haveCachedNormal = 0; return(cachedNormal * variance + mean ); } else { for(;;) { double u1 = Random::drawDouble(); double u2 = Random::drawDouble(); double v1 = 2 * u1 - 1; double v2 = 2 * u2 - 1; double w = (v1 * v1) + (v2 * v2); /* * We actually generate two IID normal distribution variables. * We cache the one & return the other. */ if (w <= 1) { double y = sqrt( (-2 * log(w)) / w); double x1 = v1 * y; double x2 = v2 * y; haveCachedNormal = 1; cachedNormal = x2; return(x1 * variance + mean); } } } } obid Normal::copy() { return shallowCopy(); } void Normal::deepenShallowCopy() { } void Normal::printOn(ostream& s) { s << "[ " ; Random::printOn(s); s << mean; s << variance; s << haveCachedNormal; s << cachedNormal; s << "]\n"; } void Normal::storer(fileDescTy& fd) { Random::storer(fd); storeBin(fd, mean); storeBin(fd, variance); storeBin(fd, haveCachedNormal); storeBin(fd, cachedNormal); } void Normal::storer(ostream& s) { Random::storer(s); s << mean; s << variance; s << haveCachedNormal; s << cachedNormal; } SHAR_EOF if test -f 'localSrc/Poisson.c' then echo shar: over-writing existing file "'localSrc/Poisson.c'" fi cat << \SHAR_EOF > 'localSrc/Poisson.c' #include "Poisson.h" #include "oopsIO.h" #include #define THIS Poisson #define BASE Random DEFINE_CLASS(Poisson,Random,1,NULL,NULL); Poisson::Poisson(double xmean, long seed, int size) : (seed, size) { mean = xmean; } Poisson::Poisson(fileDescTy& fd, Poisson& where) : (fd, where) { readBin(fd, mean); } Poisson::Poisson(istream& s, Poisson& where) : (s, where) { s >> mean; } double Poisson::asDouble() { double bound = exp(-1.0 * mean); int count = 0; for (double product = 1.0; product >= bound; product *= Random::drawDouble()) { count++; } return(count - 1); } obid Poisson::copy() { return shallowCopy(); } void Poisson::deepenShallowCopy() { } void Poisson::printOn(ostream& s) { s << "[ " ; Random::printOn(s); s << mean; s << "]\n"; } void Poisson::storer(fileDescTy& fd) { Random::storer(fd); storeBin(fd, mean); } void Poisson::storer(ostream& s) { Random::storer(s); s << mean; } SHAR_EOF if test -f 'localSrc/Random.c' then echo shar: over-writing existing file "'localSrc/Random.c'" fi cat << \SHAR_EOF > 'localSrc/Random.c' #include "Random.h" #include "oopsIO.h" #define THIS Random #define BASE Object DEFINE_CLASS(Random,Object,1,NULL,NULL); /* * Part of the table on page 28 of Wirth, vol II */ static randomStateTable[][2] = { {3,7}, {4,9}, {3,10}, {1,11}, {1,15}, {3,17}, {7,18}, {3,20}, {2,21}, {1,22}, {5,23}, {3,25}, {2,29}, {3,31}, {13,33}, {2,35}, {11,36}, {14,39}, {3,41}, {9,49}, {3,52}, {24,55}, {7,57}, {19,58}, {38,89}, {17,95}, {6,97}, {11,98}, {-1,-1} }; Random::Random(long seed, int size) { for (register int l = 0; randomStateTable[l][0] != -1 && randomStateTable[l][1] < size; l++); if (randomStateTable[l][1] == -1) { l--; } j = randomStateTable[l][0] - 1; k = randomStateTable[l][1] - 1; stateSize = k + 1; state = new long[stateSize]; /* * Initialize the state */ for (register int i = 0; i < stateSize; i++) { state[i] = seed; seed = (seed * 1103515245 + 12345) & 0xffffffff; } } Random::Random(fileDescTy& fd, Random& where) { this = &where; readBin(fd, stateSize); readBin(fd, j); readBin(fd, k); state = new long[stateSize]; for (int i = 0; i < stateSize; i++) { readBin(fd, state[i]); } } Random::Random(istream& s, Random& where) { this = &where; s >> stateSize >> j >> k; state = new long[stateSize]; for (int i = 0; i < stateSize; i++) { s >> state[i]; } } Random::~Random() { delete state; } double Random::asDouble() { return( Random::drawDouble() ); } obid Random::copy() { return shallowCopy(); } void Random::deepenShallowCopy() { } void Random::printOn(ostream& s) { s << "[ " << j << " "; s << k << " "; for (int i = 0; i < stateSize; i ++) { s << hex(state[i]) << " "; } s << "]\n"; } void Random::storer(fileDescTy& fd) { Object::storer(fd); storeBin(fd,stateSize); storeBin(fd,j); storeBin(fd,k); for( int i = 0; i << stateSize; i++) { storeBin(fd, state[i]); } } void Random::storer(ostream& s) { Object::storer(s); s << stateSize << j << k; for (int i = 0; i < stateSize; i++) { s << hex(state[i]); } } SHAR_EOF if test -f 'localSrc/RandomInterval.c' then echo shar: over-writing existing file "'localSrc/RandomInterval.c'" fi cat << \SHAR_EOF > 'localSrc/RandomInterval.c' #include "RandomInterval.h" #include "oopsIO.h" #include #define THIS RandomInterval #define BASE Random DEFINE_CLASS(RandomInterval,Random,1,NULL,NULL); RandomInterval::RandomInterval(double xlow, double xhigh, long seed, int size) : (seed, size) { if (xlow > xhigh) { double x = xhigh; xhigh = xlow; xlow = x; } low = xlow; high = xhigh; } RandomInterval::RandomInterval(fileDescTy& fd, RandomInterval& where) : (fd, where) { readBin(fd, low); readBin(fd, high); } RandomInterval::RandomInterval(istream& s, RandomInterval& where) : (s, where) { s >> low; s >> high; } double RandomInterval::asDouble() { return( low + (high - low + 1) * Random::drawDouble() ); } obid RandomInterval::copy() { return shallowCopy(); } void RandomInterval::deepenShallowCopy() { } void RandomInterval::printOn(ostream& s) { s << "[ " ; Random::printOn(s); s << low; s << high; s << "]\n"; } void RandomInterval::storer(fileDescTy& fd) { Random::storer(fd); storeBin(fd, low); storeBin(fd, high); } void RandomInterval::storer(ostream& s) { Random::storer(s); s << low; s << high; } SHAR_EOF if test -f 'localSrc/RandomRange.c' then echo shar: over-writing existing file "'localSrc/RandomRange.c'" fi cat << \SHAR_EOF > 'localSrc/RandomRange.c' #include "RandomRange.h" #include "oopsIO.h" #include #define THIS RandomRange #define BASE Random DEFINE_CLASS(RandomRange,Random,1,NULL,NULL); RandomRange::RandomRange(double xlow, double xhigh, long seed, int size) : (seed, size) { if (xlow > xhigh) { double x = xhigh; xhigh = xlow; xlow = x; } low = xlow; high = xhigh; } RandomRange::RandomRange(fileDescTy& fd, RandomRange& where) : (fd, where) { readBin(fd, low); readBin(fd, high); } RandomRange::RandomRange(istream& s, RandomRange& where) : (s, where) { s >> low; s >> high; } double RandomRange::asDouble() { return( low + (high - low) * Random::drawDouble() ); } obid RandomRange::copy() { return shallowCopy(); } void RandomRange::deepenShallowCopy() { } void RandomRange::printOn(ostream& s) { s << "[ " ; Random::printOn(s); s << low; s << high; s << "]\n"; } void RandomRange::storer(fileDescTy& fd) { Random::storer(fd); storeBin(fd, low); storeBin(fd, high); } void RandomRange::storer(ostream& s) { Random::storer(s); s << low; s << high; } SHAR_EOF if test -f 'localSrc/Thread.c' then echo shar: over-writing existing file "'localSrc/Thread.c'" fi cat << \SHAR_EOF > 'localSrc/Thread.c' #include "Thread.h" #include "ExceptAct.h" #define THIS Thread #define BASE Object DEFINE_CLASS(Thread,Link,1,NULL,NULL); extern const int OOPS_STACKOV; extern const int OOPS_BADPRI; extern const int OOPS_RESRUN; extern const int OOPS_RESTERM; extern const int OOPS_INVALIDPS; extern const int OOPS_SUSTERM; extern const int OOPS_ILLEGALFCN; extern const int OOPS_NOTINIT; Thread::Thread(int priority) // MAIN thread constructor { saved_fp = 0; stack_base = 0; stack_end = 0; stack_size = 0; thread_name = "MAIN"; thread_priority = priority; thread_state = SUSPENDED; } void Thread::checkStack() { if (stack_base == 0) return; // don't check MAIN stack if (*(stack_end) != (void*)UNINITIALIZED || #if STACK_GROWS_DOWN saved_fp < stack_end) #else saved_fp > stack_end) #endif setOOPSerror(OOPS_STACKOV,DEFAULT,name()); } unsigned char Thread::priority() { return thread_priority; } unsigned char Thread::priority(unsigned char newPriority) { register unsigned char oldPriority =thread_priority; if (newPriority > MAXPRIORITY) { setOOPSerror(OOPS_BADPRI,DEFAULT,newPriority,MAXPRIORITY); } AST_DISABLE; thread_priority = newPriority; if (newPriority != oldPriority && thread_state == RUNNING) { scheduler.runList[oldPriority].remove(*this); scheduler.runList[newPriority].addLast(*this); } AST_ENABLE; return oldPriority; } UNSIGNED Thread::capacity() { return stack_size; } void Thread::resume() { AST_DISABLE; switch (thread_state) { case SUSPENDED: { thread_state = RUNNING; scheduler.runList[thread_priority].addLast(*this); scheduler.runCount++; schedule(); break; } case RUNNING: setOOPSerror(OOPS_RESRUN,DEFAULT,name(),this); case TERMINATED: setOOPSerror(OOPS_RESTERM,DEFAULT,name(),this); default: setOOPSerror(OOPS_INVALIDPS,DEFAULT,name(),this,className(),thread_state); } AST_ENABLE; } void Thread::suspend() { AST_DISABLE; switch (thread_state) { case SUSPENDED: break; case RUNNING: { thread_state = SUSPENDED; scheduler.runList[thread_priority].remove(*this); scheduler.runCount--; break; } case TERMINATED: setOOPSerror(OOPS_SUSTERM,DEFAULT,name(),this); default: setOOPSerror(OOPS_INVALIDPS,DEFAULT,name(),this,className(),thread_state); } AST_ENABLE; } void Thread::terminate() { AST_DISABLE; suspend(); thread_state = TERMINATED; AST_ENABLE; schedule(); } int Thread::compare(const Object& ob) // compare thread priorities { assertArgSpecies(ob,class_Thread,"compare"); return thread_priority - ((Thread*)&ob)->thread_priority; } obid Thread::copy() { shouldNotImplement("copy"); return 0; } void Thread::deepenShallowCopy() { shouldNotImplement("deepCopy"); } bool Thread::forkCheck() { if (!OOPSInitialized() { setOOPSerror(OOPS_NOTINIT,DEFAULT, "Scheduler",this,className(),"forkCheck"); } return scheduler.active_thread != this; } UNSIGNED Thread::hash() { return (UNSIGNED)this; } void Thread::init() // initialize thread context { thread_state = SUSPENDED; saved_AST_state = 0; extern ExceptionEnv lastResort; saved_exception_env_stack_top = &lastResort; saved_exception_action = new ExceptionActionTbl; } bool Thread::isEqual(const const Object& ob) { return isSame(ob); } void Thread::printOn(ostream& strm) { strm << className() << " " << thread_name << " pri: " << thread_priority << " state: "; switch (thread_state) { case SUSPENDED: strm << "SUSPENDED"; break; case RUNNING: strm << "RUNNING"; break; case TERMINATED: strm << "TERMINATED"; break; default: strm << "INVALID"; } strm << " stack: 0x" << hex((int)stack_base) << " size: " << stack_size << " fp: 0x" << hex((int)saved_fp) << "\n"; } UNSIGNED Thread::size() { return stack_size; } extern Catch catch_stack_top; void Thread::restore() { exception_env_stack_top = saved_exception_env_stack_top; oops_exception_action = saved_exception_action; catch_stack_top = saved_catch_stack_top; } void Thread::save() { saved_exception_env_stack_top = exception_env_stack_top; saved_exception_action = oops_exception_action; saved_catch_stack_top = catch_stack_top; } void Thread::storer(ostream&) { shouldNotImplement("storeOn"); } void Thread::storer(fileDescTy&) { shouldNotImplement("storeOn"); } SHAR_EOF if test -f 'localSrc/Weibull.c' then echo shar: over-writing existing file "'localSrc/Weibull.c'" fi cat << \SHAR_EOF > 'localSrc/Weibull.c' #include "Weibull.h" #include "oopsIO.h" #include #define THIS Weibull #define BASE Random DEFINE_CLASS(Weibull,Random,1,NULL,NULL); Weibull::Weibull(double xalpha, double xbeta, long seed, int size) : (seed, size) { invAlpha = 1.0 / xalpha; beta = xbeta; } Weibull::Weibull(fileDescTy& fd, Weibull& where) : (fd, where) { readBin(fd, invAlpha); readBin(fd, beta); } Weibull::Weibull(istream& s, Weibull& where) : (s, where) { s >> invAlpha; s >> beta; } /* * See Simulation, Modelling & Analysis by Law & Kelton, pp259 * * This is the ``polar'' method. */ double Weibull::asDouble() { return( pow(beta * ( - log(1 - Random::drawDouble()) ), invAlpha) ); } obid Weibull::copy() { return shallowCopy(); } void Weibull::deepenShallowCopy() { } void Weibull::printOn(ostream& s) { s << "[ " ; Random::printOn(s); s << invAlpha; s << beta; s << "]\n"; } void Weibull::storer(fileDescTy& fd) { Random::storer(fd); storeBin(fd, invAlpha); storeBin(fd, beta); } void Weibull::storer(ostream& s) { Random::storer(s); s << invAlpha; s << beta; } SHAR_EOF if test -f 'localSrc/Binomial.h' then echo shar: over-writing existing file "'localSrc/Binomial.h'" fi cat << \SHAR_EOF > 'localSrc/Binomial.h' #ifndef BINOMIALH #define BINOMIALH #include "Random.h" extern Class class_Binomial; class Binomial: public Random { int n; double u; public: Binomial(int n, double u, long seed = 0, int size = 55); Binomial(fileDescTy&, Binomial&); Binomial(istream&, Binomial&); virtual double asDouble(); virtual obid copy(); // { return shallowCopy(); } virtual void deepenShallowCopy(); // {} virtual const Class* isA(); virtual void printOn(ostream& strm); virtual void storer(fileDescTy&); virtual void storer(ostream&); }; #endif SHAR_EOF if test -f 'localSrc/Erlang.h' then echo shar: over-writing existing file "'localSrc/Erlang.h'" fi cat << \SHAR_EOF > 'localSrc/Erlang.h' #ifndef ERLANGH #define ERLANGH #include "Random.h" extern Class class_Erlang; class Erlang: public Random { int k; double a; public: Erlang(double mean, double variance, long seed = 0, int size = 55); Erlang(fileDescTy&, Erlang&); Erlang(istream&, Erlang&); virtual double asDouble(); virtual obid copy(); // { return shallowCopy(); } virtual void deepenShallowCopy(); // {} virtual const Class* isA(); virtual void printOn(ostream& strm); virtual void storer(fileDescTy&); virtual void storer(ostream&); }; #endif SHAR_EOF if test -f 'localSrc/Geometric.h' then echo shar: over-writing existing file "'localSrc/Geometric.h'" fi cat << \SHAR_EOF > 'localSrc/Geometric.h' #ifndef GEOMETRICH #define GEOMETRICH #include "Random.h" extern Class class_Geometric; class Geometric: public Random { double mean; public: Geometric(double mean, long seed = 0, int size = 55); Geometric(fileDescTy&, Geometric&); Geometric(istream&, Geometric&); virtual double asDouble(); virtual obid copy(); // { return shallowCopy(); } virtual void deepenShallowCopy(); // {} virtual const Class* isA(); virtual void printOn(ostream& strm); virtual void storer(fileDescTy&); virtual void storer(ostream&); }; #endif SHAR_EOF if test -f 'localSrc/HyperGeometric.h' then echo shar: over-writing existing file "'localSrc/HyperGeometric.h'" fi cat << \SHAR_EOF > 'localSrc/HyperGeometric.h' #ifndef HYPERGEOMETRICH #define HYPERGEOMETRICH #include "Random.h" extern Class class_HyperGeometric; class HyperGeometric: public Random { double u; double p; public: HyperGeometric(double uu, double vv, long seed = 0, int size = 55); HyperGeometric(fileDescTy&, HyperGeometric&); HyperGeometric(istream&, HyperGeometric&); virtual double asDouble(); virtual obid copy(); // { return shallowCopy(); } virtual void deepenShallowCopy(); // {} virtual const Class* isA(); virtual void printOn(ostream& strm); virtual void storer(fileDescTy&); virtual void storer(ostream&); }; #endif SHAR_EOF if test -f 'localSrc/LogNormal.h' then echo shar: over-writing existing file "'localSrc/LogNormal.h'" fi cat << \SHAR_EOF > 'localSrc/LogNormal.h' #ifndef LOGNORMALH #define LOGNORMALH #include "Normal.h" extern Class class_LogNormal; class LogNormal: public Normal { public: LogNormal(double mean, double variance, long seed = 0, int size = 55); LogNormal(fileDescTy&, LogNormal&); LogNormal(istream&, LogNormal&); virtual double asDouble(); virtual obid copy(); // { return shallowCopy(); } virtual void deepenShallowCopy(); // {} virtual const Class* isA(); virtual void printOn(ostream& strm); virtual void storer(fileDescTy&); virtual void storer(ostream&); }; #endif SHAR_EOF if test -f 'localSrc/NegativeExpntl.h' then echo shar: over-writing existing file "'localSrc/NegativeExpntl.h'" fi cat << \SHAR_EOF > 'localSrc/NegativeExpntl.h' #ifndef NEGATIVEEXPNTLH #define NEGATIVEEXPNTLH #include "Random.h" extern Class class_NegativeExpntl; class NegativeExpntl: public Random { double mean; public: NegativeExpntl(double mean, long seed = 0, int size = 55); NegativeExpntl(fileDescTy&, NegativeExpntl&); NegativeExpntl(istream&, NegativeExpntl&); virtual double asDouble(); virtual obid copy(); // { return shallowCopy(); } virtual void deepenShallowCopy(); // {} virtual const Class* isA(); virtual void printOn(ostream& strm); virtual void storer(fileDescTy&); virtual void storer(ostream&); }; #endif SHAR_EOF if test -f 'localSrc/Normal.h' then echo shar: over-writing existing file "'localSrc/Normal.h'" fi cat << \SHAR_EOF > 'localSrc/Normal.h' #ifndef NORMALH #define NORMALH #include "Random.h" extern Class class_Normal; class Normal: public Random { char haveCachedNormal; double cachedNormal; protected: double mean; double variance; public: Normal(double mean, double variance, long seed = 0, int size = 55); Normal(fileDescTy&, Normal&); Normal(istream&, Normal&); virtual double asDouble(); virtual obid copy(); // { return shallowCopy(); } virtual void deepenShallowCopy(); // {} virtual const Class* isA(); virtual void printOn(ostream& strm); virtual void storer(fileDescTy&); virtual void storer(ostream&); }; #endif SHAR_EOF if test -f 'localSrc/Poisson.h' then echo shar: over-writing existing file "'localSrc/Poisson.h'" fi cat << \SHAR_EOF > 'localSrc/Poisson.h' #ifndef POISSONH #define POISSONH #include "Random.h" extern Class class_Poisson; class Poisson: public Random { double mean; public: Poisson(double mean, long seed = 0, int size = 55); Poisson(fileDescTy&, Poisson&); Poisson(istream&, Poisson&); virtual double asDouble(); virtual obid copy(); // { return shallowCopy(); } virtual void deepenShallowCopy(); // {} virtual const Class* isA(); virtual void printOn(ostream& strm); virtual void storer(fileDescTy&); virtual void storer(ostream&); }; #endif SHAR_EOF if test -f 'localSrc/Random.h' then echo shar: over-writing existing file "'localSrc/Random.h'" fi cat << \SHAR_EOF > 'localSrc/Random.h' #ifndef RANDOMH #define RANDOMH #include "Object.h" extern Class class_Random; /* * Additive number generator. This method is presented in Volume II * of The Art of Computer Programming by Knuth. With the default * parameter, it'll take 232 bytes of storage and return a stream * of random numbers with a period of around 2^55. You can vary * the period size, and set the initial seed. * * subclasses of this class might use th * * Least you think the numbers '24' & '55' are odd, see Knuth, Vol II, * page 27. */ class Random: public Object { unsigned long *state; int stateSize; int j; int k; protected: double drawDouble() { unsigned long result = state[j] + state[k]; state[k] = result; j = (j == 0) ? stateSize : (j-1); k = (k == 0) ? stateSize : (k-1); return(result / ( (double) (unsigned long) 0xffffffff) ); } public: Random(long seed = 0, int size = 55); Random(fileDescTy&,Random&); Random(istream&,Random&); ~Random(); virtual double asDouble(); int asInt() { return(int(asDouble())); } virtual obid copy(); // { return shallowCopy(); } virtual void deepenShallowCopy(); // {} virtual const Class* isA(); virtual void printOn(ostream& strm); virtual void storer(fileDescTy&); virtual void storer(ostream&); }; #endif SHAR_EOF if test -f 'localSrc/RandomInterval.h' then echo shar: over-writing existing file "'localSrc/RandomInterval.h'" fi cat << \SHAR_EOF > 'localSrc/RandomInterval.h' #ifndef RANDOMINTERVALH #define RANDOMINTERVALH #include "Random.h" /* * The interval [lo..hi] */ extern Class class_RandomInterval; class RandomInterval: public Random { double low; double high; public: RandomInterval(double low, double high, long seed = 0, int size = 55); RandomInterval(fileDescTy&, RandomInterval&); RandomInterval(istream&, RandomInterval&); virtual double asDouble(); virtual obid copy(); // { return shallowCopy(); } virtual void deepenShallowCopy(); // {} virtual const Class* isA(); virtual void printOn(ostream& strm); virtual void storer(fileDescTy&); virtual void storer(ostream&); }; #endif SHAR_EOF if test -f 'localSrc/RandomRange.h' then echo shar: over-writing existing file "'localSrc/RandomRange.h'" fi cat << \SHAR_EOF > 'localSrc/RandomRange.h' #ifndef RANDOMRANGEH #define RANDOMRANGEH #include "Random.h" /* * The interval [lo..hi) */ extern Class class_RandomRange; class RandomRange: public Random { double low; double high; public: RandomRange(double low, double high, long seed = 0, int size = 55); RandomRange(fileDescTy&, RandomRange&); RandomRange(istream&, RandomRange&); virtual double asDouble(); virtual obid copy(); // { return shallowCopy(); } virtual void deepenShallowCopy(); // {} virtual const Class* isA(); virtual void printOn(ostream& strm); virtual void storer(fileDescTy&); virtual void storer(ostream&); }; #endif SHAR_EOF if test -f 'localSrc/Thread.h' then echo shar: over-writing existing file "'localSrc/Thread.h'" fi cat << \SHAR_EOF > 'localSrc/Thread.h' #ifndef THREADH #define THREADH #include "Exception.h" #include "oopsconfig.h" const int MAXPRIORITY = 7; // maximum thread priority #define THREAD_FORK if (forkCheck()) { resume(); return; } class Scheduler; class Semaphore; class ExceptionActionTbl; extern Class class_Thread; enum threadState { SUSPENDED, RUNNING, TERMINATED }; class Thread : public Object { // saved frame pointer -- ACCESSED BY MACHINE-DEPENDENT CODE! void* saved_fp; // bottom of stack void** stack_base; // end of stack (stack_end < stack_base) if stack grows down void** stack_end; // stack size in void* unsigned stack_size; const char* thread_name; // SUSPENDED, RUNNING, or TERMINATED threadState thread_state; unsigned char thread_priority; // AST priority or signal mask (saved/restored by Scheduler) int saved_AST_state; ExceptionEnv* saved_exception_env_stack_top; ExceptionActionTbl* saved_exception_action; Catch saved_catch_stack_top; void checkStack(); void create(void** stack); // machine dependent void exchj(); // machine dependent friend Scheduler; friend Semaphore; friend void schedule(); friend void yield(); Thread(int priority); // MAIN thread constructor public: Thread(const char* name ="", unsigned stacksize =1024, int priority =0); ~Thread() { terminate(); #if STACK_GROWS_DOWN delete stack_end; #else delete stack_base; #endif } Thread(fileDescTy&,Thread&) {} Thread(istream&,Thread&) {} bool forkCheck(); const char* name() { return thread_name; } threadState state() { return thread_state; } virtual UNSIGNED capacity(); // returns stack size virtual int compare(const Object&); // compare thread priorities virtual obid copy(); virtual void deepenShallowCopy(); virtual UNSIGNED hash(); virtual void init(); virtual const Class* isA(); virtual bool isEqual(const Object& ob); virtual void printOn(ostream& strm); virtual unsigned char priority(); virtual unsigned char priority(unsigned char newPriority); virtual void restore(); virtual void resume(); virtual void save(); virtual UNSIGNED size(); virtual void storer(fileDescTy&); virtual void storer(ostream&); virtual void suspend(); virtual void terminate(); }; inline Thread::Thread(const char* name, unsigned stacksize, int priority) { thread_name = name; thread_priority = priority; stack_size = stacksize; #if STACK_GROWS_DOWN stack_end = new void*[stacksize]; stack_base = &stack_end[stacksize-1]; #else stack_base = new void*[stacksize]; stack_end = &stack_base[stacksize-1]; #endif *stack_end = (void*)UNINITIALIZED; // to detect stack overflow init(); // initialize thread context create(stack_base); // initialize the new stack // The constructor for the derived class must THREAD_FORK here! // The C++ compiler won't allow it here because there are statements // after a 'return' } #endif THREADH SHAR_EOF if test -f 'localSrc/Weibull.h' then echo shar: over-writing existing file "'localSrc/Weibull.h'" fi cat << \SHAR_EOF > 'localSrc/Weibull.h' #ifndef WEIBULLH #define WEIBULLH #include "Random.h" extern Class class_Weibull; class Weibull: public Random { double invAlpha; double beta; public: Weibull(double alpha, double beta, long seed = 0, int size = 55); Weibull(fileDescTy&, Weibull&); Weibull(istream&, Weibull&); virtual double asDouble(); virtual obid copy(); // { return shallowCopy(); } virtual void deepenShallowCopy(); // {} virtual const Class* isA(); virtual void printOn(ostream& strm); virtual void storer(fileDescTy&); virtual void storer(ostream&); }; #endif SHAR_EOF # End of shell archiveme utio7