\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