home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-09-21 | 6.6 KB | 250 lines | [TEXT/PJMM] |
- unit Randoms;
-
-
- {This code given to me courtesy of my Operating Systems instructor, Gerald B. Blanton.}
- {'Liberated' from the MS-dos world on 9/20/91 by David W. Bock}
- {If you use these routines, I'd like to hear about it! Drop me E-Mail at}
- {David Bock or IC Dave on America Online, BOCKD@ITHACA on Bitnet, or snail mail at:}
- {Fuzzy Navel Software}
- {PO Box 862}
- {Great Falls, VA 22066}
- {}
- {Thanks!!! (And I'd appreciate any credit you could give me or my instructor in your}
- {docs or 'About...' dialog.)}
- {}
- {PROGRAMMERS! If you have any good sample code, RELEASE IT! That's what I'm}
- {doing... I'd like to create an atmosphere where mac programmers help each other}
- {out. I'm not asking you to give away any proprietary secrets, but if you have a clever}
- {little routine or a better mouse trap, Release it... I'm interested in creating a}
- {P/D Library of sample code snippets. If you have something you'd like to ad, send it to me}
- {or tell me about it. You can reach me at any of the addresses above. - Thanks!}
- { -db}
-
-
- {-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
- {the random number routines - uses random number generator from CACM.}
- {Includes the user distribution routines (uniform distribution, exponential}
- {distribution and normal distribution.}
- { The Random Number (rn) routine uses a byte argument to select one of}
- {8 possible seeds from the ran array. All user distribution routines use this}
- {same convention. rn returns a real value between 0 and 1.}
- {-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
- interface
-
- const
- NUMRANDOMS = 8;
- var
- ran: array[1..NUMRANDOMS] of longint;
- norm: array[1..79] of record
- z, cp: real;
- end;
-
-
-
- procedure InitRandoms;
- {Call this routine before using any of the three functions below.}
- {data structures are set up and globals are initialized.}
-
- function Uniform (low, hi, rnIndex: integer): Integer;
-
- {a standard Random Number Generator. when passed integers for low and high,}
- {a number between low and high will be returned (with psedo-equal probability)}
- { rnIndex is a number from 1 to 8 and is used as a seed. (it actually indexes }
- {an array of seeds below.}
-
- function Exponent (mean: real; rnIndex: integer): Integer;
-
- {a Random Number Generator that passes back an integer. The probability of an}
- {integer coming back is on the exponential curve with the mean passed in 'mean'.}
- {(see the sample program... this is a hard one to explain.) rnIndex is used as above.}
-
- function Normal (mean, stdDev, rnIndex: integer): Integer;
-
- {a Random number generator that passes back an integer. Passed a mean and a standard}
- {deviation, the probability of a certain integer coming back is drawn by a bell curve}
- {around the mean. Standard deviation controls the 'width' of the bell. (again, see the}
- {sample program...) enIndex is used as above.}
-
- implementation
-
- function rn (ranNum: Byte): Real;
- const
- a = 16807;
- m = 2147483647;
- q = 127773;
- r = 3826;
- var
- lo, hi, test: Longint;
-
- begin
- hi := ran[ranNum] div q;
- lo := ran[ranNum] mod q;
- test := a * lo - r * hi;
- if test > 0 then
- ran[ranNum] := test
- else
- ran[ranNum] := test + m;
- rn := ran[ranNum] / m;
- end;
-
- {-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
- function Uniform (low, hi, rnIndex: integer): Integer;
-
-
- begin
- Uniform := trunc(low + (hi - low + 1) * rn(rnIndex));
- end;
-
- {-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
- function Exponent (mean: real; rnIndex: integer): Integer;
-
- begin
- Exponent := trunc(mean * (-ln(1 - rn(rnIndex))));
- end;
-
- {-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
- procedure InitNorm;
- var
- i: integer;
-
- begin
- norm[40].z := 0.0;
- norm[40].cp := 0.5;
- norm[41].z := 0.1;
- norm[41].cp := 0.53983;
- norm[42].z := 0.2;
- norm[42].cp := 0.57926;
- norm[43].z := 0.3;
- norm[43].cp := 0.61791;
- norm[44].z := 0.4;
- norm[44].cp := 0.65542;
- norm[45].z := 0.5;
- norm[45].cp := 0.69146;
- norm[46].z := 0.6;
- norm[46].cp := 0.72575;
- norm[47].z := 0.7;
- norm[47].cp := 0.75804;
- norm[48].z := 0.8;
- norm[48].cp := 0.78814;
- norm[49].z := 0.9;
- norm[49].cp := 0.81594;
-
- norm[50].z := 1.0;
- norm[50].cp := 0.84134;
- norm[51].z := 1.1;
- norm[51].cp := 0.86433;
- norm[52].z := 1.2;
- norm[52].cp := 0.88493;
- norm[53].z := 1.3;
- norm[53].cp := 0.90320;
- norm[54].z := 1.4;
- norm[54].cp := 0.91924;
- norm[55].z := 1.5;
- norm[55].cp := 0.93319;
- norm[56].z := 1.6;
- norm[56].cp := 0.94520;
- norm[57].z := 1.7;
- norm[57].cp := 0.95543;
- norm[58].z := 1.8;
- norm[58].cp := 0.96407;
- norm[59].z := 1.9;
- norm[59].cp := 0.97128;
-
- norm[60].z := 2.0;
- norm[60].cp := 0.97725;
- norm[61].z := 2.1;
- norm[61].cp := 0.98214;
- norm[62].z := 2.2;
- norm[62].cp := 0.98610;
- norm[63].z := 2.3;
- norm[63].cp := 0.98928;
- norm[64].z := 2.4;
- norm[64].cp := 0.99180;
- norm[65].z := 2.5;
- norm[65].cp := 0.99379;
- norm[66].z := 2.6;
- norm[66].cp := 0.99534;
- norm[67].z := 2.7;
- norm[67].cp := 0.99653;
- norm[68].z := 2.8;
- norm[68].cp := 0.99744;
- norm[69].z := 2.9;
- norm[69].cp := 0.99813;
-
- norm[70].z := 3.0;
- norm[70].cp := 0.99865;
- norm[71].z := 3.1;
- norm[71].cp := 0.99903;
- norm[72].z := 3.2;
- norm[72].cp := 0.99931;
- norm[73].z := 3.3;
- norm[73].cp := 0.99952;
- norm[74].z := 3.4;
- norm[74].cp := 0.99966;
- norm[75].z := 3.5;
- norm[75].cp := 0.99977;
- norm[76].z := 3.6;
- norm[76].cp := 0.99984;
- norm[77].z := 3.7;
- norm[77].cp := 0.99989;
- norm[78].z := 3.8;
- norm[78].cp := 0.99993;
- norm[79].z := 3.9;
- norm[79].cp := 0.99995;
-
- for i := 1 to 39 do
- begin
- norm[i].z := -norm[80 - i].z;
- norm[i].cp := 1.0 - norm[80 - i].cp;
- end;
- end;
-
- {-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
- function Normal (mean, stdDev, rnIndex: integer): Integer;
-
-
- function GetZ (rnIndex: integer): real;
- var
- lo, hi: integer;
- rancp: Real;
-
- begin
- rancp := rn(rnIndex);
- if rancp < norm[1].cp then
- GetZ := -4.0
- else if rancp > norm[79].cp then
- GetZ := 4.0
- else
- begin
- lo := 1;
- hi := 79;
- while hi - lo > 1 do
- if rancp < norm[(hi + lo) div 2].cp then
- hi := (hi + lo) div 2
- else
- lo := (hi + lo) div 2;
- GetZ := norm[lo].z;
- end;
- end;
-
- begin
- Normal := trunc(GetZ(rnIndex) * stdDev + mean);
- end;
-
- {-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
-
-
- procedure InitRandoms;
- begin
- InitNorm;
- ran[1] := 37584381;
- ran[2] := 1909996635;
- ran[3] := 1964463183;
- ran[4] := 1235671459;
- ran[5] := 1480745561;
- ran[6] := 442596621;
- ran[7] := 340029185;
- ran[8] := 2030226625;
- end;
-
- end.