\NeedsTeXFormat{LaTeX2e} \ProvidesPackage{fp-random}[1995/02/23] % Version information \def\FP@randomversion{1.0a} \message{% `Fixed Point Random,% \space\space\space\space\space\space% \space\space\space\space\space\space\space% Version \FP@randomversion% \space(C) Denis Girou (CNRS/IDRIS)% \space\space\space% } % Resolve dependencies \RequirePackage{fp-basic} % Uniform random value \newcount\FPseed % Seed value \def\FPrandom#1{% % #1 macro, which gets the result % % Uniform random number generator (numbers between 0 and 1) % % Algorithm reproduce from a very old Fortran program (unknown origin!) % % double precision function RANF() % % integer SEED % common /COMSEED/SEED % * % integer A,M,Q,R % parameter(A=16807,M=2147483647,Q=127773,R=2836) % * % integer LO,HI,TEST % * % HI = SEED/Q % LO = SEED-HI*Q % TEST = A*LO-R*HI % if(TEST.gt.0) then % SEED = TEST % else % SEED = TEST+M % endif % * % RANF = DFLOAT(SEED)/DFLOAT(M) % * % end % % The macro used a seed value, defined by the counter \FPseed. % If it's unknown at first call, we used an arbitrary value. % % We verify that we obtain the same results as in Fortran % % The algorithm seems fairly good. With the Fortran version, we obtain % typically something like 49954 numbers between 0 and 0.5 and 50046 between % 0.5 and 1 for 100000 random numbers, depending of the seed value used. % % To generate a "pseudo-random" seed, you can consider to use the \time % macro, to intialize the random numbers generator according to the time. % Something like: % \FPseed=\the\time % \multiply\FPseed\the\day % \multiply\FPseed\the\month % \multiply\FPseed\the\year % % Of course, it is very slow comparing to "standard" programming % languages. On a RS 6000 370, it's take 51s to generate 100 numbers, % loading time of the test program included (and 0.2s for the Fortran % version ... for 100000 numbers!) % But you must also notice that Hans van der Meer published in TUGboat % Vol. 15, 1, March 1994, pages 57-58, an article on "Random bit generator % in TeX". In fact, he doesn't give a complete solution to generate uniform % random numbers, but at least give some interesting ideas, and also the % code of a simple but powerful macro \SRtest{choice 1}{choice 2}, which % allow to execute the instructions of "choice 1" or those of "choice 2" % with a probability of 1/2 each. As his method is based on shifts of bits % with almost no computations, it's very fast (around 1000 faster than to do % the same thing that \SRtest with \FPrandom.) % {\FP@beginmessage{RANDOM}% % \ifnum\FPseed=0% \FPseed=123456789% \FP@debug{random: seed value undefined! We will used \the\FPseed.^^J% Define it if you want to generate a different sequence of random% numbers.}% \else% \FP@debug{random: seed value used: \the\FPseed}% \fi% % \FP@xia=\FPseed% \divide\FP@xia by 127773% \FP@xib=\FP@xia% \multiply\FP@xib by 127773% \advance\FP@xib by -\FPseed% \FP@xib=-\FP@xib% \multiply\FP@xia by 2836% \FPseed=\FP@xib% \multiply\FPseed by 16807% \advance\FPseed by -\FP@xia% % \ifnum\FPseed>0% \else% \advance\FPseed by 2147483647% \fi% \FPdiv\FP@tmpa{\the\FPseed}{2147483647}% \global\let\FP@tmp\FP@tmpa% \global\FPseed=\FPseed% \FP@debug{random: random number: \FP@tmp\space% (new seed value: \the\FPseed)}% % \FP@endmessage{}% }% \let#1\FP@tmp% } \endinput