Update 1, 1/30/2013:11:03
# Homework Three: How Random is Pseudorandom?

### Objectives for this assignment

The goals for this assignment is to provide you with:
more practice using Java and working with arrays,
improved understanding of constructors and inheritance,
broadened understanding of pseudo random number generators,
and a more full-featured random number generator.
In order to bring several random number sources into a uniform framework,
you will also be implementing several classes that satisfy a new interface,
RandI.
### Problem requirements: Part I

### Evaluating pseudorandom number generators

### Problem requirements: Part II

### Problem requirements: Part III

### Submission instructions:

For this assignment, you will
extend your PRNG class from Assignment Two
so that it generates floating-point (`double`) numbers in the range 0 to 1.0
instead of integers in the range 0 to modulus-1.
Also, you will provide evaluation methods that test the randomness quality
of you pseudorandom number generator.

Write a new class, UniformRandom,
that extends your PRNG class from Assignment Two
*and* implements the RandI interface.
You should provide at least a default constructor for your
UniformRandom class.

Next, override your `next()` method.
This new version of the method should return a `Double` instead of whatever it was returning.
As an aside, the observant coder will have already noticed that
the `next()` method from the PRNG class was returning an instance of the
Integer wrapper class.
You might not have noticed this because Java kindly wraps an `int`
in an Integer object when an Object is expected,
and kindly unwraps the integer value from the Integer object when the simple value is needed.
The same applies to all the other primitive types and their corresponding wrapper classes.
However, because we want you to use the next() method of your super-class (PRNG)
as override it for the UniformRandom class,
you will be receiving an object, which must be cast in order to extract its value.

With that aside, you should override next() to return a double (Double) value between 0.0 (inclusive) and 1.0 (exclusive). You can accomplish the translation to the 0-1 range by dividing the newly generated number by your modulus using floating-point arithmetic. Because the number generated by your PRNG method from last week is the remainder of a division by the modulus, it will never be greater than or equal to the modulus. Therefore, when dividing by the modulus, the quotient will always be strictly less than 1.0. If one repeatedly calls this new method, it should generate a sequence of pseudorandom numbers in the range [0.0 .. 1.0).

This should be the only method that you will need to override from your previous class. However, if you need or want to make changes to your version of PRNG (from which UniformRandom is inheriting), feel free to do so. Be sure to include a copy of your PRNG class with your submission whether you alter it or not.

There are many applications of pseudorandom number generators.
For some of those applications,
the particular properties or characteristics of the *distribution* and *sequence*
are of critical importance.
There are a number of such characteristics,
but for this assignment we will consider only two of them:
the distribution of numbers and the pairwise relation between consecutive numbers in the sequence.

If we divide the range [0..1.0) into some number, say ten, of "bins" and assign each number in a large sample to the appropriate bin, we would hope that a good pseudorandom number generator would fill the ten bins roughly evenly. This test checks the distribution of numbers given ensuring each number in the range is as likely to be generated as the other numbers. This alone, however, is insufficient. The sequence of numbers 0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,.... perfectly distributes numbers into the ten bins but we would hardly call this a good pseudorandom sequence.

One additional check we can employ is to track the relationship between consecutive numbers. This test checks the sequence for regularities that would reflect non-randomness. If we keep track of the number of times 0 is followed by each of the ten digits (including 0), and do the same for 1, 2 and all the other numbers, we can identify evenly distributed but non-random sequences such as the one above.

Once your new class is generating numbers in the appropriate range,
we want to be able to run experiments that evaluate the distribution and sequence of resulting numbers.
Write another class, `RandomChecker`,
that has at least two methods:

that will perform tests on the given instance of a pseudorandom number generator that satisfies the RandI interface. Your checkDistribution method should return a one-dimensional array containing the counts of numbers that fell into the respective ranges or bins. Your checkSequence returns a two-dimensional array where a cell indexed by i and j contains the number of times that j followed i in the sequence. The parameters determine the number of bins to use and how many samples to generate.public int[] checkDistribution(RandI rng, int howManyBins, int testSize);

public int[][] checkSequence(RandI rng, int howManyBins, int testSize);

Because the purpose of these methods is to evaluate the ‘random’ quality of your generator,
you should write your `main` driver method
to consume three integer inputs for the multiplier, increment and modulus.
Then you will be able to run tests with different values of these parameters
and observe their impact on the distribution and sequence without recompiling.

Your main method should run checkDistribution and checkSequence on a given number of bins, say ten, over a large sample of generated random numbers, say one million. If using ten bins, you would divide the range [0..1) into ten smaller ranges: [0.. 0.1), [0.1 .. 0.2), ... [0.9 .. 1.0). Finally, print out your results in a manner such as shown in the screen shot.

Run your experiment several times with different values for the multiplier, increment, and modulus. A set of good choices for these will yield approximately 10% of the total in each range. A generator with this equal-interval behavior is called uniformly distributed. Try to find a set of values that produce a better distribution than the values recommended in Assignment 2. (Note, the initial seed value is not too important in this regard as long as you have a large sample. So don't worry too much about experimenting with that value.)

Write two additional classes.
The first, `PRNGLogistic` should extend your Logistic class from a previous lab
and should implement the `RandI` interface.
*Update 1: The logistic function, under certain values of r,
will give rise to a chaotic (random) sequence of values.
Thus it may (under certain conditions) serve as a pseudo-random number generator.
Depending on the details of your Logistic implementation from the lab,
you may need to refactor your code
so that the logistic element (what we care about)
is separated from the graphical elements (that are irrelevant for this assignment).
Ideally, you will refactor your lab code so that it works as before but as separate classes
but that is not part of the assignment.*
The second class,

Finally, modify the main method in your RandomChecker class
to compare three different types of pseudo-random number generators:
an instance of UniformRandom with the best multiplier, increment and modulus that you can find,
an instance of PRNGLogistic with the best value of *r* that you can come up with,
and an instance of PRNGBuiltIn.
In your documentation for RandomChecker,
you should report which method you found to be the best generator of random numbers.

Make sure that you create a folder named with your Westmont email name followed by "HW3". For example, someone with email address "cjones" would create a folder called "cjonesHW3". Make sure that inside that folder you have: java source files as well as html documentation files resulting from javadoc. Finally, either tar or zip the folder so that when we extract it, the folder "<emailname>HW3" will be created. Submit the packaged file for assignment 3 on Eureka.