\[ \begin{aligned} R_{1,i} & = (1,403,580 R_{1,i-2} - 810,728 R_{1,i-3})\bmod (2^{32}-209)\\ R_{2,i} & = (527,612R_{2,i-1} - 1,370,589 R_{2,i-3})\bmod (2^{32}-22,853)\\ Y_i & = (R_{1,i}-R_{2,i})\bmod(2^{32}-209)\\ U_i & = \frac{Y_i}{2^{32}-209} \end{aligned} \]
Random Number Stream Interfaces
RNStreamProvider and ask it for a stream.randU01() function to get pseudo-random numbers uniformly distributed between 0 and 1.fun main() {
// make a provider for creating streams
val p1 = RNStreamProvider()
// get the first stream from the provider
val p1s1 = p1.rnStream(streamNum = 1)
// make another provider, the providers are identical
val p2 = RNStreamProvider()
// Thus, the first streams returned are identical
val p2s1 = p2.rnStream(streamNum = 1)
print(String.format("%3s %15s %15s %n", "n", "p1s1", "p2s1"))
for (i in 1..5) {
print(String.format("%3d %15f %15f %n", i, p1s1.randU01(), p2s1.randU01()))
}
}p1s1 and p2s2 produce the same sequence of random numbers because they were created from two different instances of RNStreamProvider that have the same initial starting state (seeds). n p1s1 p2s1
1 0.127011 0.127011
2 0.318528 0.318528
3 0.309186 0.309186
4 0.825847 0.825847
5 0.221630 0.221630
RNStreamProvider InterfaceThe RNStreamProvider has a well-define set of functions to get streams and to control the behavior of streams that it produced.
nextRNStream() - returns the next random number stream associated with the provider. Each call to nextRNStream() makes a new stream in the sequence of streams.lastRNStreamNumber() - returns the number of the stream that was last made. This indicates how many streams have been made. If \(0\) is returned, then no streams have been made by the provider.rnStream(k : Int) - returns the \(k^{th}\) stream. If \(k\) is greater than lastRNStreamNumber() then lastRNStreamNumber() is advanced according to the additional number of streams by creating any intermediate streams.streamNumber(RNStreamIfc stream) - returns the stream number of the instance of a stream.advanceStreamMechanism(int n) - advances the underlying stream mechanism by the specified number of streams, without actually creating the streams.resetRNStreamSequence() - Causes the random number stream provider to act as if has never created any streams.RNStreamControlIfc InterfaceThe RNStreamProvider creates and instance of a stream that implements the RNStreamIfc interface, which has a well-defined set of functions for moving and manipulating the stream.
resetStartStream() - positions the random number stream at the beginning of its sequence This is the same location in the stream as assigned when the random number stream was created and initialized.resetStartSubstream() - resets the position of the random number stream to the start of the current substream. If the random number stream has advanced into the substream, then this method resets to the beginning of the substream.advanceToNextSubStream() - positions the random number stream at the beginning of its next substream. This method move through the current substream and positions the stream at the beginning of the next substream.antithetic indicates to the stream to start producing antithetic variates. If the option is true, the stream should start producing antithetic variates with the next call to randU01(). If the option is false, the stream should stop producing antithetic variates.KSLRandom ObjectThe KSLRandom object has a default RNStreamProvider that can be used to get stream.
nextRNStream() - calls the underlying default RNStreamProvider to create a new random number streamrnStream(int k) - returns the \(k^{th}\) stream from the default RNStreamProviderdefaultRNStream() - calls the underlying default RNStreamProvider for its default streamfun main() {
val s1 = KSLRandom.defaultRNStream()
s1.advanceToNextSubStream()
println("Advance to next sub-stream and get some more random numbers")
for (i in 1..3) {
println("u = " + s1.randU01())
}
println("Notice that they are different from the first 3.")
s1.resetStartStream()
println("Reset the stream to the beginning of its sequence")
for (i in 1..3) {
println("u = " + s1.randU01())
}
println("Notice that they are the same as the first 3.")
println("Get another random number stream")
val s2 = KSLRandom.nextRNStream()
println("2nd stream")
for (i in 1..3) {
println("u = " + s2.randU01())
}
println("Notice that they are different from the first 3.")
}RNStreamProvider or clone the stream to implement CRN. n U U again
1 0.127011 0.127011
2 0.318528 0.318528
3 0.309186 0.309186
resetStartStream() method of the stream to reset the stream to the desired location in its sequence and then reproduce the random numbers.fun main() {
val s = KSLRandom.defaultRNStream()
// generate regular
print(String.format("%3s %15s %n", "n", "U"))
for (i in 1..3) {
val u = s.randU01()
print(String.format("%3d %15f %n", i, u))
}
// reset the stream and generate again
s.resetStartStream()
println()
print(String.format("%3s %15s %n", "n", "U again"))
for (i in 1..3) {
val u = s.randU01()
print(String.format("%3d %15f %n", i, u))
}
} n U
1 0.127011
2 0.318528
3 0.309186
n U again
1 0.127011
2 0.318528
3 0.309186
antitheticInstance() method.fun main() {
// get the default stream
val s = KSLRandom.defaultRNStream()
// make its antithetic version
val ans = s.antitheticInstance()
print(String.format("%3s %15s %15s %15s %n", "n", "U", "1-U", "sum"))
for (i in 1..5) {
val u = s.randU01()
val au = ans.randU01()
print(String.format("%3d %15f %15f %15f %n", i, u, au, u + au))
}
} n U 1-U sum
1 0.127011 0.872989 1.000000
2 0.318528 0.681472 1.000000
3 0.309186 0.690814 1.000000
4 0.825847 0.174153 1.000000
5 0.221630 0.778370 1.000000
resetStartStream() method and the antithetic property of the current stream.fun main() {
val s = KSLRandom.defaultRNStream()
s.resetStartStream()
// generate regular
print(String.format("%3s %15s %n", "n", "U"))
for (i in 1..5) {
val u = s.randU01()
System.out.printf("%3d %15f %n", i, u)
}
// generate antithetic
s.resetStartStream()
s.antithetic = true
println()
print(String.format("%3s %15s %n", "n", "1-U"))
for (i in 1..5) {
val u = s.randU01()
print(String.format("%3d %15f %n", i, u))
}
} n U
1 0.127011
2 0.318528
3 0.309186
4 0.825847
5 0.221630
n 1-U
1 0.872989
2 0.681472
3 0.690814
4 0.174153
5 0.778370