home *** CD-ROM | disk | FTP | other *** search
- ; Program: ULTRA.ASM
- ;
- ; 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 (first public release)
- ; 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.
- ;
- ; CONTENTS: 1. Detailed Description
- ; 2. Compilation Instructions
- ; 3. Functions and Subroutines
- ; 4. Program Structure
- ;
- ;----------------------------------------------------------------------
- ; 1. 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.
- ;
- ;----------------------------------------------------------------------
- ; 2. COMPILATION INSTRUCTIONS
- ;
- ; This assembler code is written for TASM 2.0, to allow one program
- ; to serve for many different languages.
- ;
- ; The header files define language dependent macros. These are:
- ; ULTRA_C.ASM, ULTRA_TP.ASM and ULTRA_LH.ASM are for Turbo C,
- ; Turbo Pascal and Lahey Fortran respectively.
- ;
- ; All of these files then include the core files ULTRADAT.INC and
- ; ULTRACOD.INC, which actually implementat the algorithm.
- ;
- ; A second set of files ULT32_C.ASM, ULT32_TP.ASM, and ULT32_LH.ASM
- ; which include ULT32DAT.INC and ULT32COR.INC are the same programs
- ; rewritten to use 32 bit code available on 80386 or 80486 machines
- ; for faster execution.
- ;
- ; The C files ULTRA_C.ASM and ULT32_C.ASM depend on the user defining
- ; a variable `m' to be the memory model. Thus the command:
- ; TASM -dm=small ULTRA_C.ASM
- ; will create a small memory model object file. The memory model can
- ; be any of `tiny', `small', `compact', `medium', `large' or `huge'.
- ;
- ; Implementation in any other language is simply a matter of fixing
- ; the header file.
- ;
- ;----------------------------------------------------------------------
- ; 3. 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() 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).
- ;
- ; The variables swbn and swbx and the subroutine swbfill() are
- ; declared globally to allow macros to implement even faster
- ; versions of these subroutines. swbx is an array of 148 bytes
- ; that is filled with random bytes every time swbfill is called.
- ; swbn is a 16-bit integer that counts how many bytes of swbx
- ; have not yet been used by any of the random functions.
- ;
- ; An example of a macro in C that provides 32-bit integers is given
- ; below. Note that this is written assuming no other random
- ; routines are being used at the same time.
- ;
- ; extern long swbx[37];
- ; short int nlft = 0;
- ; long swbp
- ; #define i32bit() ( (--nlft >= 0) ? *(swbp++) : \
- ; swbfill(), nlft=36, swbp=&swbx[0], *(swbp++) )
- ;
- ; Speed comes from the fact that, 36 out of 37 times, there need
- ; be no subroutine call at all, just a simple table lookup.
- ; (The overhead of function calls can take as many cycles
- ; as the generating process itself.)
- ;
- ; The data is laid out in such a way that if swbx is declared as
- ; an array containing 306 bytes, this array would contain the
- ; entire state of the random number generator. Thus, saving
- ; and then later restoring these 306 bytes would allow one to
- ; continue exactly where the process had left off.
- ;
- ;----------------------------------------------------------------------
- ;
- ; 4. DATA
- ; The array swbx has 148 random bytes in it. All the functions
- ; take as many bytes as they need from it. swbn is the number of
- ; bytes remaining in that array. When this gets to zero, the
- ; fillswb routine refills them with a fresh batch of 148 bytes.
- ;
- ;----------------------------------------------------------------------
- ; 5. Header files
- ; This is where all language-dependent entry and exit conventions
- ; have been placed. If you want to add another language which uses
- ; another protocol to pass arguments, return values, or save registers,
- ; this is where you want to modify the program.
- ;
- ; You must define:
- ; EnterProcedure Called every time a procedure is entered
- ; save all registers etc here. Make DS point to the
- ; data segement if it doesn't.
- ; ExitProcedure Called every time a procedure exits
- ; undo all that EnterProcdure did here.
- ; RinitProcStart Loads the two arguments for RINIT into
- ; CONGX and SHRGX (for ULTRA), and into the
- ; 32-bit registers EAX and EBX (for ULT32).
- ; Make sure ES=DS.
- ; RinitProcEnd Undo what RinitProcStart did.
- ; FillProcStart Make sure ES=DS.
- ; FillProcEnd Undo what FillProcStart did.
- ; DwordFn The function result is in DX:AX. Place it
- ; where the language expects it to be.
- ; WordFn Put result in AX where it is expected.
- ; ByteFn Put result in AL where it is expected.
- ; RealFn,DoubleFn Put result from the NDP stack to where it should be.
- ;
- ; The segment names, classes etc must also be defined here.
- ; The files ULTRADAT.INC and ULTRACOD.INC (or ULT32DAT.INC
- ; and ULT32COD.INC) must be included in the appropriate
- ; segments. Look at examples of header files for more information.
-