// ------------------------------------------------
// 
// Swarm rel. 1.0 (random rel. 0.6)
// 
// Notes on the use of the random number generators
// 
// Sven Thommesen <sthomme@humsci.auburn.edu>
//
// 1997-01-15
// 
// ------------------------------------------------


USAGE notes:
------------

This library (random) implements all the generators that were in
previous releases of Swarm, but now as standard objects that 
inherit from SwarmObject.

Of these generators, the SWB series and PMMLCG series have better
properties than the rest. ACG and SCG are included for historical
completeness only; they are not recommended for serious use.

// -----

More generators may be added to this library in the future. Please
e-mail me with references if you come across a good one we might use!

These objects were designed in a minimalist fashion; extraneous
functionality was avoided. However, you the user call the shots!
If you think of functionality that you feel is missing from this
release of the random library, please e-mail me with your suggestions.

// -----

In the following text, wherever I use SWB1 as an example you may
substitute any other generator.

You CREATE a generator in one of two ways:

(a) the hard way:

	aGenerator = [ SWB1 createBegin: [self getZone] ];
	[ aGenerator setStateFromSeed: seedValue ];
	aGenerator = [ aGenerator createEnd ];

(b) the easier way:

	aGenerator = [ SWB1 create: [self getZone]
			setStateFromSeed: seedValue ];

You CANNOT use the following idiom (it generates an error & halts):

	aGenerator = [ SWB1 create: [self getZone] ];
	[ aGenerator setStateFromSeed: seedValue ];


You may RESET THE STATE OF THE GENERATOR at any time to a predictable
value by calling:

	[ aGenerator setStateFromSeed: seedValue ];

NOTE: a generator should always produce the same sequence of 
random numbers after being reset with a given seed value. If you
discover otherwise, please notify me soonest!

There is no default seed provided, nor any randomized starting seed.
The generators do not keep track of what seeds you are using. You are
responsible for using sensible seed values.

You may obtain the LARGEST GENERATOR VALUE produced by a given
generator by calling

	uValue = [ aGenerator getUnsignedMax ];

You obtain a STREAM OF (PSEUDO-) RANDOM NUMBERS through successive
calls to

	uValue = [ aGenerator getUnsignedSample ];

The complete inner STATE OF A GENERATOR may be extracted and saved;
and at a later time this state may be restored to the generator (or
another generator of the same type).

The amount of state data that is generated is reported by method

	uValue = [ aGenerator getStateSize ];

You are responsible for allocating a large enough buffer area to hold
the generated state data, for example:

	unsigned stateSize = [ aGenerator getStateSize ];
	id stateBuf = [[self getZone] alloc: stateSize];

You may then extract the state data into your buffer:

	[ aGenerator getState: (void *) stateBuf ];

NOTE: if you have not allocated enough memory, the generator will 
happily attempt to overwrite whatever follows your buffer in memory!

You may restore state data to a generator with this method call:

	[ aGenerator setState: (void *) stateBuf ];

and you free up the memory buffer with

	[ [self getZone] free: stateBuf ];

When being called with setState, the generator will make certain sanity
checks on the data in your buffer, to make sure the data were generated
by the right type of generator. If not, it will complain & abort.

The internal composition of the data retrieved with getState should be
of no concern to users; it may in fact change if the implementation of
the generators changes. Just make sure you save and restore the correct
number of bytes as indicated by getStateSize.

When a generator's state is saved (e.g. to disk) and later restored,
it should produce the same subsequent stream of random variates as
would have been produced if the generator had never been interrupted.
Again, if you discover otherwise, please send documentation my way 
so the problem may be rectified.


PROGRAMMING notes:
------------------

Every generator is subclassed from the RandomNumberGenerator class (which is
a subclass of SwarmObject). Code and data common to all generators is
in RandomNumberGenerator, and the subclassed generators add their own data 
and override RandomNumberGenerator methods as needed.

RandomNumberGenerator is not functional as a standalone object.

Each generator implements:

-initState;	// called by createBegin; initializes fixed
		// (unchanging) parameters for the generator

-resetState;	// called by setStateFromSeed; initializes (resets)
		// parameters that depend on the seed, and other
		// variable working data (state data).

-getUnsignedMax;	// return largest value that may be produced
			// by this generator (smallest is always 0).

-getUnsignedSample;	// return the next random number.

-getStateSize;	// obtain the required buffer size for getState
-getState;	// extract generator's internal state into user's buffer
-setState;	// set generator's internal state from user's buffer

// -----------------
