Added RandomAdaptor to complete PRNG pluggability framework, updated User Guide.
git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/math/trunk@179494 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f1a9880905
commit
ad94c5d1de
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2005 The Apache Software Foundation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.commons.math.random;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension of <code>java.util.Random</code> wrapping a
|
||||||
|
* {@link RandomGenerator}.
|
||||||
|
*
|
||||||
|
* @since 1.1
|
||||||
|
* @version $Revision:$ $Date$
|
||||||
|
*/
|
||||||
|
public class RandomAdaptor extends Random implements RandomGenerator {
|
||||||
|
|
||||||
|
/** Wrapped randomGenerator instance */
|
||||||
|
private RandomGenerator randomGenerator = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent instantiation without a generator argument
|
||||||
|
*/
|
||||||
|
private RandomAdaptor() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a RandomAdaptor wrapping the supplied RandomGenerator.
|
||||||
|
*
|
||||||
|
* @param randomGenerator the wrapped generator
|
||||||
|
*/
|
||||||
|
public RandomAdaptor(RandomGenerator randomGenerator) {
|
||||||
|
this.randomGenerator = randomGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory method to create a <code>Random</code> using the supplied
|
||||||
|
* <code>RandomGenerator</code>.
|
||||||
|
*
|
||||||
|
* @param randomGenerator
|
||||||
|
* @return a Random instance wrapping the RandomGenerator
|
||||||
|
*/
|
||||||
|
public static Random createAdaptor(RandomGenerator randomGenerator) {
|
||||||
|
return new RandomAdaptor(randomGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.util.Random#nextBoolean()
|
||||||
|
*/
|
||||||
|
public boolean nextBoolean() {
|
||||||
|
return randomGenerator.nextBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.util.Random#nextBytes(byte[])
|
||||||
|
*/
|
||||||
|
public void nextBytes(byte[] bytes) {
|
||||||
|
randomGenerator.nextBytes(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.util.Random#nextDouble()
|
||||||
|
*/
|
||||||
|
public double nextDouble() {
|
||||||
|
return randomGenerator.nextDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.util.Random#nextFloat()
|
||||||
|
*/
|
||||||
|
public float nextFloat() {
|
||||||
|
return randomGenerator.nextFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.util.Random#nextGaussian()
|
||||||
|
*/
|
||||||
|
public double nextGaussian() {
|
||||||
|
return randomGenerator.nextGaussian();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.util.Random#nextInt()
|
||||||
|
*/
|
||||||
|
public int nextInt() {
|
||||||
|
return randomGenerator.nextInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.util.Random#nextInt(int)
|
||||||
|
*/
|
||||||
|
public int nextInt(int n) {
|
||||||
|
return randomGenerator.nextInt(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.util.Random#nextLong()
|
||||||
|
*/
|
||||||
|
public long nextLong() {
|
||||||
|
return randomGenerator.nextLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.util.Random#setSeed(long)
|
||||||
|
*/
|
||||||
|
public void setSeed(long seed) {
|
||||||
|
if (randomGenerator != null) { // required to avoid NPE in constructor
|
||||||
|
randomGenerator.setSeed(seed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2005 The Apache Software Foundation.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.commons.math.random;
|
||||||
|
import junit.framework.Test;
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test cases for the RandomAdaptor class
|
||||||
|
*
|
||||||
|
* @version $Revision:$ $Date$
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class RandomAdaptorTest extends RandomDataTest {
|
||||||
|
|
||||||
|
public RandomAdaptorTest(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Test suite() {
|
||||||
|
TestSuite suite = new TestSuite(RandomAdaptorTest.class);
|
||||||
|
suite.setName("RandomAdaptor Tests");
|
||||||
|
return suite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAdaptor() {
|
||||||
|
ConstantGenerator generator = new ConstantGenerator();
|
||||||
|
Random random = RandomAdaptor.createAdaptor(generator);
|
||||||
|
checkConstant(random);
|
||||||
|
RandomAdaptor randomAdaptor = new RandomAdaptor(generator);
|
||||||
|
checkConstant(randomAdaptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkConstant(Random random) {
|
||||||
|
byte[] bytes = new byte[] {0};
|
||||||
|
random.nextBytes(bytes);
|
||||||
|
assertEquals(0, bytes[0]);
|
||||||
|
assertEquals(false, random.nextBoolean());
|
||||||
|
assertEquals(0, random.nextDouble(), 0);
|
||||||
|
assertEquals(0, random.nextFloat(), 0);
|
||||||
|
assertEquals(0, random.nextGaussian(), 0);
|
||||||
|
assertEquals(0, random.nextInt());
|
||||||
|
assertEquals(0, random.nextInt(1));
|
||||||
|
assertEquals(0, random.nextLong());
|
||||||
|
random.setSeed(100);
|
||||||
|
assertEquals(0, random.nextDouble(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "Constant" generator to test Adaptor delegation.
|
||||||
|
* "Powered by Eclipse ;-)"
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private class ConstantGenerator implements RandomGenerator {
|
||||||
|
|
||||||
|
public boolean nextBoolean() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void nextBytes(byte[] bytes) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public double nextDouble() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float nextFloat() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double nextGaussian() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int nextInt() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int nextInt(int n) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long nextLong() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSeed(long seed) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,7 +50,8 @@
|
||||||
<li><a href="random.html#2.2 Random numbers">2.2 Random numbers</a></li>
|
<li><a href="random.html#2.2 Random numbers">2.2 Random numbers</a></li>
|
||||||
<li><a href="random.html#2.3 Random Strings">2.3 Random Strings</a></li>
|
<li><a href="random.html#2.3 Random Strings">2.3 Random Strings</a></li>
|
||||||
<li><a href="random.html#2.4 Random permutations, combinations, sampling">2.4 Random permutations, combinations, sampling</a></li>
|
<li><a href="random.html#2.4 Random permutations, combinations, sampling">2.4 Random permutations, combinations, sampling</a></li>
|
||||||
<li><a href="random.html#2.5 Generating data &apos;like&apos; an input file">2.5 Generating data 'like' an input file</a></li>
|
<li><a href="random.html#2.5 Generating data 'like' an input file">2.5 Generating data 'like' an input file</a></li>
|
||||||
|
<li><a href="random.html#2.6 PRNG Pluggability">2.6 PRNG Pluggability</a></li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
<li><a href="linear.html">3. Linear Algebra</a>
|
<li><a href="linear.html">3. Linear Algebra</a>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
|
@ -34,95 +34,130 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li>generating random numbers</li>
|
<li>generating random numbers</li>
|
||||||
<li>generating random strings</li>
|
<li>generating random strings</li>
|
||||||
<li>generating cryptographically secure sequences of random numbers or strings</li>
|
<li>generating cryptographically secure sequences of random numbers or
|
||||||
|
strings</li>
|
||||||
<li>generating random samples and permuations</li>
|
<li>generating random samples and permuations</li>
|
||||||
<li>analyzing distributions of values in an input file and generating values "like"
|
<li>analyzing distributions of values in an input file and generating
|
||||||
the values in the file</li>
|
values "like" the values in the file</li>
|
||||||
<li>generating data for grouped frequency distributions or histograms</li>
|
<li>generating data for grouped frequency distributions or
|
||||||
|
histograms</li>
|
||||||
</ul></p>
|
</ul></p>
|
||||||
|
<p>
|
||||||
|
The source of random data used by the data generation utilities is
|
||||||
|
pluggable. By default, the JDK-supplied PseudoRandom Number Generator
|
||||||
|
(PRNG) is used, but alternative generators can be "plugged in" using an
|
||||||
|
adaptor framework, which provides a generic facility for replacing
|
||||||
|
<code>java.util.Random</code> with an alternative PRNG.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Sections 2.3-2.5 below show how to use the commons math API to generate
|
||||||
|
different kinds of random data. The examples all use the default
|
||||||
|
JDK-supplied PRNG. PRNG pluggability is covered in 2.6. The only
|
||||||
|
modification required to the examples to use alternative PRNGs is to
|
||||||
|
replace the argumentless constructor calls with invocations including
|
||||||
|
a <code>RandomGenerator</code> instance as a parameter.
|
||||||
|
</p>
|
||||||
</subsection>
|
</subsection>
|
||||||
|
|
||||||
<subsection name="2.2 Random numbers" href="deviates">
|
<subsection name="2.2 Random numbers" href="deviates">
|
||||||
<p>
|
<p>
|
||||||
The <a href="../apidocs/org/apache/commons/math/random/RandomData.html">
|
The <a href="../apidocs/org/apache/commons/math/random/RandomData.html">
|
||||||
org.apache.commons.math.RandomData</a> interface defines methods for generating
|
org.apache.commons.math.RandomData</a> interface defines methods for
|
||||||
random sequences of numbers. The API contracts of these methods use the following concepts:
|
generating random sequences of numbers. The API contracts of these methods
|
||||||
|
use the following concepts:
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Random sequence of numbers from a probability distribution</dt>
|
<dt>Random sequence of numbers from a probability distribution</dt>
|
||||||
<dd>There is no such thing as a single "random number." What can be generated
|
<dd>There is no such thing as a single "random number." What can be
|
||||||
are <i>sequences</i> of numbers that appear to be random. When using the
|
generated are <i>sequences</i> of numbers that appear to be random. When
|
||||||
built-in JDK function <code>Math.random(),</code> sequences of values generated
|
using the built-in JDK function <code>Math.random(),</code> sequences of
|
||||||
follow the <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda3662.htm">
|
values generated follow the
|
||||||
Uniform Distribution</a>, which means that the values are evenly spread over the interval
|
<a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda3662.htm">
|
||||||
between 0 and 1, with no sub-interval having a greater probability of containing generated
|
Uniform Distribution</a>, which means that the values are evenly spread
|
||||||
values than any other interval of the same length. The mathematical concept of a <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm">
|
over the interval between 0 and 1, with no sub-interval having a greater
|
||||||
probability distribution</a> basically amounts to asserting that different ranges in the set
|
probability of containing generated values than any other interval of the
|
||||||
of possible values for of a random variable have different probabilities of containing the value.
|
same length. The mathematical concept of a
|
||||||
Commons Math supports generating random sequences from the following probability distributions. The
|
<a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm">
|
||||||
javadoc for the <code>nextXxx</code> methods in <code>RandomDataImpl</code> describes the algorithms used
|
probability distribution</a> basically amounts to asserting that different
|
||||||
to generate random deviates from each of these distributions.
|
ranges in the set of possible values for of a random variable have
|
||||||
|
different probabilities of containing the value. Commons Math supports
|
||||||
|
generating random sequences from the following probability distributions.
|
||||||
|
The javadoc for the <code>nextXxx</code> methods in
|
||||||
|
<code>RandomDataImpl</code> describes the algorithms used to generate
|
||||||
|
random deviates from each of these distributions.
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda3662.htm">uniform distribution</a></li>
|
<li><a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda3662.htm">
|
||||||
<li><a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda3667.htm">exponential distribution</a></li>
|
uniform distribution</a></li>
|
||||||
<li><a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda366j.htm">poisson distribution</a></li>
|
<li><a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda3667.htm">
|
||||||
<li><a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda3661.htm">Gaussian distribution</a></li>
|
exponential distribution</a></li>
|
||||||
|
<li><a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda366j.htm">
|
||||||
|
poisson distribution</a></li>
|
||||||
|
<li><a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda3661.htm">
|
||||||
|
Gaussian distribution</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</dd>
|
</dd>
|
||||||
<dt>Cryptographically secure random sequences</dt>
|
<dt>Cryptographically secure random sequences</dt>
|
||||||
<dd>It is possible for a sequence of numbers to appear random, but nonetheless to be
|
<dd>It is possible for a sequence of numbers to appear random, but
|
||||||
predictable based on the algorithm used to generate the sequence. If in addition to
|
nonetheless to be predictable based on the algorithm used to generate the
|
||||||
randomness, strong unpredictability is required, it is best to use a
|
sequence. If in addition to randomness, strong unpredictability is
|
||||||
|
required, it is best to use a
|
||||||
<a href="http://www.wikipedia.org/wiki/Cryptographically_secure_pseudo-random_number_generator">
|
<a href="http://www.wikipedia.org/wiki/Cryptographically_secure_pseudo-random_number_generator">
|
||||||
secure random number generator</a> to generate values (or strings). The nextSecureXxx methods
|
secure random number generator</a> to generate values (or strings). The
|
||||||
in the <code>RandomDataImpl</code> implementation of the <code>RandomData</code> interface use the
|
nextSecureXxx methods in the <code>RandomDataImpl</code> implementation of
|
||||||
JDK <code>SecureRandom</code> pseudo-random number generator (PRNG)
|
the <code>RandomData</code> interface use the JDK <code>SecureRandom</code>
|
||||||
to generate cryptographically secure sequences. The <code>setSecureAlgorithm</code> method
|
PRNG to generate cryptographically secure sequences. The
|
||||||
allows you to change the underlying PRNG. These methods are <strong>much slower</strong> than
|
<code>setSecureAlgorithm</code> method allows you to change the underlying
|
||||||
the corresponding "non-secure" versions, so they should only be used when cryptographic security
|
PRNG. These methods are <strong>much slower</strong> than the corresponding
|
||||||
is required.</dd>
|
"non-secure" versions, so they should only be used when cryptographic
|
||||||
|
security is required.</dd>
|
||||||
<dt>Seeding pseudo-random number generators</dt>
|
<dt>Seeding pseudo-random number generators</dt>
|
||||||
<dd>By default, the implementation provided in <code>RandomDataImpl</code> uses the JDK-provided
|
<dd>By default, the implementation provided in <code>RandomDataImpl</code>
|
||||||
PRNG. Like other PRNGs, the JDK generator generates sequences of random numbers based on an initial
|
uses the JDK-provided PRNG. Like most other PRNGs, the JDK generator
|
||||||
"seed value". For the non-secure methods, starting with the same seed always produces the same
|
generates sequences of random numbers based on an initial "seed value".
|
||||||
sequence of values. Secure sequences started with the same seeds will diverge. When a new
|
For the non-secure methods, starting with the same seed always produces the
|
||||||
<code>RandomDataImpl</code> is created, the underlying random number generators are
|
same sequence of values. Secure sequences started with the same seeds will
|
||||||
<strong>not</strong> intialized. The first call to a data generation method, or to a
|
diverge. When a new <code>RandomDataImpl</code> is created, the underlying
|
||||||
<code>reSeed()</code> method initializes the appropriate generator. If you do not explicitly
|
random number generators are <strong>not</strong> intialized. The first
|
||||||
seed the generator, it is by default seeded with the current time in milliseconds. Therefore,
|
call to a data generation method, or to a <code>reSeed()</code> method
|
||||||
to generate sequences of random data values, you should always instantiate <strong>one</strong>
|
initializes the appropriate generator. If you do not explicitly seed the
|
||||||
<code>RandomDataImpl</code> and use it repeatedly instead of creating new instances for
|
generator, it is by default seeded with the current time in milliseconds.
|
||||||
subsequent values in the sequence. For example, the following will generate a random sequence
|
Therefore, to generate sequences of random data values, you should always
|
||||||
of 50 long integers between 1 and 1,000,000, using the current time in milliseconds as the seed
|
instantiate <strong>one</strong> <code>RandomDataImpl</code> and use it
|
||||||
for the JDK PRNG:
|
repeatedly instead of creating new instances for subsequent values in the
|
||||||
|
sequence. For example, the following will generate a random sequence of 50
|
||||||
|
long integers between 1 and 1,000,000, using the current time in
|
||||||
|
milliseconds as the seed for the JDK PRNG:
|
||||||
<source>
|
<source>
|
||||||
RandomDataImpl randomData = new RandomDataImpl();
|
RandomDataImpl randomData = new RandomDataImpl();
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
value = randomData.nextLong(1, 1000000);
|
value = randomData.nextLong(1, 1000000);
|
||||||
}
|
}
|
||||||
</source>
|
</source>
|
||||||
The following will not in general produce a good random sequence, since the PRNG is reseeded
|
The following will not in general produce a good random sequence, since the
|
||||||
each time through the loop with the current time in milliseconds:
|
PRNG is reseeded each time through the loop with the current time in
|
||||||
|
milliseconds:
|
||||||
<source>
|
<source>
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
RandomDataImpl randomData = new RandomDataImpl();
|
RandomDataImpl randomData = new RandomDataImpl();
|
||||||
value = randomData.nextLong(1, 1000000);
|
value = randomData.nextLong(1, 1000000);
|
||||||
}
|
}
|
||||||
</source>
|
</source>
|
||||||
The following will produce the same random sequence each time it is executed:
|
The following will produce the same random sequence each time it is
|
||||||
|
executed:
|
||||||
<source>
|
<source>
|
||||||
RandomDataImpl randomData = new RandomDataImpl();
|
RandomDataImpl randomData = new RandomDataImpl();
|
||||||
randomData.reSeed(1000);
|
randomData.reSeed(1000);
|
||||||
for (int i = 0; i = 1000; i++) {
|
for (int i = 0; i = 1000; i++) {
|
||||||
value = randomData.nextLong(1, 1000000);
|
value = randomData.nextLong(1, 1000000);
|
||||||
}
|
}
|
||||||
</source>
|
</source>
|
||||||
The following will produce a different random sequence each time it is executed.
|
The following will produce a different random sequence each time it is
|
||||||
|
executed.
|
||||||
<source>
|
<source>
|
||||||
RandomDataImpl randomData = new RandomDataImpl();
|
RandomDataImpl randomData = new RandomDataImpl();
|
||||||
randomData.reSeedSecure(1000);
|
randomData.reSeedSecure(1000);
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
value = randomData.nextSecureLong(1, 1000000);
|
value = randomData.nextSecureLong(1, 1000000);
|
||||||
}
|
}
|
||||||
</source>
|
</source>
|
||||||
</dd></dl>
|
</dd></dl>
|
||||||
</p>
|
</p>
|
||||||
|
@ -228,6 +263,87 @@
|
||||||
</p>
|
</p>
|
||||||
</subsection>
|
</subsection>
|
||||||
|
|
||||||
|
<subsection name="2.6 PRNG Pluggability" href="pluggability">
|
||||||
|
<p>
|
||||||
|
To enable alternative PRNGs to be "plugged in" to the commons-math data
|
||||||
|
generation utilities and to provide a generic means to replace
|
||||||
|
<code>java.util.Random</code> in applications, a random generator
|
||||||
|
adaptor framework has been added to commons-math. The
|
||||||
|
<a href="../apidocs/org/apache/commons/math/random/RandomGenerator.html">
|
||||||
|
org.apache.commons.math.RandomGenerator</a> interface abstracts the public
|
||||||
|
interface of <code>java.util.Random</code> and any implementation of this
|
||||||
|
interface can be used as the source of random data for the commons-math
|
||||||
|
data generation classes. An abstract superclass,
|
||||||
|
<a href="../apidocs/org/apache/commons/math/random/AbstractRandomGenerator.html">
|
||||||
|
org.apache.commons.math.AbstractRandomGenerator</a> is provided to make
|
||||||
|
implementation easier. This class provides default implementations of
|
||||||
|
"derived" data generation methods based on the primitive,
|
||||||
|
<code>nextDouble().</code> To support generic replacement of
|
||||||
|
<code>java.util.Random</code>, the
|
||||||
|
<a href="../apidocs/org/apache/commons/math/random/RandomAdaptor.html">
|
||||||
|
org.apache.commons.math.RandomAdaptor</a> class is provided, which
|
||||||
|
extends <code>java.util.Random</code> and wraps and delegates calls to
|
||||||
|
a <code>RandomGenerator</code> instance.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Examples:
|
||||||
|
<dl>
|
||||||
|
<dt>Create a RandomGenerator based on RngPack's Mersenne Twister</dt>
|
||||||
|
<dd>To create a RandomGenerator using the RngPack Mersenne Twister PRNG
|
||||||
|
as the source of randomness, extend <code>AbstractRandomGenerator</code>
|
||||||
|
overriding the derived methods that the RngPack implementation provides:
|
||||||
|
<source>
|
||||||
|
import edu.cornell.lassp.houle.RngPack.RanMT;
|
||||||
|
/**
|
||||||
|
* AbstractRandomGenerator based on RngPack RanMT generator.
|
||||||
|
*/
|
||||||
|
public class RngPackGenerator extends AbstractRandomGenerator {
|
||||||
|
|
||||||
|
private RanMT random = new RanMT();
|
||||||
|
|
||||||
|
public void setSeed(long seed) {
|
||||||
|
random = new RanMT(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double nextDouble() {
|
||||||
|
return random.raw();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double nextGaussian() {
|
||||||
|
return random.gaussian();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int nextInt(int n) {
|
||||||
|
return random.choose(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean nextBoolean() {
|
||||||
|
return random.coin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</source>
|
||||||
|
</dd>
|
||||||
|
<dt>Use the Mersenne Twister RandomGenerator in place of
|
||||||
|
<code>java.util.Random</code> in <code>RandomData</code></dt>
|
||||||
|
<dd>
|
||||||
|
<source>
|
||||||
|
RandomData randomData = new RandomDataImpl(new RngPackGenerator());
|
||||||
|
</source>
|
||||||
|
</dd>
|
||||||
|
<dt>Create an adaptor instance based on the Mersenne Twister generator
|
||||||
|
that can be used in place of a <code>Random</code></dt>
|
||||||
|
<dd>
|
||||||
|
<source>
|
||||||
|
RandomGenerator generator = new RngPackGenerator();
|
||||||
|
Random random = RandomAdaptor.createAdaptor(generator);
|
||||||
|
// random can now be used in place of a Random instance, data generation
|
||||||
|
// calls will be delegated to the wrapped Mersenne Twister
|
||||||
|
</source>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</p>
|
||||||
|
</subsection>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
Loading…
Reference in New Issue