3.3 Creating and Using Random Variables

The following example code illustrates how to create a normal random variable and how to generate values.

// create a normal mean = 20.0, variance = 4.0 random variable
NormalRV n = new NormalRV(20.0, 4.0);
System.out.printf("%3s %15s %n", "n", "Values");
// generate some values
for (int i = 0; i < 5; i++) {
    // getValue() method returns generated values
    double x = n.getValue();
    System.out.printf("%3d %15f %n", i+1, x);
}

The resulting output is what you would expect.

  n          Values 
  1       21.216624 
  2       23.639128 
  3       25.335884 
  4       17.599163 
  5       23.858350 

Alternatively, the user can use the sample() method to generate an array of values that can be later processed. The following code illustrates how to do that with a triangular distribution.

// create a triangular random variable with min = 2.0, mode = 5.0, max = 10.0
TriangularRV t = new TriangularRV(2.0, 5.0, 10.0);
// sample 5 values
double[] sample = t.sample(5);
System.out.printf("%3s %15s %n", "n", "Values");
for (int i = 0; i < sample.length; i++) {
    System.out.printf("%3d %15f %n", i+1, sample[i]);
}

Again, the output is what we would expect.

  n          Values 
  1        3.515540 
  2        6.327783 
  3        4.382075 
  4        7.392228 
  5        8.409238 

It is important to note that the full range of functionality related to stream control is also available for random variables. That is, the underlying stream can be reset to its start, can be advanced to the next substream, can generate antithetic variates, etc. Each new instance of a random variable is supplied with its own unique stream that is not shared with another other random variable instances. Since this underlying random number generator has an enormous number of streams, approximately \(1.8 \times 10^{19}\), it is very unlikely that the user will create so many streams as to start reusing them. However, the streams that are used by random variable instances can be supplied directly so that they may be shared. The following following code example illustrates how to assign a specific stream by passing a specific stream instance into the constructor of the random variable.

// get stream 3
RNStreamIfc stream = JSLRandom.rnStream(3);
// create a normal mean = 20.0, variance = 4.0, with the stream
NormalRV n = new NormalRV(20.0, 4.0, stream);
System.out.printf("%3s %15s %n", "n", "Values");
for (int i = 0; i < 5; i++) {
    // getValue() method returns generated values
    double x = n.getValue();
    System.out.printf("%3d %15f %n", i+1, x);
}

As a final example, the discrete empirical distribution requires a little more setup. The user must supply the set of values that can be generated as well as an array holding the cumulative distribution probability across the values. The following code illustrates how to do this.

// values is the set of possible values
double[] values = {1.0, 2.0, 3.0, 4.0};
// cdf is the cumulative distribution function over the values
double[] cdf = {1.0/6.0, 3.0/6.0, 5.0/6.0, 1.0};
//create a discrete empirical random variable
DEmpiricalRV n1 = new DEmpiricalRV(values, cdf);
System.out.println(n1);
System.out.printf("%3s %15s %n", "n", "Values");
for (int i = 1; i <= 5; i++) {
    System.out.printf("%3d %15f %n", i+1, n1.getValue());
}

While the preferred method for generating random values from random variables is to create instance of the appropriate random variable class, the JSL also provide a set of functions for generating random values within the JSLRandom class. For all the previously listed random variables, there is a corresponding function that will generate a random value. For example, the method rNormal() will generate a normally distributed value. Each method is named with an "r" in front of the distribution name. By using static import of JSLRandom the user can more conveniently call these methods. The following code example illustrates how to do this.

// use import static jsl.utilities.random.rvariable.JSLRandom.*;
// at the top of your java file
double v = rUniform(10.0, 15.0); // generate a U(10, 15) value
double x = rNormal(5.0, 2.0); // generate a Normal(mu=5.0, var= 2.0) value
double n = rPoisson(4.0); //generate from a Poisson(mu=4.0) value
System.out.printf("v = %f, x = %f, n = %f %n", v, x, n);

In addition to random values through these static methods, the JSLRandom class provides a set of methods for randomly selecting from arrays and lists and for creating permutations of arrays and lists. In addition, there is a set of methods for sampling from arrays and lists without replacement. The following code provide examples of using these methods.

// create a list
List<String> strings = Arrays.asList("A", "B", "C", "D");
// randomly pick from the list, with equal probability
for (int i=1; i<=5; i++){
    System.out.println(randomlySelect(strings));
}

// create an array to hold a population of values
double[] y = new double[10];
for (int i = 0; i < 10; i++) {
    y[i] = i + 1;
}

// create the population
DPopulation p = new DPopulation(y);
System.out.println(p);

// permute the population
p.permute();
System.out.println(p);

// directly permute the array using JSLRandom
System.out.println("Permuting y");
JSLRandom.permutation(y);
System.out.println(DPopulation.toString(y));

// sample from the population
double[] x = p.sample(5);
System.out.println("Sampling 5 from the population");
System.out.println(DPopulation.toString(x));

// create a string list and permute it
List<String> strList = new ArrayList<>();
strList.add("a");
strList.add("b");
strList.add("c");
strList.add("d");
System.out.println(strList);
JSLRandom.permutation(strList);
System.out.println(strList);