You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
3.6 KiB
120 lines
3.6 KiB
\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
|
|
|