summaryrefslogtreecommitdiff
path: root/tex/context/base/supp-ran.tex
blob: 8c76ab443f65117bf886773551f1027cedc9666c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
%D \module
%D   [       file=supp-ran,
%D        version=1998.01.21,
%D          title=\CONTEXT\ Support Macros,
%D       subtitle=Random Number Generation,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

\writestatus{loading}{Third Party Macros / Random Number Generation}

%D \macros
%D   {getrandomcount, getrandomdimen,
%D    getrandomfloat, getrandomnumber,
%D    setrandomseed, getrandomseed}
%D
%D This module load Donald Arseneau's generic file
%D \type{random.tex}. A small shell is needed because we
%D redefine some \TEX\ primitives. We also use different names
%D for the two generators and add an extra one.
%D
%D \starttyping
%D \getrandomcount  \countregister {minimum} {maximum}
%D \getrandomdimen  \dimenregister {minimum} {maximum}
%D \getrandomnumber \macroname     {minimum} {maximum}
%D \getrandomfloat  \macroname     {minimum} {maximum}
%D \stoptyping
%D
%D Of course the file \type{random.tex} needs to be present.
%D To prevent name clashes, the \CONTEXT\ distribution
%D contains a copy in \type {thrd-ran.tex}.
%D
%D The randomseed can be set by:
%D
%D \starttyping
%d \setrandomseed{number>0}
%D \stoptyping
%D
%D and get by:
%D
%D \starttyping
%D \getrandomseed\randomseed
%D \stoptyping

\ifx\nextrandom\undefined

  \readfile{random.tex}
    {\writestatus{loading}{Donald Arseneau's 'random.tex'     (found)}}
    {\writestatus{loading}{Donald Arseneau's 'random.tex' (not found)}}

\fi

\ifx\nextrandom\undefined

  \writestatus{loading}{using fake randomizer}

  \newcount\randomi

  \def\setrandim#1#2#3{\scratchdimen  #2\relax#1\scratchdimen  }
  \def\setrannum#1#2#3{\scratchcounter#2\relax#1\scratchcounter}

  \let\nextrandom\relax

\fi

\ifx\nextrandom\undefined \endinput \fi

\ifx\normaluniformdeviate\undefined

  \let\verynormalnextrandom\nextrandom

  \def\normalnextrandom
    {\bgroup
     \let\time \normaltime
     \let\day  \normalday
     \let\month\normalmonth
     \let\year \normalyear
     \verynormalnextrandom
     \egroup}

\else

  % Yet untested.

  \writestatus{loading}{using tex's built in randomizer (overloading macro)}

  % For the meaning of the magic number, see \type {thrd-ran.tex}.

  % \def\normalnextrandom
  %   {\setrandomseed\randomi
  %    \global\randomi\normaluniformdeviate2147483647\relax}

  % Taco suggested to use the following alternative because \type
  % {\normaluniformdeviate} can return a zero (as expected) while
  % Donalds's alternative has a minimum of~1.

  \beginTEX
    \def\nextrandom
      {\normalsetrandomseed\randomi
       \global\randomi\normaluniformdeviate2147483646%
       \global\advance\randomi\plusone}
  \endTEX

  \beginETEX \numexpr
    \def\nextrandom
      {\normalsetrandomseed\randomi
       \global\randomi\numexpr\normaluniformdeviate2147483646+1\relax}
  \endETEX

  \let\normalnextrandom\nextrandom

\fi

\def\nextrandom
  {\bgroup
   \normalnextrandom
   \gdef\nextrandom{\ifcase\randomseedfrozen\normalnextrandom\fi}%
   \egroup}

\chardef\randomseedfrozen\zerocount

\def\freezerandomseed
  {\ifcase\randomseedfrozen
     \nextrandom \global\chardef\randomseedfrozen\plusone
   \fi}

\def\defrostrandomseed
  {\ifcase\randomseedfrozen\else
     \global\chardef\randomseedfrozen\zerocount \nextrandom
   \fi}

\let\getrandomcount\setrannum
\let\getrandomdimen\setrandim

\def\getrandomnumber#1#2#3%
  {\getrandomcount\scratchcounter{#2}{#3}%
   \edef#1{\the\scratchcounter}}

\def\getrandomfloat#1#2#3%
  {\getrandomdimen\scratchdimen{#2\points}{#3\points}%
   \edef#1{\withoutpt\the\scratchdimen}}

\unexpanded \def\setrandomseed#1%
  {\global\randomi#1\relax} % global added

\unexpanded \def\getrandomseed#1%
  {\edef#1{\number\randomi}}

\def\getnewrandomseed#1%
  {\setrandomseed\minusone  % signals thrd-ran to auto reseed
   \nextrandom              % this signal is needed for the
   #1\randomi}              % pseudo randomizer (see: third-ran)

\endinput