MTRandom64 has functions to produce 32-, 64- and 128-bit integers, as well as 53-bit precision reals. In all, MTRandom64 provides eight equidistribution generator functions and seven initializing methods. Saving a generator's state to a file and loading it later is simple.
MTRandom64 has been successfully tested against the original MT authors' mt19937-64.c code by generating 100 million integers and 100 million reals with both, and comparing the entire outputs.
MTRandom64 passes George Marsalia's Diehard tests.
MTRandom64 implements MT as a VB class. Code is included in a separate file to demonstrate use of the VB class in your program. Test code for the class is also included to duplicate the original authors' mt19937-64.out.txt file.
MTRandom64 will not compile with VB 6 or earlier.
This MTRandom64 (mt19937-64.vb) release is version 1.7, dated 2014-06-18.
FILE CONTENTS
------------------------ ---------------------------------------------------
mt19937-64.vb The only file necessary to use the PRNGs. It
consists of one Visual Basic .NET PRNG class:
MTRandom64; and some exception classes used by
MTRandom64.
Main.vb The original MT authors' test duplicated in VB .NET;
it also calls the following modules:
MakeEntropyTestData64.vb Makes a file to test with John Walker's 'ent.exe'
entropy and chi-squared program available at
http://www.fourmilab.ch/random/
MakeDiehardData64.vb Makes a file to test with George Marsaglia's
Diehard tests
Test_init_by_crypto64.vb Produces a binary file of the initialization values
from init_by_crypto64().
Demo64.vb Demonstrates how to initialize and use the PRNGs
PerformanceTest64.vb A performance test
MersenneTwister64.vbproj VB Project file for Visual Basic 2012. It likely
won't work with Visual Basic 2010 or earlier. For
VB 2005-2010 make an empty console project
and add to it the *.vb files named above.
mt19937-64.vb (for Visual Basic .NET), by Ron Charlton, based on
C code that is Copyright (c) 2004 by Takuji Nishimura and Makoto
Matsumoto. mt19937-64.vb is Copyright (c) 2014 by Ron Charlton.
The C source code comments below have detailed redistribution
requirements and disclaimers that apply to mt19937-64.vb.
This file implements the 64-bit Mersenne Twister (MT), mt19937-64,
pseudorandom number generator (PRNG) as a Visual Basic .NET (VB)
class. Its period is 2^19937-1; approximately 10^6002.
It is equidistributed in 311 dimensions.
TO USE 64-bit Mersenne Twister in your VB project:
1) Add only this file, mt19937-64.vb, to your VB project
2) Check "Remove Integer Overflow Checks" for your project in
SolutionExplorer-MyProject-Compile-AdvancedCompilerOptions...
3) mt19937-64.vb has a genrand64_int128SignedInt() function
that REQUIRES VB 2010 or later for data type BigInteger.
The function is disabled by default. If you want to use
genrand64_int128SignedInt() do the following:
a) Add a project reference to BigInteger with
Visual Basic menu item
[VB 2010] Project/AddReference/.NET/System.Numerics
[VB 2012] Project/AddReference/Assemblies/Framework/System.Numerics
b) Set Need128bitInts to True below.
Set to True if you need genrand64_int128SignedInt() with Visual
Basic 2010 or later. Set it to False otherwise (must be False
for Visual Basic 2008 or earlier).
#Const Need128bitInts = False
(Also set the #Const in Demo64.vb if you include that file in a
project.)
Important information follows in these header comments. Please
skim them if you have trouble with MTRandom64.
To see a list of PRNGs herein, search for "FUNCTIONS:" (no quotes).
To see instructions for using the PRNGs, search for "USE:" (no quotes).
To see performance results, search for "PERFORMANCE:" (no quotes).
Class MTRandom64 was implemented in two steps:
1) A C-program for MT19937-64 (2004/9/29 version). Coded by Takuji
Nishimura and Makoto Matsumoto.
2) Translation from C (mt19937-64.c) to Visual Basic .NET was made
and tested by me, Ron Charlton (2014-02-18). I also translated
genrand64_intMax() from C++ code by Richard J. Wagner and Magnus
Jonsson.
Ron Charlton
9002 Balcor Circle
Knoxville, TN 37923-2301 USA
Email: Ron @ RonCharlton.org (remove spaces)
Home Page: http://RonCharlton.org/
Start Date: 2014-02-18
Bug reports, improvements, corrections, complaints or kudos are welcomed.
The C version, mt19937-64.c, was obtained via a link at
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html on 2014-02-17.
For cryptographically secure random number generation, search
Visual Basic .NET Help for "RNGCryptoServiceProvider class". Or
see http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/efaq.html.
I compared the Visual Basic .NET Main()'s output file,
"mt19937-64VBTest.out.txt", to file "mt19937-64.out.txt" from
the original MT authors' web site. The files are identical.
(See "USE:" below for details.)
I also modified the original mt19937-64test.c code and VB Main() to
produce 100,000,000 random integers and 100,000,000 random reals.
The C & VB genrand64_int64() outputs were identical.
The genrand64_real2() VB output was different from the C output for
7 reals out of 100,000,000. BUT THE DIFFERENCE IS AN ILLUSION
caused by VB and C rounding differences when converting to
a string.
I compared 100,000,000 genrand64_real2() outputs for C and VB by
using a VB union to show the VB genrand64_real2() output bit
patterns in hexadecimal. The 100,000,000 hexadecimal outputs for
C and VB genrand64_real2() are identical.
VB Format() rounds all Double outputs to no more than 15
places, regardless of the Format() string. The 7 reals out of
100,000,000 where VB differed are explained by printing them
to 14 decimal places:
C: 0.73880033999999 VB: 0.73880034000000
C: 0.58501159999999 VB: 0.58501160000000
C: 0.77837456999999 VB: 0.77837457000000
C: 0.90141489999999 VB: 0.90141490000000
C: 0.45203357999999 VB: 0.45203358000000
C: 0.51149137999999 VB: 0.51149138000000
C: 0.13164961999999 VB: 0.13164962000000
Note: In Visual Basic 2012, 2010, 2008 and 2005 --
Data type Integer has a range of -2^31 inclusive to 2^31-1 inclusive.
Data type UInteger has a range of 0 inclusive to 2^32-1 inclusive.
Data type Long has a range of -2^63 inclusive to 2^63-1 inclusive.
Data type ULong has a range of 0 inclusive to 2^64-1 inclusive.
Data type BigInteger has an unlimited range and is signed
Comments (with redistribution requirements and disclaimers) from
the original MT authors' C source code (mt19337-64.c) follow.
/*
A C-program for MT19937-64 (2004/9/29 version).
Coded by Takuji Nishimura and Makoto Matsumoto.
This is a 64-bit version of Mersenne Twister pseudorandom number
generator.
Before using, initialize the state by using init_genrand64(seed)
or init_by_array64(init_key, key_length).
Copyright (C) 2004, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
References:
T. Nishimura, ``Tables of 64-bit Mersenne Twisters''
ACM Transactions on Modeling and
Computer Simulation 10. (2000) 348--357.
M. Matsumoto and T. Nishimura,
``Mersenne Twister: a 623-dimensionally equidistributed
uniform pseudorandom number generator''
ACM Transactions on Modeling and
Computer Simulation 8. (Jan. 1998) 3--30.
Any feedback is very welcome.
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove spaces)
*/
[End mt19937-64.c comments]
The redistribution requirements and the disclaimers above
apply to this file, mt19937-64.vb, and to its author as
a contributor.
It would be nice to CC: rjwagner@writeme.com and Ron @ RonCharlton.org
when you write to the original authors.
---
_________________________________________________________________________________________
FUNCTIONS:
Function Returns values in the range:
------------------------- -------------------------------------------------------
genrand64_int64() [0,18446744073709551615] (0 to 2^64-1)
genrand64_int63() [0,9223372036854775807] (0 to 2^63-1)
genrand64_real1() [0.0,1.0] (both 0.0 and 1.0 included)
genrand64_real2() [0.0,1.0) (0.0 included, 1.0 excluded)
genrand64_real3() (0.0,1.0) (both 0.0 and 1.0 excluded)
The following three functions were added by Ron Charlton for Visual Basic .NET.
genrand64_intMax(upper) [0,upper] for upper < 2^64
(0 to 18446744073709551615 but <= upper)
genrand64_intRange(lower,upper) [lower,upper] for 0 <= lower <= upper < 2^64
(0 <= lower <= upper <= 18446744073709551615)
Optional:
genrand64_int128SignedInt() [-2^127,2^127-1]
(-170141183460469231731687303715884105728 to
170141183460469231731687303715884105727)
_________________________________________________________________________________________
OPERATORS:
Operator =(ByVal v As MTRandom64, ByVal w As MTRandom64) As Boolean
Operator <>(ByVal v As MTRandom64, ByVal w As MTRandom64) As Boolean
_________________________________________________________________________________________
SUBS:
Sub Argument
------------------------ ---------------------------------------------------------
init_genrand64(seed) any seed included in [0,18446744073709551615]
init_by_array64(array) array has elements of type ULong;
the array must have at least one element
These four Subs were added for the Visual Basic .NET version.
init_by_array32(array) array has elements of type UInteger;
the array must have at least two elements
init_by_MTRandom64(r) r is another MTRandom64 instance
init_by_random64(boolean) True: reseed VB Random from the system clock,
then reseed MTRandom64 from VB Random
False: use the next two values from VB Random to
reseed MTRandom64
init_by_crypto64(0.0) 0.0 (cryptographically randomize the
PRNG state; this DOES NOT make mt19937-64
cryptographically secure, it provides the
full range of possible initialized states/
sequences). Changing the argument value
(not its type) will not affect initialization
saveState64("fileName") any valid file name (creates an XML file)
loadState64("fileName") name of any file saved earlier with saveState()
_________________________________________________________________________________________
USE:
In your Visual Basic .NET application:
1) Add this file to your Visual Basic .NET project.
2) Remove Integer Overflow Checks (detailed at the top of this file).
3) Optional: For genrand64_int128SignedInt() with VB2010 and later, add
a project reference to BigInteger with menu item
[VB 2010] Project/AddReference/.NET/System.Numerics
[VB 2012] Project/AddReference/Assemblies/Framework/System.Numerics
Set the #Const assignment near the first of this file as appropriate.
4) Create one or more instances of the MTRandom64 class. The pseudorandom
sequence for each instance is initialized based on the arguments.
Make certain each instance stays in scope for the duration of its use so
it won't be re-initialized inadvertently. Seven different methods of
initialization are:
a) Dim r As New MTRandom64()
Initialize with seed == 5489 (the original MT
authors' default seed).
b) Dim r As New MTRandom64(19456UL)
Initialize with seed==19456. Any unsigned long seed
in the range [1,18446744073709551615] is acceptable.
c) Dim init64() As ULong = {&H12345UL, &H23456UL, &H34567UL, &H45678UL}
Dim r As New MTRandom64(init64)
Initialize with an array of ULong (as in the
original MT authors' version). The array must have
at least one element. 312 elements are desirable; more
or fewer elements are acceptable. The element values
ideally should be truly random for best results.
d) Dim r As New MTRandom64(True)
Seed VB Random from the system clock, and then
seed MTRandom64 with the next two values from VB Random.
True is required but ignored.
e) Dim r As New MTRandom64("filename.ext")
Initialize with a generator state saved earlier with
MTRandom64.saveState("filename.ext")
f) Dim r As New MTRandom64(0.0)
Initialize with cryptographically random numbers from
Visual Basic's RNGCryptoServiceProvider. The argument
0.0 is required but ignored. Every new MTRandom64 instance
that is initialized this way will have any one of
approximately 2^19937 different beginning states.
THIS DOES NOT MAKE MTRandom64 CRYPTOGRAPHICALLY SECURE.
g) Dim init32() As UInteger = {&H12345UL, &H23456UL, &H34567UL, &H45678UL}
Dim r As New MTRandom64(init32)
Initialize with an array of UInteger. The array must have
at least two elements. 624 elements are desirable; more
or fewer elements are acceptable. The element values
ideally should be truly random for best results.
h) Dim p As New MTRandom64()
Dim r As New MTRandom64(p)
Initialize PRNG r's state with PRNG p's state.
5) Call any of the genrand64_X() functions listed above. You can re-
initialize an MTRandom64 instance at any point by calling init_genrand64(),
init_by_array64(), init_by_random64(True), init_by_crypto64(), init_by_MTRandom64()
or init_by_array32(). You can save or load the PRNG state at any point
by calling saveState64() or loadState64().
6) Catch exceptions as desired. The MTRandom64 exception classes are at the
end of this file.
To test genrand64_int64(), genrand64_real2(), init_genrand64() and init_by_array64()
in the Visual Basic .NET version of 64-bit Mersenne Twister:
1) Create a Visual Basic .NET console application Project consisting of files
mt19937-64.vb
Demo64.vb
PerformanceTest64.vb
MakeEntropyTestData64.vb
MakeDiehardData64.vb
Main.vb
2) Follow the instructions at the top of this file. Then build and run the project.
3) Compare the file "mt19937-64VBTest.out.txt" with the original MT authors'
test output file ("mt19937-64.out.txt", found by following
links at http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt64.html).
They should be identical.
_________________________________________________________________________________________
PERFORMANCE:
On a iBUYPOWER Pro Series P700 computer with 3.60 GHz Intel i7-3820 processor,
32 GB RAM, Visual Basic .NET (2012) compiler, and generating 100,000,000 random
numbers with each function (running the Release version at a Cmd.exe prompt)
on 64-bit Windows:
Seconds Nanoseconds Calls Per
Function Run Time Per Call Second
-------------------------- -------- ----------- -----------
genrand64_int64() 0.741 7.41 135,000,000
genrand64_int63() 0.787 7.87 127,000,000
genrand64_real1() 0.866 8.66 109,000,000
genrand64_real2() 0.881 8.81 106,000,000
genrand64_real3() 0.881 8.81 106,000,000
genrand64_intMax(1000UL) 0.790 7.90 83,540,000
genrand64_intMax(&H5FFFFFFFUL) 1.666 16.66 56,460,000
genrand64_intRange(10UL, 20UL) 2.953 29.53 46,750,000
genrand64_int128SignedInt() 31.823 318.23 3,142,000
NOTE: genrand64_int64() runs about 43 times faster than
genrand64_int128SignedInt(). Data type BigInteger is SLOW on 32- and 64-bit
Windows!
Bug reports, improvements, corrections, complaints or kudos are welcomed.
Document last revised: 2024-08-17