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 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<TITLE>AARM95 - Random Number Generation</TITLE>
<META NAME="Author" CONTENT="JTC1/SC22/WG9/ARG, by Randall Brukardt, ARG Editor">
<META NAME="GENERATOR" CONTENT="Arm_Form.Exe, Ada Reference Manual generator">
<STYLE type="text/css">
DIV.paranum {position: absolute; font-family: Arial, Helvetica, sans-serif; left: 0.5 em; top: auto}
TT {font-family: "Courier New", monospace}
DT {display: compact}
DIV.Normal {font-family: "Times New Roman", Times, serif; margin-bottom: 0.6em}
DIV.Wide {font-family: "Times New Roman", Times, serif; margin-top: 0.6em; margin-bottom: 0.6em}
DIV.Annotations {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-bottom: 0.6em}
DIV.WideAnnotations {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0.6em; margin-bottom: 0.6em}
DIV.Index {font-family: "Times New Roman", Times, serif}
DIV.SyntaxSummary {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.4em}
DIV.Notes {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.6em}
DIV.NotesHeader {font-family: "Times New Roman", Times, serif; margin-left: 2.0em}
DIV.SyntaxIndented {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.4em}
DIV.Indented {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-bottom: 0.6em}
DIV.CodeIndented {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-bottom: 0.6em}
DIV.SmallIndented {font-family: "Times New Roman", Times, serif; margin-left: 10.0em; margin-bottom: 0.6em}
DIV.SmallCodeIndented {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-bottom: 0.6em}
DIV.Examples {font-family: "Courier New", monospace; margin-left: 2.0em; margin-bottom: 0.6em}
DIV.SmallExamples {font-family: "Courier New", monospace; font-size: 80%; margin-left: 7.5em; margin-bottom: 0.6em}
DIV.IndentedExamples {font-family: "Courier New", monospace; margin-left: 8.0em; margin-bottom: 0.6em}
DIV.SmallIndentedExamples {font-family: "Courier New", monospace; font-size: 80%; margin-left: 15.0em; margin-bottom: 0.6em}
UL.Bulleted {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.SmallBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.NestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.SmallNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.IndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.CodeIndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.CodeIndentedNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.SyntaxIndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.NotesBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.NotesNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
DL.Hanging {font-family: "Times New Roman", Times, serif; margin-top: 0em; margin-bottom: 0.6em}
DD.Hanging {margin-left: 6.0em}
DL.IndentedHanging {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0em; margin-bottom: 0.6em}
DD.IndentedHanging {margin-left: 2.0em}
DL.HangingInBulleted {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
DD.HangingInBulleted {margin-left: 4.0em}
DL.SmallHanging {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0em; margin-bottom: 0.6em}
DD.SmallHanging {margin-left: 7.5em}
DL.SmallIndentedHanging {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-top: 0em; margin-bottom: 0.6em}
DD.SmallIndentedHanging {margin-left: 2.0em}
DL.SmallHangingInBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
DD.SmallHangingInBulleted {margin-left: 5.0em}
DL.Enumerated {font-family: "Times New Roman", Times, serif; margin-right: 0.0em; margin-top: 0em; margin-bottom: 0.5em}
DD.Enumerated {margin-left: 2.0em}
DL.SmallEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
DD.SmallEnumerated {margin-left: 2.5em}
DL.NestedEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
DL.SmallNestedEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
</STYLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFF0" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
<P><A HREF="AA-TOC.html">Contents</A> <A HREF="AA-0-29.html">Index</A> <A HREF="AA-A-5-1.html">Previous</A> <A HREF="AA-A-5-3.html">Next</A></P>
<HR>
<H1> A.5.2 Random Number Generation</H1>
<DIV Class="Paranum"><FONT SIZE=-2>1</FONT></DIV>
<DIV Class="Normal"> [Facilities for the generation of pseudo-random
floating point numbers are provided in the package Numerics.Float_Random;
the generic package Numerics.Discrete_Random provides similar facilities
for the generation of pseudo-random integers and pseudo-random values
of enumeration types. <A NAME="I5576"></A>For brevity, pseudo-random
values of any of these types are called <I>random numbers</I>.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>2</FONT></DIV>
<DIV Class="Normal"> Some of the facilities provided are basic to all
applications of random numbers. These include a limited private type
each of whose objects serves as the generator of a (possibly distinct)
sequence of random numbers; a function to obtain the ``next'' random
number from a given sequence of random numbers (that is, from its generator);
and subprograms to initialize or reinitialize a given generator to a
time-dependent state or a state denoted by a single integer.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>3</FONT></DIV>
<DIV Class="Normal"> Other facilities are provided specifically for
advanced applications. These include subprograms to save and restore
the state of a given generator; a private type whose objects can be used
to hold the saved state of a generator; and subprograms to obtain a string
representation of a given generator state, or, given such a string representation,
the corresponding state.] </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>3.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Discussion: </B>These facilities
support a variety of requirements ranging from repeatable sequences (for
debugging) to unique sequences in each execution of a program. </FONT></DIV>
<H4 ALIGN=CENTER>Static Semantics</H4>
<DIV Class="Paranum"><FONT SIZE=-2>4</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> The library package
Numerics.Float_Random has the following declaration: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>5</FONT></DIV>
<DIV Class="Examples"><TT><B>package</B> Ada.Numerics.Float_Random <B>is</B><A NAME="I5577"></A><A NAME="I5578"></A><A NAME="I5579"></A></TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>6</FONT></DIV>
<DIV Class="Examples"><TT> -- <I>Basic facilities</I></TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>7</FONT></DIV>
<DIV Class="Examples"><TT> <B>type</B> <A NAME="I5580"></A><A NAME="I5581"></A>Generator <B>is</B> <B>limited</B> <B>private</B>;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>8</FONT></DIV>
<DIV Class="Examples"><TT> <B>subtype</B> <A NAME="I5582"></A>Uniformly_Distributed <B>is</B> Float <B>range</B> 0.0 .. 1.0;<BR>
<B>function</B> <A NAME="I5583"></A><A NAME="I5584"></A>Random (Gen : Generator) <B>return</B> Uniformly_Distributed;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>9</FONT></DIV>
<DIV Class="Examples"><TT> <B>procedure</B> <A NAME="I5585"></A><A NAME="I5586"></A>Reset (Gen : <B>in</B> Generator;<BR>
Initiator : <B>in</B> Integer);<BR>
<B>procedure</B> <A NAME="I5587"></A><A NAME="I5588"></A>Reset (Gen : <B>in</B> Generator);</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>10</FONT></DIV>
<DIV Class="Examples"><TT> -- <I>Advanced facilities</I></TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>11</FONT></DIV>
<DIV Class="Examples"><TT> <B>type</B> <A NAME="I5589"></A><A NAME="I5590"></A>State <B>is</B> <B>private</B>;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>12</FONT></DIV>
<DIV Class="Examples"><TT> <B>procedure</B> <A NAME="I5591"></A><A NAME="I5592"></A>Save (Gen : <B>in</B> Generator;<BR>
To_State : <B>out</B> State);<BR>
<B>procedure</B> <A NAME="I5593"></A><A NAME="I5594"></A>Reset (Gen : <B>in</B> Generator;<BR>
From_State : <B>in</B> State);</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>13</FONT></DIV>
<DIV Class="Examples"><TT> <A NAME="I5595"></A>Max_Image_Width : <B>constant</B> := <I>implementation-defined integer value</I>;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>14</FONT></DIV>
<DIV Class="Examples"><TT> <B>function</B> <A NAME="I5596"></A><A NAME="I5597"></A>Image (Of_State : State) <B>return</B> String;<BR>
<B>function</B> <A NAME="I5598"></A><A NAME="I5599"></A>Value (Coded_State : String) <B>return</B> State;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>15</FONT></DIV>
<DIV Class="Examples"><TT><B>private</B><BR>
... -- <I>not specified by the language</I><BR>
<B>end</B> Ada.Numerics.Float_Random;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>16</FONT></DIV>
<DIV Class="Normal"> The generic library package Numerics.Discrete_Random
has the following declaration: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>17</FONT></DIV>
<DIV Class="Examples"><TT><A NAME="I5600"></A><A NAME="I5601"></A><A NAME="I5602"></A><BR>
<B>generic</B><BR>
<B>type</B> Result_Subtype <B>is</B> (<>);<BR>
<B>package</B> Ada.Numerics.Discrete_Random <B>is</B></TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>18</FONT></DIV>
<DIV Class="Examples"><TT> -- <I>Basic facilities</I></TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>19</FONT></DIV>
<DIV Class="Examples"><TT> <B>type</B> <A NAME="I5603"></A><A NAME="I5604"></A>Generator <B>is</B> <B>limited</B> <B>private</B>;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>20</FONT></DIV>
<DIV Class="Examples"><TT> <B>function</B> <A NAME="I5605"></A><A NAME="I5606"></A>Random (Gen : Generator) <B>return</B> Result_Subtype;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>21</FONT></DIV>
<DIV Class="Examples"><TT> <B>procedure</B> <A NAME="I5607"></A><A NAME="I5608"></A>Reset (Gen : <B>in</B> Generator;<BR>
Initiator : <B>in</B> Integer);<BR>
<B>procedure</B> <A NAME="I5609"></A><A NAME="I5610"></A>Reset (Gen : <B>in</B> Generator);</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>22</FONT></DIV>
<DIV Class="Examples"><TT> -- <I>Advanced facilities</I></TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>23</FONT></DIV>
<DIV Class="Examples"><TT> <B>type</B> <A NAME="I5611"></A><A NAME="I5612"></A>State <B>is</B> <B>private</B>;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>24</FONT></DIV>
<DIV Class="Examples"><TT> <B>procedure</B> <A NAME="I5613"></A><A NAME="I5614"></A>Save (Gen : <B>in</B> Generator;<BR>
To_State : <B>out</B> State);<BR>
<B>procedure</B> <A NAME="I5615"></A><A NAME="I5616"></A>Reset (Gen : <B>in</B> Generator;<BR>
From_State : <B>in</B> State);</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>25</FONT></DIV>
<DIV Class="Examples"><TT> <A NAME="I5617"></A>Max_Image_Width : <B>constant</B> := <I>implementation-defined integer value</I>;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>26</FONT></DIV>
<DIV Class="Examples"><TT> <B>function</B> <A NAME="I5618"></A><A NAME="I5619"></A>Image (Of_State : State) <B>return</B> String;<BR>
<B>function</B> <A NAME="I5620"></A><A NAME="I5621"></A>Value (Coded_State : String) <B>return</B> State;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>27</FONT></DIV>
<DIV Class="Examples"><TT><B>private</B><BR>
... -- <I>not specified by the language</I><BR>
<B>end</B> Ada.Numerics.Discrete_Random;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>27.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Implementation defined: </B>The
value of Numerics.Float_Random.Max_Image_Width.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>27.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Implementation defined: </B>The
value of Numerics.Discrete_Random.Max_Image_Width.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>27.c/1</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Implementation Note: </B>{<I><A HREF="defect2.html#8652/0097">8652/0097</A></I>}
The following is a possible implementation of the private part of <U>Numerics.Float_Random</U><S>each
package</S> (assuming the presence of ``<B>with</B> Ada.Finalization;''
as a context clause): </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>27.d</FONT></DIV>
<DIV Class="SmallExamples" Style="margin-bottom: 0.4em"><TT><B>type</B> State <B>is</B> ...;<BR>
<B>type</B> Access_State <B>is</B> <B>access</B> State;<BR>
<B>type</B> Generator <B>is</B> <B>new</B> Finalization.Limited_Controlled <B>with</B><BR>
<B>record</B><BR>
S : Access_State := <B>new</B> State'(...);<BR>
<B>end</B> <B>record</B>;<BR>
<B>procedure</B> Finalize (G : <B>in</B> <B>out</B> Generator);</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>27.d.1/1</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>{<I><A HREF="defect2.html#8652/0097">8652/0097</A></I>}
<U>Unfortunately, Numerics.Discrete_Random.Generator cannot be implemented
this way, as Numerics.Discrete_Random can be instantiated at any nesting
depth. However, Generator could have a component of a controlled type,
as long as that type is declared in some other (non-generic) package.
One possible solution would be to implement Numerics.Discrete_Random
in terms of Numerics.Float_Random, using a component of Numerics.Float_Random.Generator
to implement Numerics.Float_Random.Generator.</U></FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>27.e</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>Clearly some level of indirection
is required in the implementation of a Generator, since the parameter
mode is <B>in</B> for all operations on a Generator. For this reason,
Numerics.Float_Random and Numerics.Discrete_Random cannot be declared
pure. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>28</FONT></DIV>
<DIV Class="Normal"> An object of the limited private type Generator
is associated with a sequence of random numbers. Each generator has a
hidden (internal) state, which the operations on generators use to determine
the position in the associated sequence. <A NAME="I5622"></A>All generators
are implicitly initialized to an unspecified state that does not vary
from one program execution to another; they may also be explicitly initialized,
or reinitialized, to a time-dependent state, to a previously saved state,
or to a state uniquely denoted by an integer value. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>28.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Discussion: </B>The repeatability
provided by the implicit initialization may be exploited for testing
or debugging purposes. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>29</FONT></DIV>
<DIV Class="Normal"> An object of the private type State can be used
to hold the internal state of a generator. Such objects are only needed
if the application is designed to save and restore generator states or
to examine or manufacture them.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>30</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.9em"> The operations
on generators affect the state and therefore the future values of the
associated sequence. The semantics of the operations on generators and
states are defined below. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>31</FONT></DIV>
<DIV Class="Examples"><TT><B>function</B> Random (Gen : Generator) <B>return</B> Uniformly_Distributed;<BR>
<B>function</B> Random (Gen : Generator) <B>return</B> Result_Subtype;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>32</FONT></DIV>
<DIV Class="CodeIndented" Style="margin-bottom: 0.9em">Obtains the ``next''
random number from the given generator, relative to its current state,
according to an implementation-defined algorithm. The result of the function
in Numerics.Float_Random is delivered as a value of the subtype Uniformly_Distributed,
which is a subtype of the predefined type Float having a range of 0.0
.. 1.0. The result of the function in an instantiation of Numerics.Discrete_Random
is delivered as a value of the generic formal subtype Result_Subtype.
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>32.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Implementation defined: </B>The
algorithms for random number generation.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>32.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>The requirement
for a level of indirection in accessing the internal state of a generator
arises from the desire to make Random a function, rather than a procedure.
</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>33</FONT></DIV>
<DIV Class="Examples"><TT><B>procedure</B> Reset (Gen : <B>in</B> Generator;<BR>
Initiator : <B>in</B> Integer);<BR>
<B>procedure</B> Reset (Gen : <B>in</B> Generator);</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>34</FONT></DIV>
<DIV Class="CodeIndented" Style="margin-bottom: 0.9em"><A NAME="I5623"></A>Sets
the state of the specified generator to one that is an unspecified function
of the value of the parameter Initiator (or to a time-dependent state,
if only a generator parameter is specified). <A NAME="I5624"></A>The
latter form of the procedure is known as the <I>time-dependent Reset
procedure</I>. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>34.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Implementation Note: </B>The
time-dependent Reset procedure can be implemented by mapping the current
time and date as determined by the system clock into a state, but other
implementations are possible. For example, a white-noise generator or
a radioactive source can be used to generate time-dependent states. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>35</FONT></DIV>
<DIV Class="Examples"><TT><B>procedure</B> Save (Gen : <B>in</B> Generator;<BR>
To_State : <B>out</B> State);<BR>
<B>procedure</B> Reset (Gen : <B>in</B> Generator;<BR>
From_State : <B>in</B> State);</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>36</FONT></DIV>
<DIV Class="CodeIndented" Style="margin-bottom: 0.9em">Save obtains
the current state of a generator. Reset gives a generator the specified
state. A generator that is reset to a state previously obtained by invoking
Save is restored to the state it had when Save was invoked.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>37</FONT></DIV>
<DIV Class="Examples"><TT><B>function</B> Image (Of_State : State) <B>return</B> String;<BR>
<B>function</B> Value (Coded_State : String) <B>return</B> State;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>38</FONT></DIV>
<DIV Class="CodeIndented">Image provides a representation of a state
coded (in an implementation-defined way) as a string whose length is
bounded by the value of Max_Image_Width. Value is the inverse of Image:
Value(Image(S)) = S for each state S that can be obtained from a generator
by invoking Save. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>38.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Implementation defined: </B>The
string representation of a random number generator's state.</FONT></DIV>
<H4 ALIGN=CENTER>Dynamic Semantics</H4>
<DIV Class="Paranum"><FONT SIZE=-2>39</FONT></DIV>
<DIV Class="Normal"> <A NAME="I5625"></A><A NAME="I5626"></A><A NAME="I5627"></A>Instantiation
of Numerics.Discrete_Random with a subtype having a null range raises
Constraint_Error.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>40/1</FONT></DIV>
<DIV Class="Normal"> <FONT SIZE=-1><I>This paragraph was deleted.</I></FONT>{<I><A HREF="defect1.html#8652/0050">8652/0050</A></I>}
<S><A NAME="I5628"></A><A NAME="I5629"></A><A NAME="I5630"></A>Invoking
Value with a string that is not the image of any generator state raises
Constraint_Error.</S> </DIV>
<H4 ALIGN=CENTER>Bounded (Run-Time) Errors</H4>
<DIV Class="Paranum"><FONT SIZE=-2>40.1/1</FONT></DIV>
<DIV Class="Normal"> {<I><A HREF="defect1.html#8652/0050">8652/0050</A></I>}
<U>It is a bounded error to invoke Value with a string that is not the
image of any generator state. <A NAME="I5631"></A><A NAME="I5632"></A>If
the error is detected, Constraint_Error or Program_Error is raised. Otherwise,
a call to Reset with the resulting state will produce a generator such
that calls to Random with this generator will produce a sequence of values
of the appropriate subtype, but which might not be random in character.
That is, the sequence of values might not fulfill the implementation
requirements of this subclause.</U> </DIV>
<H4 ALIGN=CENTER>Implementation Requirements</H4>
<DIV Class="Paranum"><FONT SIZE=-2>41</FONT></DIV>
<DIV Class="Normal"> A sufficiently long sequence of random numbers
obtained by successive calls to Random is approximately uniformly distributed
over the range of the result subtype.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>42</FONT></DIV>
<DIV Class="Normal"> The Random function in an instantiation of Numerics.Discrete_Random
is guaranteed to yield each value in its result subtype in a finite number
of calls, provided that the number of such values does not exceed 2 <SUP><FONT SIZE=+1><FONT SIZE=-2>15</FONT></FONT></SUP>.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>43</FONT></DIV>
<DIV Class="Normal"> Other performance requirements for the random
number generator, which apply only in implementations conforming to the
Numerics Annex, and then only in the ``strict'' mode defined there (see
<A HREF="AA-G-2.html">G.2</A>), are given in <A HREF="AA-G-2-5.html">G.2.5</A>.
</DIV>
<H4 ALIGN=CENTER>Documentation Requirements</H4>
<DIV Class="Paranum"><FONT SIZE=-2>44</FONT></DIV>
<DIV Class="Normal"> No one algorithm for random number generation
is best for all applications. To enable the user to determine the suitability
of the random number generators for the intended application, the implementation
shall describe the algorithm used and shall give its period, if known
exactly, or a lower bound on the period, if the exact period is unknown.
Periods that are so long that the periodicity is unobservable in practice
can be described in such terms, without giving a numerical bound.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>45</FONT></DIV>
<DIV Class="Normal"> The implementation also shall document the minimum
time interval between calls to the time-dependent Reset procedure that
are guaranteed to initiate different sequences, and it shall document
the nature of the strings that Value will accept without raising Constraint_Error.
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>45.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Implementation defined: </B>The
minimum time interval between calls to the time-dependent Reset procedure
that are guaranteed to initiate different random number sequences.</FONT></DIV>
<H4 ALIGN=CENTER>Implementation Advice</H4>
<DIV Class="Paranum"><FONT SIZE=-2>46</FONT></DIV>
<DIV Class="Normal"> Any storage associated with an object of type
Generator should be reclaimed on exit from the scope of the object. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>46.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>A level of
indirection is implicit in the semantics of the operations, given that
they all take parameters of mode <B>in</B>. This implies that the full
type of Generator probably should be a controlled type, with appropriate
finalization to reclaim any heap-allocated storage. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>47</FONT></DIV>
<DIV Class="Normal"> If the generator period is sufficiently long
in relation to the number of distinct initiator values, then each possible
value of Initiator passed to Reset should initiate a sequence of random
numbers that does not, in a practical sense, overlap the sequence initiated
by any other value. If this is not possible, then the mapping between
initiator values and generator states should be a rapidly varying function
of the initiator value. </DIV>
<DIV Class="NotesHeader"><FONT SIZE=-1>NOTES</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>48</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>14 If two or more tasks are
to share the same generator, then the tasks have to synchronize their
access to the generator as for any shared variable (see <A HREF="AA-9-10.html">9.10</A>).</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>49</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>15 Within a given implementation,
a repeatable random number sequence can be obtained by relying on the
implicit initialization of generators or by explicitly initializing a
generator with a repeatable initiator value. Different sequences of random
numbers can be obtained from a given generator in different program executions
by explicitly initializing the generator to a time-dependent state.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>50</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>16 A given implementation
of the Random function in Numerics.Float_Random may or may not be capable
of delivering the values 0.0 or 1.0. Portable applications should assume
that these values, or values sufficiently close to them to behave indistinguishably
from them, can occur. If a sequence of random integers from some fixed
range is needed, the application should use the Random function in an
appropriate instantiation of Numerics.Discrete_Random, rather than transforming
the result of the Random function in Numerics.Float_Random. However,
some applications with unusual requirements, such as for a sequence of
random integers each drawn from a different range, will find it more
convenient to transform the result of the floating point Random function.
For M >= 1, the expression </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>51</FONT></DIV>
<DIV Class="Examples"><TT> Integer(Float(M) * Random(G)) mod M</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>52</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>transforms the result of Random(G) to
an integer uniformly distributed over the range 0 .. M-1; it is valid
even if Random delivers 0.0 or 1.0. Each value of the result range is
possible, provided that M is not too large. Exponentially distributed
(floating point) random numbers with mean and standard deviation 1.0
can be obtained by the transformation </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>53</FONT></DIV>
<DIV Class="Examples"><TT> -Log(Random(G) + Float'Model_Small))</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>54</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>where Log comes from Numerics.Elementary_Functions
(see <A HREF="AA-A-5-1.html">A.5.1</A>); in this expression, the addition
of Float'Model_Small avoids the exception that would be raised were Log
to be given the value zero, without affecting the result (in most implementations)
when Random returns a nonzero value. </FONT></DIV>
<H4 ALIGN=CENTER>Examples</H4>
<DIV Class="Paranum"><FONT SIZE=-2>55</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> <I>Example of a
program that plays a simulated dice game:</I> </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>56</FONT></DIV>
<DIV Class="Examples" Style="margin-bottom: 0.9em"><TT><B>with</B> Ada.Numerics.Discrete_Random;<BR>
<B>procedure</B> Dice_Game <B>is</B><BR>
<B>subtype</B> Die <B>is</B> Integer <B>range</B> 1 .. 6;<BR>
<B>subtype</B> Dice <B>is</B> Integer <B>range</B> 2*Die'First .. 2*Die'Last;<BR>
<B>package</B> Random_Die <B>is</B> <B>new</B> Ada.Numerics.Discrete_Random (Die);<BR>
<B>use</B> Random_Die;<BR>
G : Generator;<BR>
D : Dice;<BR>
<B>begin</B><BR>
Reset (G); -- <I>Start the generator in a unique state in each run</I><BR>
<B>loop</B><BR>
-- <I>Roll a pair of dice; sum and process the results</I><BR>
D := Random(G) + Random(G);<BR>
...<BR>
<B>end</B> <B>loop</B>;<BR>
<B>end</B> Dice_Game;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>57</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> <I>Example of a
program that simulates coin tosses:</I> </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>58</FONT></DIV>
<DIV Class="Examples" Style="margin-bottom: 0.9em"><TT><B>with</B> Ada.Numerics.Discrete_Random;<BR>
<B>procedure</B> Flip_A_Coin <B>is</B><BR>
<B>type</B> Coin <B>is</B> (Heads, Tails);<BR>
<B>package</B> Random_Coin <B>is</B> <B>new</B> Ada.Numerics.Discrete_Random (Coin);<BR>
<B>use</B> Random_Coin;<BR>
G : Generator;<BR>
<B>begin</B><BR>
Reset (G); -- <I>Start the generator in a unique state in each run</I><BR>
<B>loop</B><BR>
-- <I>Toss a coin and process the result</I><BR>
<B>case</B> Random(G) <B>is</B><BR>
<B>when</B> Heads =><BR>
...<BR>
<B>when</B> Tails =><BR>
...<BR>
<B>end</B> <B>case</B>;<BR>
...<BR>
<B>end</B> <B>loop</B>;<BR>
<B>end</B> Flip_A_Coin;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>59</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> <I>Example of a
parallel simulation of a physical system, with a separate generator of
event probabilities in each task:</I> </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>60</FONT></DIV>
<DIV Class="Examples"><TT><B>with</B> Ada.Numerics.Float_Random;<BR>
<B>procedure</B> Parallel_Simulation <B>is</B><BR>
<B>use</B> Ada.Numerics.Float_Random;<BR>
<B>task</B> <B>type</B> Worker <B>is</B><BR>
<B>entry</B> Initialize_Generator (Initiator : <B>in</B> Integer);<BR>
...<BR>
<B>end</B> Worker;<BR>
W : <B>array</B> (1 .. 10) <B>of</B> Worker;<BR>
<B>task</B> <B>body</B> Worker <B>is</B><BR>
G : Generator;<BR>
Probability_Of_Event : Uniformly_Distributed;<BR>
<B>begin</B><BR>
<B>accept</B> Initialize_Generator (Initiator : <B>in</B> Integer) <B>do</B><BR>
Reset (G, Initiator);<BR>
<B>end</B> Initialize_Generator;<BR>
<B>loop</B><BR>
...<BR>
Probability_Of_Event := Random(G);<BR>
...<BR>
<B>end</B> <B>loop</B>;<BR>
<B>end</B> Worker;<BR>
<B>begin</B><BR>
-- <I>Initialize the generators in the Worker tasks to different states</I><BR>
<B>for</B> I <B>in</B> W'Range <B>loop</B><BR>
W(I).Initialize_Generator (I);<BR>
<B>end</B> <B>loop</B>;<BR>
... -- <I>Wait for the Worker tasks to terminate</I><BR>
<B>end</B> Parallel_Simulation;</TT></DIV>
<DIV Class="NotesHeader"><FONT SIZE=-1>NOTES</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>61</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>17 <I>Notes on the last example:</I>
Although each Worker task initializes its generator to a different state,
those states will be the same in every execution of the program. The
generator states can be initialized uniquely in each program execution
by instantiating Ada.Numerics.Discrete_Random for the type Integer in
the main procedure, resetting the generator obtained from that instance
to a time-dependent state, and then using random integers obtained from
that generator to initialize the generators in each Worker task. </FONT></DIV>
<HR>
<P><A HREF="AA-TOC.html">Contents</A> <A HREF="AA-0-29.html">Index</A> <A HREF="AA-A-5-1.html">Previous</A> <A HREF="AA-A-5-3.html">Next</A> <A HREF="AA-TTL.html">Legal</A></P>
</BODY>
</HTML>
|