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: 2019-09-04