Skip to content
PRNGine - Pseudo Random Number Engines for Monte Carlo simulations
Java C++ Other
Branch: master
Clone or download

Latest commit

Fetching latest commit…
Cannot retrieve the latest commit at this time.

Files

Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
gradle/wrapper
prngine
.gitignore
.travis.yml
LICENSE.txt
NOTICE.txt
README.md
build.gradle
dieharder.md
gradlew
gradlew.bat
jrun
jrun.cmd
random_seeding.adoc
settings.gradle

README.md

PRNGine

Build Status Maven Central Javadoc Code Quality: Java Total Alerts

PRNGine is a pseudo-random number generator library for sequential and parallel Monte Carlo simulations. It has been designed to work smoothly with the Jenetics GA library, but it has no dependency to it. All PRNG implementations of this library extends the Java Random class, which makes it easily usable in other projects. The PRNGs are not cryptographically strong RNGs.

The following PRNGs are currently implemented:

  • KISS32Random: Implementation of an simple PRNG as proposed in Good Practice in (Pseudo) Random Number Generation for Bioinformatics Applications (JKISS32, page 3) David Jones, UCL Bioinformatics Group.
  • KISS64Random: Implementation of an simple PRNG as proposed in Good Practice in (Pseudo) Random Number Generation for Bioinformatics Applications (JKISS64, page 10) David Jones, UCL Bioinformatics Group.
  • LCG64ShiftRandom: This class implements a linear congruential PRNG with additional bit-shift transition. It is a port of the trng::lcg64_shift PRNG class of the TRNG library created by Heiko Bauke.
  • MT19937_32Random: This is a 32-bit version of Mersenne Twister pseudorandom number generator.
  • MT19937_64Random: This is a 64-bit version of Mersenne Twister pseudorandom number generator.
  • XOR32ShiftRandom: This generator was discovered and characterized by George Marsaglia [Xorshift RNGs]. In just three XORs and three shifts (generally fast operations) it produces a full period of 232 - 1 on 32 bits. (The missing value is zero, which perpetuates itself and must be avoided.) High and low bits pass Diehard.
  • XOR64ShiftRandom: This generator was discovered and characterized by George Marsaglia [Xorshift RNGs]. In just three XORs and three shifts (generally fast operations) it produces a full period of 264 - 1 on 64 bits. (The missing value is zero, which perpetuates itself and must be avoided.) High and low bits pass Diehard.

Requirements

  • JRE 8: Java runtime version 8 is needed for using the library.

Building PRNGine

For building the PRNGine library you have to check out the master branch from Github.

$ git clone https://github.com/jenetics/prngine.git

Executing the tests:

$ cd prngine
$ ./gradle test

Building the library:

$ ./gradle jar

Examples

PRN creation

Every PRNG of the library comes in three flavours, a un-synchronized base implementation, a synchronized implementation and in a thread-local implementation.

Un-synchronized base implementation with the naming scheme XXXRandom:

final Random random = new LCG64ShiftRandom();
random.doubles(10).forEach(System.out::println);

Synchronized implementation with the naming scheme XXXRandom.ThreadSafe:

final Random random = new LCG64ShiftRandom.ThreadSafe();
final Runnable runnable = () -> random.doubles(10).forEach(System.out::println);

final ExecutionService executor = ...;
for (int i = 0; i < 10; ++i) {
	executor.submit(runnable);
}

ThreadLocal implementation with the naming scheme XXXRandom.ThreadLocal:

static final ThreadLocal<? extends Random> random = 
    new LCG64ShiftRandom.ThreadLocal();

final Runnable runnable = () -> random.get()
    .doubles(10).forEach(System.out::println);

final ExecutionService executor = ...;
for (int i = 0; i < 10; ++i) {
	executor.submit(runnable);
}

PRNG seeding

The library also contains methods for creating random seed values, which can be used for initializing the available PRNGs.

// Creating a new 64 bit seed value.
final long seed = PRNG.seed();
final Random ranomd = new LCG64ShiftRandom(seed);

A more detailed description of how the seeding is implemented can be found here. Every random engine has a seedBytes() method, which return the seed byte[] array with the length required by the PRNG.

// This random creation is equivalent to...
final Random random1 = new LCG64ShiftRandom();

// ...creating it with the seed bytes of the PRNG. 
final byte[] seed = LCG64ShiftRandom.seedBytes();
final Random random2 = new LCG53ShiftRandom(seed);

Test results

Statistical tests (dieharder)

All implemented PRNGs has been tested with the dieharder test suite.

PRNG Passed Weak Failed
KISS32Random 108 6 0
KISS64Random 109 5 0
LCG64ShiftRandom 110 4 0
MT19937_32Random 113 1 0
MT19937_64Random 111 3 0
XOR32ShiftRandom 101 4 9
XOR64ShiftRandom 107 7 0
java.util.Random 106 4 4

Runtime performance tests

The runtime performance of the PRNGs was tested with the JMH testing framework on an Intel Core i7-6700HQ CPU @ 2.60GHz with Java SE Runtime Environment (build 1.8.0_112-b15)—Java HotSpot.

PRNG 106 ints/s 106 floats/s 106 longs/s 106 doubles/s
KISS32Random 189 143 129 108
KISS64Random 128 124 115 124
LCG64ShiftRandom 258 185 261 191
MT19937_32Random 140 115 92 82
MT19937_64Random 148 120 148 120
XOR32ShiftRandom 227 161 140 120
XOR64ShiftRandom 225 166 235 166
java.util.Random 91 89 46 46

License

The library is licensed under the Apache License, Version 2.0.

Copyright 2017-2019 Franz Wilhelmstötter

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.

Release notes

1.0.2

Improvements

  • #21: Update Gradle version and add CI build for Java 11.

Bugs

1.0.1

Improvements

  • #3: Define stable module name. Set the Automatic-Module-Name to io.jenetics.prngine.
You can’t perform that action at this time.