home *** CD-ROM | disk | FTP | other *** search
- The following is a description of a random number package written
- for the 8086 family in assembler. An inefficient but easy to understand
- algorithm written in C implementing the same generator is also
- included for those who wish to port it to other architectures.
- There seem to be all the good properties that one could ask for
- in a generator here, while the speed is comparable to the fastest
- generators:
-
- Program: ULTRA
-
- Description: The greatest random number generator that ever was
- or ever will be. Way beyond Super-Duper.
- (Just kidding, but we think its a good one.)
-
- Authors: Arif Zaman (arif@stat.fsu.edu) and
- George Marsaglia (geo@stat.fsu.edu).
-
- Date: 18 March 1992
-
- Version: 1.01
-
- Copyright: To obtain permission to incorporate this program into
- any commercial product, please contact the authors at
- the e-mail address given above or at
-
- Department of Statistics and
- Supercomputer Computations Research Institute
- Florida State University
- Tallahassee, FL 32306.
-
-
- ----------------------------------------------------------------------
- DETAILED DESCRIPTION:
-
- This is an implementation of a random number generator with many
- good properties that common generators lack, namely:
-
- o Extremely long period (more than 10^356---that's more than
- 10^270 numbers for each atom in the universe, in case you
- want to simulate creation).
-
- o Combines two different types of generators, to achieve a very
- thorough mixing.
-
- o Very fast.
-
- o Random bits, bytes, 16 or 32 bit words, single or double precision
- real numbers are all available.
-
- o Single precision reals (by far the most common) are guaranteed
- to have full precision in the fraction (mantissa).
- Almost all generators produce reals by dividing a 32 (or 31) bit
- integer by 2^32 (2^31). This means the smallest possible
- random reals are small multiples of 2^(-32). This implementation
- will produce random reals down to 2^(-50) or smaller with the proper
- frequencies. This makes it impossible to get a 0, which
- avoids the rare, but irritating program-stopping situation
- that arises from taking a logarithm of, or dividing by, zero.
-
- The principal component of ULTRA is the Subtract-with-Borrow (SWB)
- generator that is described in our paper `A New Class of Random Number
- Generators', Annals of Applied Probability V1 462-480, 1991.
- This uses a 148 byte seed array, to obtain an astronomically large
- period, while satisfying all the usual theoretical and experimental
- tests for randomness.
-
- The other component of ULTRA is the congruential generator with
- multiplier 69069 and base 2^32. This is a very well known, reliable
- (but short period) generator, tried and tested. It is, for example,
- the generator built into VAX's. The results of both of these
- generators are xor'ed to provide the bytes which form the output
- of the ULTRA random number generator.
-
- ----------------------------------------------------------------------
-
- FUNCTIONS and SUBROUTINES
-
- The i[n]bit functions:
- ---------------------
- i1bit(), i7bit(), i8bit(), i15bit(), i16bit(), i31bit(), i32bit()
-
- For n=32, 16, 8 these return a 4, 2, 1 byte answer which has
- all bits random, hence is a random integer. If it is treated
- as a signed integer, it ranges from -2^(n-1) to 2^(n-1)-1.
- As an unsigned integer it range is 0 to 2^n-1.
-
- For n=31, 15, 7 these return a 4, 2, 1 byte answer, but since
- the sign bit is always off, these are always positive integers
- from 0 and 2^n-1.
-
- [d][u/v]ni functions:
- --------------------
- uni(), vni(), duni(), dvni()
-
- uni() is a single precision uniform random number strictly
- between 0 and 1. uni() always has 24 bits of precision;
- it will never be 0 (or 1).
-
- vni() is a single precision uniform between -1 and 1. It always has
- 24 bits of precision, and it never takes on the extreme values.
-
- duni() and dvni() are double precision version of uni and vni.
- They have no more than 64 bits of precision.
-
- rinit(n1,n2):
- ------------
- Calling rinit(n1,n2) initializes the seed array, using
- the two 32-bit integer arguments n1 and n2.
- The first argument should be odd (if it isn't it is made so).
- If rinit is not called, the built-in default state is
- what would result from the call rinit(1234567,7654321).
-
- =======================================================================
-
- Contents of this package:
-
- readme - This file
- ultra.doc - An explanation of the structure of the following
- assmbeler programs. Linkage and Compilation
- instructions and internal details can be found here.
-
- ultra_c.asm - A Turbo C header file
- ultra_lh.asm - A Lahey Fortran header file
- ultra_fr.asm - An IBM Fortran/2 header file
- ultra_tp.asm - A Turbo Pascal header file
-
- ultracod.inc - The assmebler implementation of the Ultra
- ultradat.inc random number generator. To use any high level
- language is simply a matter of changing the
- header file.
-
- ult32_c.asm - These four files are just like the above four
- ult32_lh.asm - but they will work on 80386 and above processors.
- ult32_tp.asm - They use the 32bit instructions to get more speed.
- ult32_fr.asm------This file doesn't work see note at the end.
- ult32cod.inc
- ult32dat.inc
-
- ultratpu.pas - A program to make Turbo Pascal units. See it or the
- makefile for an explanation of switches to make
- ultra.tpu or ultra32.tpu
-
- demo.c - Programs to exercise the various parts of ultra.asm
- demo.pas - and verify that the output remains unchanged. The
- demo.for - 'correct' output is contained in the file demo.out.
-
- ultra.c - The same program as the assembler version written
- very inefficiently in C. This is only to allow
- programmers inexperienced with 80x86 assembley
- language to understand the alogrithm.
- We hope this will encourage others to implement
- the algorithm on other hardware platforms.
- If you do, please report it to us.
-
- demo.out - The output from demo.c linked with ultra.c
- makefile - A makefile (for the Borland MAKE program) which compiles
- all the .obj files on my machine. It will almost certainly
- have to be modified for any other machine. You can use it
- as an example of the comilation switches needed.
- dif - A comparison of outputs from all the various demos.
- Turbo C tiny model seems to mess up its output for some
- reason. The Fortran output seems to round the last digit
- differently for the floating point part. Otherwise it
- all seems to work. IBM fortran/2 doesn't link correctly
- with ULT32 for some reason (see note at the end).
-
- Compiled object codes for several languages:
-
- ultra_fr.obj - IBM Fortran/2
- ultra_lh.obj - Lahey Fortran
- ultra_ct.obj - Turbo C (Tiny model)
- ultra_cs.obj - Tubro C (Small model)
- ultra_cm.obj - Turbo C (Medium model)
- ultra_cc.obj - Turbo C (Compact model)
- ultra_cl.obj - Turbo C (Large model)
- ultra_ch.obj - Turbo C (Huge model)
-
- ult32-??.obj - are 80386/80486 versions of the same libraries.
-
- ultra.tpu - Turbo Pascal 6.0 TPU
- ultra32.tpu - 80386/80486 version of above.
-
- NOTE: My computer crashes when I run the demo with ult32_fr (the
- 32 bit version for IBM Fortran/2). I include it for whoever
- wants to fix it.