grunwald@uiucdcsm.UUCP (11/17/87)
We've got the OOPS distribution dated May, 1986. I'm planning on using modifying & augmenting the OOPS stuff to support process-oriented discrete event simulation, along the lines of Csim. I'd like to find Keith Gorlen (email if possible) to get an uptodate version. Also, I'd like to donate the following parts (subclassing follows) Random -- not a linear method, much better additive method, should be comparable to Unix 'random'. Binomial Erlang Geometric HyperGeometric NegativeExpntl Normal LogNormal Poisson RandomInterval RandomRange Weibull I'm willing to set these up for anon. FTP, or a submission to this news group. dirk grunwald univ. of Illinois grunwald@m.cs.uiuc.edu ...!ihnp4!uiucdcs!grunwald
grunwald@uiucdcsm.cs.uiuc.edu (11/21/87)
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 <math.h> #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 <math.h> #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 <math.h> #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 <math.h> #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 <math.h> #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 <math.h> #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 <math.h> #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 <math.h> #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 <math.h> #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 <math.h> #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 <math.h> #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
grunwald@uiucdcsm.UUCP (11/24/87)
patch #1: you'll need to put "this = where" in all of the storage constructors.
dave@cs.arizona.edu (Dave Schaumann) (05/15/91)
In article <1512@caslon.cs.arizona.edu> dave@cs.arizona.edu (Dave Schaumann) writes: >typedef struct FOO { > ... > void (*foo_fn) ( struct FOO * ) c; ^ | oops.. this is a typo... > ... > } foo ; -- Dave Schaumann | There is no cause so right that one cannot find a fool dave@cs.arizona.edu | following it. - Niven's Law # 16