├── tools ├── nuget.exe ├── separator.txt ├── coverage.cmd └── pack.cmd ├── lib ├── mt19937ar.tgz ├── SFMT-src-1.4.1.zip ├── dSFMT-src-2.2.3.zip └── mt19937-64stdint.tgz ├── doc └── MersenneTwister.xlsx ├── MersenneTwister ├── SFMT │ ├── SFMT-src-1.4.1.zip │ ├── Isfmt.cs │ ├── sfmt_t_params.cs │ ├── w128_t.cs │ └── sfmt_base_t.cs ├── dSFMT │ ├── dSFMT-src-2.2.3.zip │ ├── Idsfmt.cs │ └── dsfmt_t_params.cs ├── MT64Edition.cs ├── SfmtEdition.cs ├── MTEdition.cs ├── LICENSE-mt19937ar.txt ├── LICENSE-mt19937ar-cok.txt ├── DsfmtEdition.cs ├── MT │ ├── Imt19937.cs │ ├── mt_base_t.cs │ ├── Imt19937_64.cs │ ├── mt19937_64_t.cs │ ├── mt19937ar_t.cs │ ├── mt19937ar_cok_t.cs │ ├── mt19937ar_cok_opt_t.cs │ └── mt19937_64_opt_t.cs ├── SeedUtil.cs ├── Properties │ └── AssemblyInfo.cs ├── MathUtil_UInt64ToDouble.cs ├── MersenneTwisterRandom.cs ├── MathUtil.cs ├── LICENSE.txt ├── MathUtil_UInt32ToDouble.cs ├── LICENSE-dSFMT-2.2.3.txt ├── LICENSE-SFMT-1.4.1.txt ├── RandomBase32.cs ├── LICENSE-mt19937-64.txt ├── MersenneTwister.nuspec ├── SfmtRandom.cs ├── README.txt ├── BitScanner.cs ├── MT64Random.cs ├── RandomBase64.cs ├── MTRandom.cs ├── Randoms.cs ├── AccurateRandom.cs ├── MersenneTwister.csproj └── DsfmtRandom.cs ├── MersenneTwister.Benchmark ├── App.config ├── NullRandom.cs ├── Properties │ └── AssemblyInfo.cs └── MersenneTwister.Benchmark.csproj ├── MersenneTwister.Tests ├── packages.config ├── Properties │ └── AssemblyInfo.cs ├── mt19937_64_t_Test.cs ├── mt19937ar_t_Test.cs ├── SequenceTest.cs ├── TestBase.cs ├── RandomTest.cs ├── MathUtilTest.cs ├── AccurateRandomTest.cs ├── sfmt_t_Test.cs ├── BitScannerTest.cs ├── StatisticsTest.cs ├── MersenneTwister.Tests.csproj └── dsfmt_t_Test.cs ├── .gitattributes ├── MersenneTwister.sln ├── .gitignore └── .editorconfig /tools/nuget.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akiotakahashi/MersenneTwister/HEAD/tools/nuget.exe -------------------------------------------------------------------------------- /lib/mt19937ar.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akiotakahashi/MersenneTwister/HEAD/lib/mt19937ar.tgz -------------------------------------------------------------------------------- /doc/MersenneTwister.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akiotakahashi/MersenneTwister/HEAD/doc/MersenneTwister.xlsx -------------------------------------------------------------------------------- /lib/SFMT-src-1.4.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akiotakahashi/MersenneTwister/HEAD/lib/SFMT-src-1.4.1.zip -------------------------------------------------------------------------------- /lib/dSFMT-src-2.2.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akiotakahashi/MersenneTwister/HEAD/lib/dSFMT-src-2.2.3.zip -------------------------------------------------------------------------------- /lib/mt19937-64stdint.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akiotakahashi/MersenneTwister/HEAD/lib/mt19937-64stdint.tgz -------------------------------------------------------------------------------- /tools/separator.txt: -------------------------------------------------------------------------------- 1 | 2 | ===================================================================================== 3 | -------------------------------------------------------------------------------- /MersenneTwister/SFMT/SFMT-src-1.4.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akiotakahashi/MersenneTwister/HEAD/MersenneTwister/SFMT/SFMT-src-1.4.1.zip -------------------------------------------------------------------------------- /MersenneTwister/dSFMT/dSFMT-src-2.2.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akiotakahashi/MersenneTwister/HEAD/MersenneTwister/dSFMT/dSFMT-src-2.2.3.zip -------------------------------------------------------------------------------- /MersenneTwister/MT64Edition.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MersenneTwister 4 | { 5 | public enum MT64Edition 6 | { 7 | Original_19937, 8 | Opt_19937, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /MersenneTwister/SfmtEdition.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MersenneTwister 4 | { 5 | public enum SfmtEdition 6 | { 7 | Original_19937, 8 | Opt_19937, 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /MersenneTwister/MTEdition.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MersenneTwister 4 | { 5 | public enum MTEdition 6 | { 7 | Original_19937, 8 | Cok_19937, 9 | CokOpt_19937, 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MersenneTwister.Benchmark/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /MersenneTwister.Tests/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /MersenneTwister/LICENSE-mt19937ar.txt: -------------------------------------------------------------------------------- 1 | This is a Mersenne Twister pseudorandom number generator 2 | with period 2^19937-1 with improved initialization scheme, 3 | modified on 2002/1/26 by Takuji Nishimura and Makoto Matsumoto. 4 | ------- 5 | Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, 6 | All rights reserved. 7 | -------------------------------------------------------------------------------- /MersenneTwister/LICENSE-mt19937ar-cok.txt: -------------------------------------------------------------------------------- 1 | This is a Mersenne Twister pseudorandom number generator 2 | with period 2^19937-1 with improved initialization scheme, 3 | modified on 2002/2/10 by Takuji Nishimura and Makoto Matsumoto. 4 | This is a faster version by taking Shawn Cokus's optimization, 5 | Matthe Bellew's simplification, Isaku Wada's real version. 6 | ------- 7 | Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, 8 | All rights reserved. 9 | -------------------------------------------------------------------------------- /MersenneTwister/DsfmtEdition.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MersenneTwister 4 | { 5 | public enum DsfmtEdition 6 | { 7 | Original_19937, 8 | Opt_19937, 9 | OptGen_521, 10 | OptGen_1279, 11 | OptGen_2203, 12 | OptGen_4253, 13 | OptGen_11213, 14 | OptGen_19937, 15 | OptGen_44497, 16 | OptGen_86243, 17 | OptGen_132049, 18 | OptGen_216091, 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /MersenneTwister/MT/Imt19937.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MersenneTwister.MT 4 | { 5 | #if PUBLIC 6 | public 7 | #else 8 | internal 9 | #endif 10 | interface Imt19937 11 | { 12 | void init_genrand(uint s); 13 | void init_by_array(uint[] init_key, int key_length); 14 | int genrand_int31(); 15 | uint genrand_int32(); 16 | double genrand_real2(); 17 | double genrand_res53(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MersenneTwister/MT/mt_base_t.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MersenneTwister.MT 4 | { 5 | #if PUBLIC 6 | public 7 | #else 8 | internal 9 | #endif 10 | abstract class mt_base_t 11 | { 12 | static mt_base_t() 13 | { 14 | if (!BitConverter.IsLittleEndian) { 15 | throw new PlatformNotSupportedException("MersenneTwister does not support Big Endian platforms"); 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MersenneTwister/MT/Imt19937_64.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using uint32_t = System.UInt32; 4 | using uint64_t = System.UInt64; 5 | 6 | namespace MersenneTwister.MT 7 | { 8 | #if PUBLIC 9 | public 10 | #else 11 | internal 12 | #endif 13 | interface Imt19937_64 14 | { 15 | void init_genrand64(ulong s); 16 | void init_by_array64(uint64_t[] init_key, uint64_t key_length); 17 | uint64_t genrand64_int64(); 18 | #if PUBLIC 19 | double genrand64_real2(); 20 | #endif 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tools/coverage.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | PATH %PATH%;..\packages\OpenCover.4.6.519\tools 3 | PATH %PATH%;..\packages\ReportGenerator.2.4.5.0\tools 4 | PATH %PATH%;"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE" 5 | mkdir coverage >NUL 2>&1 6 | OpenCover.Console.exe -target:MSTest.exe -targetargs:"/nologo /testcontainer:..\MersenneTwister.Tests\bin\Debug\MersenneTwister.Tests.dll" -coverbytest:*.Tests.dll -register:user -output:coverage\results.xml 7 | rmdir /s /q TestResults 8 | ReportGenerator.exe -reports:coverage\results.xml -targetdir:coverage 9 | start coverage\index.htm 10 | -------------------------------------------------------------------------------- /MersenneTwister/SFMT/Isfmt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using uint32_t = System.UInt32; 4 | using uint64_t = System.UInt64; 5 | 6 | namespace MersenneTwister.SFMT 7 | { 8 | #if PUBLIC 9 | public 10 | #else 11 | internal 12 | #endif 13 | interface Isfmt 14 | { 15 | string sfmt_get_idstring(); 16 | int sfmt_get_min_array_size32(); 17 | int sfmt_get_min_array_size64(); 18 | void sfmt_fill_array32(uint32_t[] array, int size); 19 | void sfmt_fill_array64(uint64_t[] array, int size); 20 | void sfmt_init_gen_rand(uint32_t seed); 21 | void sfmt_init_by_array(uint32_t[] init_key, uint key_length); 22 | void sfmt_init_by_array(uint32_t[] init_key); 23 | uint32_t sfmt_genrand_uint32(); 24 | uint64_t sfmt_genrand_uint64(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MersenneTwister/SeedUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Threading; 4 | 5 | namespace MersenneTwister 6 | { 7 | internal static class SeedUtil 8 | { 9 | private static readonly Stopwatch watch = Stopwatch.StartNew(); 10 | 11 | private static int counter = 0; 12 | 13 | public static uint[] GenerateSeed() 14 | { 15 | var tick = (ulong)DateTime.UtcNow.Ticks; 16 | var time = (ulong)watch.ElapsedTicks; 17 | var seed = new[] { 18 | (uint)tick, (uint)(tick >> 32), 19 | (uint)time, (uint)(time >> 32), 20 | (uint)Environment.TickCount, 21 | (uint)Environment.CurrentManagedThreadId, 22 | (uint)Interlocked.Increment(ref counter), 23 | }; 24 | return seed; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /MersenneTwister/dSFMT/Idsfmt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using uint32_t = System.UInt32; 4 | using uint64_t = System.UInt64; 5 | 6 | namespace MersenneTwister.dSFMT 7 | { 8 | #if PUBLIC 9 | public 10 | #else 11 | internal 12 | #endif 13 | interface Idsfmt 14 | { 15 | int MEXP { get; } 16 | int DSFMT_N { get; } 17 | string dsfmt_get_idstring(); 18 | void dsfmt_init_gen_rand(uint32_t seed); 19 | void dsfmt_init_by_array(uint32_t[] init_key); 20 | uint32_t dsfmt_genrand_uint32(); 21 | double dsfmt_genrand_open_open(); 22 | double dsfmt_genrand_close_open(); 23 | double dsfmt_genrand_open_close(); 24 | double dsfmt_genrand_close1_open2(); 25 | void dsfmt_fill_array_open_open(double[] array, int size); 26 | void dsfmt_fill_array_close_open(double[] array, int size); 27 | void dsfmt_fill_array_open_close(double[] array, int size); 28 | void dsfmt_fill_array_close1_open2(double[] array, int size); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /MersenneTwister/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Resources; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 7 | // アセンブリに関連付けられている情報を変更するには、 8 | // これらの属性値を変更してください。 9 | [assembly: AssemblyTitle("MersenneTwister")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("MersenneTwister")] 14 | [assembly: AssemblyCopyright("Copyright (C) 2016-2019 Akio Takahashi")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: NeutralResourcesLanguage("")] 18 | 19 | // アセンブリのバージョン情報は次の 4 つの値で構成されています: 20 | // 21 | // メジャー バージョン 22 | // マイナー バージョン 23 | // ビルド番号 24 | // リビジョン 25 | // 26 | // すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を 27 | // 既定値にすることができます: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.*")] 30 | [assembly: AssemblyFileVersion("1.0.6")] 31 | -------------------------------------------------------------------------------- /MersenneTwister.Benchmark/NullRandom.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MersenneTwister.Benchmark 8 | { 9 | public sealed class NullRandom : Random 10 | { 11 | public static readonly Random Defalut = new NullRandom(); 12 | 13 | private NullRandom() 14 | { 15 | } 16 | 17 | public override int Next() 18 | { 19 | return 0; 20 | } 21 | 22 | public override int Next(int maxValue) 23 | { 24 | return 0; 25 | } 26 | 27 | public override int Next(int minValue, int maxValue) 28 | { 29 | return minValue; 30 | } 31 | 32 | public override void NextBytes(byte[] buffer) 33 | { 34 | } 35 | 36 | public override double NextDouble() 37 | { 38 | return 0; 39 | } 40 | 41 | protected override double Sample() 42 | { 43 | return 0; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /MersenneTwister.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 6 | // アセンブリに関連付けられている情報を変更するには、 7 | // これらの属性値を変更してください。 8 | [assembly: AssemblyTitle("MersenneTwister.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MersenneTwister.Tests")] 13 | [assembly: AssemblyCopyright("Copyright (C) 2016 Akio Takahashi")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから 18 | // 参照できなくなります。このアセンブリ内で COM から型にアクセスする必要がある場合は、 19 | // その型の ComVisible 属性を true に設定してください。 20 | [assembly: ComVisible(false)] 21 | 22 | // このプロジェクトが COM に公開される場合、次の GUID が typelib の ID になります 23 | [assembly: Guid("ce129cfc-57e2-49f3-9c41-22c35bdeff63")] 24 | 25 | // アセンブリのバージョン情報は次の 4 つの値で構成されています: 26 | // 27 | // メジャー バージョン 28 | // マイナー バージョン 29 | // ビルド番号 30 | // Revision 31 | // 32 | // すべての値を指定するか、以下のように '*' を使用してビルド番号とリビジョン番号を 33 | // 既定値にすることができます: 34 | //[アセンブリ: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MersenneTwister.Benchmark/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 6 | // アセンブリに関連付けられている情報を変更するには、 7 | // これらの属性値を変更してください。 8 | [assembly: AssemblyTitle("MersenneTwister.Benchmark")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MersenneTwister.Benchmark")] 13 | [assembly: AssemblyCopyright("Copyright (C) 2016 Akio Takahashi")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから 18 | // 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 19 | // その型の ComVisible 属性を true に設定してください。 20 | [assembly: ComVisible(false)] 21 | 22 | // このプロジェクトが COM に公開される場合、次の GUID が typelib の ID になります 23 | [assembly: Guid("690f202c-566c-4325-b23c-91f37806078a")] 24 | 25 | // アセンブリのバージョン情報は次の 4 つの値で構成されています: 26 | // 27 | // メジャー バージョン 28 | // マイナー バージョン 29 | // ビルド番号 30 | // Revision 31 | // 32 | // すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を 33 | // 既定値にすることができます: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MersenneTwister/MathUtil_UInt64ToDouble.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.CompilerServices; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace MersenneTwister 9 | { 10 | partial class MathUtil 11 | { 12 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 13 | public static double UInt64ToDouble_c0o1(ulong x) 14 | { 15 | #if false // WRONG CALCULUS 16 | return x * (1.0 / 18446744073709551616.0 /*(1 << 64)*/); 17 | return (x >> 10) * (1.0 / (1UL << 54)); 18 | return ((uint)(x >> 32) * (1.0 / (1UL << 32))) + ((uint)x * (0.5 / (1UL << 63))); 19 | return ((x >> 12) * (1.0 / (1UL << 52))) + ((uint)(x & 0xFFF) * (0.5 / (1UL << 63))); 20 | #endif 21 | return (x >> 11) * (1.0 / (1UL << 53)); 22 | } 23 | 24 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 25 | public static double UInt64ToDouble_o0o1(ulong x) 26 | { 27 | return ((x >> 12) + 0.5) * (1.0 / (1UL << 52)); 28 | } 29 | 30 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 31 | public static double UInt64ToDouble_c0c1(ulong x) 32 | { 33 | return (x >> 11) * (1.0 / ((1UL << 53) - 1)); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /MersenneTwister/MersenneTwisterRandom.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace MersenneTwister 8 | { 9 | public abstract class MersenneTwisterRandom : Random 10 | { 11 | public sealed override int Next() 12 | { 13 | return MathUtil.Next(this.GenerateUInt32()); 14 | } 15 | 16 | public sealed override int Next(int maxValue) 17 | { 18 | return MathUtil.Next(maxValue, this.GenerateUInt32()); 19 | } 20 | 21 | public sealed override int Next(int minValue, int maxValue) 22 | { 23 | return MathUtil.Next(minValue, maxValue, this.GenerateUInt32()); 24 | } 25 | 26 | public sealed override void NextBytes(byte[] buffer) 27 | { 28 | this.GenerateBytes(buffer); 29 | } 30 | 31 | public sealed override double NextDouble() 32 | { 33 | return this.GenerateDouble(); 34 | } 35 | 36 | protected sealed override double Sample() 37 | { 38 | return this.GenerateDouble(); 39 | } 40 | 41 | public abstract uint GenerateUInt32(); 42 | public abstract ulong GenerateUInt64(); 43 | public abstract double GenerateDouble(); 44 | protected abstract void GenerateBytes(byte[] buffer); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /MersenneTwister/MathUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.CompilerServices; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace MersenneTwister 9 | { 10 | #if PUBLIC 11 | public 12 | #else 13 | internal 14 | #endif 15 | static partial class MathUtil 16 | { 17 | /// [0, int.MaxValue) 18 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 19 | public static int Next(uint r) 20 | { 21 | // DO NOT USE: (int)(r >> 1) 22 | // because Random.Next returns exclusive int.MaxValue 23 | // i.e. The return value must be equal or less than 0x7FFFFFFE. 24 | return (int)(((ulong)int.MaxValue * r) >> 32); 25 | } 26 | 27 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 28 | public static int Next(int maxValue, uint r) 29 | { 30 | if (maxValue < 0) { throw new ArgumentOutOfRangeException(); } 31 | return (int)(((ulong)maxValue * r) >> 32); 32 | } 33 | 34 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 35 | public static int Next(int minValue, int maxValue, uint r) 36 | { 37 | if (maxValue < minValue) { throw new ArgumentOutOfRangeException(); } 38 | var num = (ulong)((long)maxValue - minValue); 39 | return (int)((num * r) >> 32) + minValue; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /MersenneTwister/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Akio Takahashi 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | 3. Neither the name of the copyright holder nor the names of its contributors 15 | may be used to endorse or promote products derived from this software 16 | without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /MersenneTwister/MathUtil_UInt32ToDouble.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.CompilerServices; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace MersenneTwister 9 | { 10 | partial class MathUtil 11 | { 12 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 13 | public static double UInt32ToDouble_c0c1(uint a, uint b) 14 | { 15 | return ((a << 21) ^ b) * (1.0 / ((1UL << 53) - 1)); 16 | } 17 | 18 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 19 | public static double UInt32ToDouble_c0o1(uint a, uint b) 20 | { 21 | return ((a << 21) ^ b) * (1.0 / (1UL << 53)); 22 | } 23 | 24 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 25 | public static double UInt32ToDouble_o0o1(uint a, uint b) 26 | { 27 | return (((a << 20) ^ b) + 0.5) * (1.0 / (1UL << 51)); 28 | } 29 | 30 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 31 | public static double UInt32ToDouble_c0c1(uint x) 32 | { 33 | return x * (1.0 / 4294967295.0); 34 | } 35 | 36 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 37 | public static double UInt32ToDouble_c0o1(uint x) 38 | { 39 | return x * (1.0 / 4294967296.0); 40 | } 41 | 42 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 43 | public static double UInt32ToDouble_o0o1(uint x) 44 | { 45 | return (x + 0.5) * (1.0 / 4294967296.0); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /MersenneTwister.Tests/mt19937_64_t_Test.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | using MersenneTwister.MT; 7 | using Microsoft.VisualStudio.TestTools.UnitTesting; 8 | 9 | namespace MersenneTwister.Tests 10 | { 11 | [TestClass] 12 | public class mt19937_64_t_Test : TestBase 13 | { 14 | [TestMethod] 15 | public void MersenneTwister_MT19937_64() 16 | { 17 | Test(new mt19937_64_t()); 18 | } 19 | 20 | [TestMethod] 21 | public void MersenneTwister_MT19937_64_opt() 22 | { 23 | Test(new mt19937_64_opt_t()); 24 | } 25 | 26 | private void Test(T mt) where T : Imt19937_64 27 | { 28 | var init = new[] { 0x12345UL, 0x23456UL, 0x34567UL, 0x45678UL }; 29 | mt.init_by_array64(init, (uint)init.Length); 30 | printf("1000 outputs of genrand64_int64()\n"); 31 | for (var i = 0; i < 1000; i++) { 32 | printf("{0,20} ", mt.genrand64_int64()); 33 | if (i % 5 == 4) { 34 | printf("\n"); 35 | } 36 | } 37 | printf("\n1000 outputs of genrand64_real2()\n"); 38 | for (var i = 0; i < 1000; i++) { 39 | printf("{0,10} ", d2s(mt.genrand64_real2(), 8)); 40 | if (i % 5 == 4) { 41 | printf("\n"); 42 | } 43 | } 44 | // 45 | var expected = File.ReadAllText(Path.Combine("MT", "mt19937-64.out.txt")); 46 | expected = expected.Replace("\r\n", "\n"); 47 | var actual = this.GetOutput(); 48 | AssertResults(expected, actual, 1e-7); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /MersenneTwister/LICENSE-dSFMT-2.2.3.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007, 2008, 2009 Mutsuo Saito, Makoto Matsumoto 2 | and Hiroshima University. 3 | Copyright (c) 2011, 2002 Mutsuo Saito, Makoto Matsumoto, Hiroshima 4 | University and The University of Tokyo. 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are 9 | met: 10 | 11 | * Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above 14 | copyright notice, this list of conditions and the following 15 | disclaimer in the documentation and/or other materials provided 16 | with the distribution. 17 | * Neither the name of the Hiroshima University nor the names of 18 | its contributors may be used to endorse or promote products 19 | derived from this software without specific prior written 20 | permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | -------------------------------------------------------------------------------- /MersenneTwister/LICENSE-SFMT-1.4.1.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima 2 | University. 3 | Copyright (c) 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima University 4 | and The University of Tokyo. 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are 9 | met: 10 | 11 | * Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above 14 | copyright notice, this list of conditions and the following 15 | disclaimer in the documentation and/or other materials provided 16 | with the distribution. 17 | * Neither the names of Hiroshima University, The University of 18 | Tokyo nor the names of its contributors may be used to endorse 19 | or promote products derived from this software without specific 20 | prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | -------------------------------------------------------------------------------- /tools/pack.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | mkdir ..\nuget >NUL 2>&1 3 | 4 | set LICENSE=..\nuget\LICENSES-MersenneTwister.txt 5 | echo THIS FILE IS A COLLECTION OF THE LICENSES RELATED TO MERSENNE TWISTER PACKAGE.> %LICENSE% 6 | type separator.txt >> %LICENSE% 7 | echo Mersenne Twister Pseudorandom Number Generator .NET Library>> %LICENSE% 8 | echo ----------------------------------------------------------->> %LICENSE% 9 | echo;>> %LICENSE% 10 | type ..\MersenneTwister\LICENSE.txt >> %LICENSE% 11 | type separator.txt >> %LICENSE% 12 | echo MT19937ar>> %LICENSE% 13 | echo --------->> %LICENSE% 14 | echo;>> %LICENSE% 15 | type ..\MersenneTwister\LICENSE-mt19937ar.txt >> %LICENSE% 16 | type separator.txt >> %LICENSE% 17 | echo MT19937ar-cok>> %LICENSE% 18 | echo ------------->> %LICENSE% 19 | echo;>> %LICENSE% 20 | type ..\MersenneTwister\LICENSE-mt19937ar-cok.txt >> %LICENSE% 21 | type separator.txt >> %LICENSE% 22 | echo MT19937-64>> %LICENSE% 23 | echo ---------->> %LICENSE% 24 | echo;>> %LICENSE% 25 | type ..\MersenneTwister\LICENSE-mt19937-64.txt >> %LICENSE% 26 | type separator.txt >> %LICENSE% 27 | echo SFMT 1.4.1>> %LICENSE% 28 | echo ---------->> %LICENSE% 29 | echo;>> %LICENSE% 30 | type ..\MersenneTwister\LICENSE-SFMT-1.4.1.txt >> %LICENSE% 31 | type separator.txt >> %LICENSE% 32 | echo dSFMT 2.2.3>> %LICENSE% 33 | echo ----------->> %LICENSE% 34 | echo;>> %LICENSE% 35 | type ..\MersenneTwister\LICENSE-dSFMT-2.2.3.txt >> %LICENSE% 36 | type separator.txt >> %LICENSE% 37 | echo (EOF)>> %LICENSE% 38 | 39 | nuget pack -Build -BasePath ..\MersenneTwister -OutputDirectory ..\nuget ..\MersenneTwister\MersenneTwister.nuspec 40 | pause 41 | -------------------------------------------------------------------------------- /MersenneTwister/SFMT/sfmt_t_params.cs: -------------------------------------------------------------------------------- 1 | #define SFMT_MEXP_19937 2 | using System; 3 | 4 | namespace MersenneTwister.SFMT 5 | { 6 | #if PUBLIC 7 | public 8 | #else 9 | internal 10 | #endif 11 | abstract class sfmt_t_params : sfmt_base_t 12 | { 13 | /** SFMT generator has an internal state array of 128-bit integers, 14 | * and N is its size. */ 15 | protected const int SFMT_N = (SFMT_MEXP / 128 + 1); 16 | 17 | /** N32 is the size of internal state array when regarded as an array 18 | * of 32-bit integers.*/ 19 | protected const int SFMT_N32 = (SFMT_N * 4); 20 | 21 | /** N64 is the size of internal state array when regarded as an array 22 | * of 64-bit integers.*/ 23 | protected const int SFMT_N64 = (SFMT_N * 2); 24 | 25 | /*---------------------- 26 | the parameters of SFMT 27 | ----------------------*/ 28 | 29 | #if SFMT_MEXP_19937 30 | protected const int SFMT_MEXP = 19937; 31 | protected const int SFMT_POS1 = 122; 32 | protected const int SFMT_SL1 = 18; 33 | protected const int SFMT_SL2 = 1; 34 | protected const int SFMT_SR1 = 11; 35 | protected const int SFMT_SR2 = 1; 36 | protected const uint SFMT_MSK1 = 0xdfffffefU; 37 | protected const uint SFMT_MSK2 = 0xddfecb7fU; 38 | protected const uint SFMT_MSK3 = 0xbffaffffU; 39 | protected const uint SFMT_MSK4 = 0xbffffff6U; 40 | protected const uint SFMT_PARITY1 = 0x00000001U; 41 | protected const uint SFMT_PARITY2 = 0x00000000U; 42 | protected const uint SFMT_PARITY3 = 0x00000000U; 43 | protected const uint SFMT_PARITY4 = 0x13c9e684U; 44 | protected const string SFMT_IDSTR = "SFMT-19937:122-18-1-11-1:dfffffef-ddfecb7f-bffaffff-bffffff6"; 45 | #else 46 | #error "SFMT_MEXP is not valid." 47 | #endif 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /MersenneTwister.Tests/mt19937ar_t_Test.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | using MersenneTwister.MT; 7 | using Microsoft.VisualStudio.TestTools.UnitTesting; 8 | 9 | namespace MersenneTwister.Tests 10 | { 11 | [TestClass] 12 | public class mt19937ar_t_Test : TestBase 13 | { 14 | [TestMethod] 15 | public void MersenneTwister_MT19937ar() 16 | { 17 | var mt = new mt19937ar_t(); 18 | TestMT19937(mt); 19 | } 20 | 21 | [TestMethod] 22 | public void MersenneTwister_MT19937ar_cok() 23 | { 24 | var mt = new mt19937ar_cok_t(); 25 | TestMT19937(mt); 26 | } 27 | 28 | [TestMethod] 29 | public void MersenneTwister_MT19937ar_cok_opt() 30 | { 31 | var mt = new mt19937ar_cok_opt_t(); 32 | TestMT19937(mt); 33 | } 34 | 35 | private void TestMT19937(T mt) where T : Imt19937 36 | { 37 | var init = new uint[] { 0x123, 0x234, 0x345, 0x456 }; 38 | mt.init_by_array(init, init.Length); 39 | printf("1000 outputs of genrand_int32()\n"); 40 | for (var i = 0; i < 1000; i++) { 41 | printf("{0,10} ", mt.genrand_int32()); 42 | if (i % 5 == 4) { 43 | printf("\n"); 44 | } 45 | } 46 | printf("\n1000 outputs of genrand_real2()\n"); 47 | for (var i = 0; i < 1000; i++) { 48 | printf("{0,10} ", d2s(mt.genrand_real2(), 8)); 49 | if (i % 5 == 4) { 50 | printf("\n"); 51 | } 52 | } 53 | // 54 | var expected = File.ReadAllText(Path.Combine("MT", "mt19937ar.out.txt")); 55 | expected = expected.Replace("\r\n", "\n"); 56 | var actual = this.GetOutput(); 57 | AssertResults(expected, actual, 1e-7); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /MersenneTwister/RandomBase32.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.CompilerServices; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace MersenneTwister 9 | { 10 | #if PUBLIC 11 | public 12 | #else 13 | internal 14 | #endif 15 | abstract class RandomBase32 : MersenneTwisterRandom 16 | { 17 | public sealed override ulong GenerateUInt64() 18 | { 19 | var a = this.GenerateUInt32(); 20 | var b = this.GenerateUInt32(); 21 | return a | ((ulong)b << 32); 22 | } 23 | 24 | public override double GenerateDouble() 25 | { 26 | return MathUtil.UInt32ToDouble_c0o1(this.GenerateUInt32()); 27 | } 28 | 29 | protected sealed override void GenerateBytes(byte[] buffer) 30 | { 31 | if (buffer == null) { throw new ArgumentNullException(); } 32 | uint val; 33 | var i = 3; 34 | for (; i < buffer.Length; i += 4) { 35 | val = this.GenerateUInt32(); 36 | buffer[i - 3] = (byte)val; 37 | buffer[i - 2] = (byte)(val >> 8); 38 | buffer[i - 1] = (byte)(val >> 16); 39 | buffer[i - 0] = (byte)(val >> 24); 40 | } 41 | i -= 3; 42 | val = this.GenerateUInt32(); 43 | switch (buffer.Length - i) { 44 | case 3: 45 | buffer[i++] = Shift(ref val); 46 | goto case 2; 47 | case 2: 48 | buffer[i++] = Shift(ref val); 49 | goto case 1; 50 | case 1: 51 | buffer[i++] = Shift(ref val); 52 | break; 53 | } 54 | } 55 | 56 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 57 | private static byte Shift(ref uint value) 58 | { 59 | var r = (byte)value; 60 | value >>= 8; 61 | return r; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /MersenneTwister/dSFMT/dsfmt_t_params.cs: -------------------------------------------------------------------------------- 1 | #define DSFMT_MEXP_19937 2 | using System; 3 | 4 | namespace MersenneTwister.dSFMT 5 | { 6 | #if PUBLIC 7 | public 8 | #else 9 | internal 10 | #endif 11 | abstract class dsfmt_t_params : SFMT.sfmt_base_t 12 | { 13 | protected const ulong DSFMT_LOW_MASK = 0x000FFFFFFFFFFFFFUL; 14 | protected const ulong DSFMT_HIGH_CONST = 0x3FF0000000000000UL; 15 | protected const int DSFMT_SR = 12; 16 | 17 | /** DSFMT generator has an internal state array of 128-bit integers, 18 | * and N is its size. */ 19 | protected const int DSFMT_N = ((DSFMT_MEXP - 128) / 104 + 1); 20 | /** N32 is the size of internal state array when regarded as an array 21 | * of 32-bit integers.*/ 22 | protected const int DSFMT_N32 = (DSFMT_N * 4); 23 | /** N64 is the size of internal state array when regarded as an array 24 | * of 64-bit integers.*/ 25 | protected const int DSFMT_N64 = (DSFMT_N * 2); 26 | 27 | #if DSFMT_MEXP_19937 28 | /* Mersenne Exponent. The period of the sequence 29 | * is a multiple of 2^DSFMT_MEXP-1. */ 30 | protected const int DSFMT_MEXP = 19937; 31 | protected const int DSFMT_POS1 = 117; 32 | protected const int DSFMT_SL1 = 19; 33 | protected const ulong DSFMT_MSK1 = 0x000ffafffffffb3fUL; 34 | protected const ulong DSFMT_MSK2 = 0x000ffdfffc90fffdUL; 35 | protected const uint DSFMT_MSK32_1 = 0x000ffaffU; 36 | protected const uint DSFMT_MSK32_2 = 0xfffffb3fU; 37 | protected const uint DSFMT_MSK32_3 = 0x000ffdffU; 38 | protected const uint DSFMT_MSK32_4 = 0xfc90fffdU; 39 | protected const ulong DSFMT_FIX1 = 0x90014964b32f4329UL; 40 | protected const ulong DSFMT_FIX2 = 0x3b8d12ac548a7c7aUL; 41 | protected const ulong DSFMT_PCV1 = 0x3d84e1ac0dc82880UL; 42 | protected const ulong DSFMT_PCV2 = 0x0000000000000001UL; 43 | protected const string DSFMT_IDSTR = "dSFMT2-19937:117-19:ffafffffffb3f-ffdfffc90fffd"; 44 | #else 45 | #error "DSFMT_MEXP is not valid." 46 | #endif 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /MersenneTwister.Tests/SequenceTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | 8 | namespace MersenneTwister.Tests 9 | { 10 | [TestClass] 11 | public class SequenceTest 12 | { 13 | private void Test(Random expected, Random actual) 14 | { 15 | for (var i = 0; i < 1000000; ++i) { 16 | Assert.AreEqual(expected.Next(), actual.Next()); 17 | } 18 | for (var i = 0; i < 1000000; ++i) { 19 | Assert.AreEqual(expected.NextDouble(), actual.NextDouble()); 20 | } 21 | var bufe = new byte[727]; 22 | var bufa = new byte[bufe.Length]; 23 | for (var i = 0; i < 10000; ++i) { 24 | expected.NextBytes(bufe); 25 | actual.NextBytes(bufa); 26 | CollectionAssert.AreEqual(bufe, bufa); 27 | } 28 | } 29 | 30 | [TestMethod] 31 | public void Sequence_MT() 32 | { 33 | var seed = Environment.TickCount; 34 | Test(MTRandom.Create(seed, MTEdition.Original_19937), MTRandom.Create(seed, MTEdition.Cok_19937)); 35 | Test(MTRandom.Create(seed, MTEdition.Original_19937), MTRandom.Create(seed, MTEdition.CokOpt_19937)); 36 | } 37 | 38 | [TestMethod] 39 | public void Sequence_MT64() 40 | { 41 | var seed = Environment.TickCount; 42 | Test(MT64Random.Create(seed, MT64Edition.Original_19937), MT64Random.Create(seed, MT64Edition.Opt_19937)); 43 | } 44 | 45 | [TestMethod] 46 | public void Sequence_SFMT() 47 | { 48 | var seed = Environment.TickCount; 49 | Test(SfmtRandom.Create(seed, SfmtEdition.Original_19937), SfmtRandom.Create(seed, SfmtEdition.Opt_19937)); 50 | } 51 | 52 | [TestMethod] 53 | public void Sequence_dSFMT() 54 | { 55 | var seed = Environment.TickCount; 56 | Test(DsfmtRandom.Create(seed, DsfmtEdition.Original_19937), DsfmtRandom.Create(seed, DsfmtEdition.Opt_19937)); 57 | Test(DsfmtRandom.Create(seed, DsfmtEdition.Original_19937), DsfmtRandom.Create(seed, DsfmtEdition.OptGen_19937)); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /MersenneTwister/LICENSE-mt19937-64.txt: -------------------------------------------------------------------------------- 1 | A C-program for MT19937-64 (2014/2/23 version). 2 | Coded by Takuji Nishimura and Makoto Matsumoto. 3 | 4 | This is a 64-bit version of Mersenne Twister pseudorandom number 5 | generator. 6 | 7 | Before using, initialize the state by using init_genrand64(seed) 8 | or init_by_array64(init_key, key_length). 9 | 10 | Copyright (C) 2004, 2014, Makoto Matsumoto and Takuji Nishimura, 11 | All rights reserved. 12 | 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions 15 | are met: 16 | 17 | 1. Redistributions of source code must retain the above copyright 18 | notice, this list of conditions and the following disclaimer. 19 | 20 | 2. Redistributions in binary form must reproduce the above copyright 21 | notice, this list of conditions and the following disclaimer in the 22 | documentation and/or other materials provided with the distribution. 23 | 24 | 3. The names of its contributors may not be used to endorse or promote 25 | products derived from this software without specific prior written 26 | permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 32 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 33 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 34 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 35 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 36 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 37 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 38 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 | 40 | References: 41 | T. Nishimura, ``Tables of 64-bit Mersenne Twisters'' 42 | ACM Transactions on Modeling and 43 | Computer Simulation 10. (2000) 348--357. 44 | M. Matsumoto and T. Nishimura, 45 | ``Mersenne Twister: a 623-dimensionally equidistributed 46 | uniform pseudorandom number generator'' 47 | ACM Transactions on Modeling and 48 | Computer Simulation 8. (Jan. 1998) 3--30. 49 | 50 | Any feedback is very welcome. 51 | http://www.math.hiroshima-u.ac.jp/~m-mat/MT/emt.html 52 | email: m-mat @ math.sci.hiroshima-u.ac.jp (remove spaces) 53 | -------------------------------------------------------------------------------- /MersenneTwister.Tests/TestBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | using System.Threading.Tasks; 7 | using Microsoft.VisualStudio.TestTools.UnitTesting; 8 | 9 | namespace MersenneTwister.Tests 10 | { 11 | [TestClass] 12 | public abstract class TestBase 13 | { 14 | private readonly StringBuilder stdout = new StringBuilder(); 15 | 16 | [TestInitialize] 17 | [TestCleanup] 18 | public void TestInit() 19 | { 20 | this.stdout.Clear(); 21 | } 22 | 23 | protected static string d2s(double d) 24 | { 25 | return d.ToString("G16").PadRight(17, '0').Substring(0, 17); 26 | } 27 | 28 | protected static string d2s(double d, int digit = 15) 29 | { 30 | return d.ToString("G" + digit).PadRight(17, '0').Substring(0, digit + 2); 31 | } 32 | 33 | protected void printf(string s) 34 | { 35 | stdout.Append(s); 36 | } 37 | 38 | protected void printf(string format, params object[] args) 39 | { 40 | this.stdout.AppendFormat(format, args); 41 | } 42 | 43 | protected string GetOutput() 44 | { 45 | return this.stdout.ToString(); 46 | } 47 | 48 | protected static void AssertResults(string expected, string actual, double doubleDelta) 49 | { 50 | AssertIntegerResults(expected, actual); 51 | AssertDoubleResults(expected, actual, doubleDelta); 52 | } 53 | 54 | protected static void AssertIntegerResults(string expected, string actual) 55 | { 56 | var me = Regex.Matches(expected, @"\b(? 2 | 3 | 4 | MersenneTwister 5 | 1.0.6 6 | Mersenne Twister 7 | Akio Takahashi 8 | content\LICENSES-MersenneTwister.txt 9 | https://github.com/akiotakahashi/MersenneTwister 10 | 11 | true 12 | Mersenne Twister Pseudorandom Number Generators 13 | This portable class library provides Mersenne Twister PRNGs; 14 | 15 | Mersenne Twister (MT): 16 | - MT19937ar, MT19937ar-cok, MT19937ar-cok-opt 17 | - MT19937-64, MT19937-64-opt 18 | 19 | SIMD-oriented Fast MT (SFMT): 20 | - SFMT-19937, SFMT-opt-19937 21 | 22 | Double precision SFMT (dSFMT): 23 | - dSFMT-19937, dSFMT-opt-19937 24 | - dSFMT-opt-gen-* (Generics version for many Mersenne Exponents) 25 | -- 521, 1279, 2203, 4253, 11213, 19937, 44497, 86243, 132049, 216091 26 | 27 | You can use any PRNG via a corresponding System.Random derived wrapping class: 28 | - MTRandom 29 | - MT64Random 30 | - SfmtRandom 31 | - DsfmtRandom 32 | 33 | and also we provide Randoms class for convenience that has; 34 | - Create(RandomType type) to get the suitable implementaiton such as fastest for Random.Next() 35 | - Thread-local default object propreties: 36 | -- WellBalanced for general purpose 37 | -- FastestInt32 for Random.Next() 38 | -- FastestDouble for Random.Next(int) or Next(int,int) or NextDouble() 39 | 40 | Further more, AccurateRandom class provides accurate results of Random.Next(int maxValue) and Next(int minValue, int maxValue). 41 | .NET Porting and extra classes: 2016 Akio Takahashi. MT19937ar, MT19937ar-cok, MT19937-64: 1997-2002, 2004, 2014, Makoto Matsumoto and Takuji Nishimura. SFMT: 2006, 2007, 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima University and The University of Tokyo. dSFMT: 2007, 2008, 2009, 2011, 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima University and The University of Tokyo. 42 | Mersenne Twister Pseudorandom Number Generator Random PRNG RNG 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /MersenneTwister/SfmtRandom.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | using MersenneTwister.SFMT; 4 | 5 | namespace MersenneTwister 6 | { 7 | public static class SfmtRandom 8 | { 9 | public static Random Create() 10 | { 11 | return Create(SfmtEdition.Opt_19937); 12 | } 13 | 14 | public static Random Create(int seed) 15 | { 16 | return Create(seed, SfmtEdition.Opt_19937); 17 | } 18 | 19 | public static Random Create(uint[] seed) 20 | { 21 | return Create(seed, SfmtEdition.Opt_19937); 22 | } 23 | 24 | public static Random Create(SfmtEdition edition) 25 | { 26 | switch (edition) { 27 | case SfmtEdition.Original_19937: 28 | return new SfmtRandom(); 29 | case SfmtEdition.Opt_19937: 30 | return new SfmtRandom(); 31 | default: 32 | throw new ArgumentException(); 33 | } 34 | } 35 | 36 | public static Random Create(int seed, SfmtEdition edition) 37 | { 38 | switch (edition) { 39 | case SfmtEdition.Original_19937: 40 | return new SfmtRandom(seed); 41 | case SfmtEdition.Opt_19937: 42 | return new SfmtRandom(seed); 43 | default: 44 | throw new ArgumentException(); 45 | } 46 | } 47 | 48 | public static Random Create(uint[] seed, SfmtEdition edition) 49 | { 50 | switch (edition) { 51 | case SfmtEdition.Original_19937: 52 | return new SfmtRandom(seed); 53 | case SfmtEdition.Opt_19937: 54 | return new SfmtRandom(seed); 55 | default: 56 | throw new ArgumentException(); 57 | } 58 | } 59 | } 60 | 61 | #if PUBLIC 62 | public 63 | #else 64 | internal 65 | #endif 66 | sealed class SfmtRandom : RandomBase64 where T : Isfmt, new() 67 | { 68 | private readonly T sfmt = new T(); 69 | 70 | public SfmtRandom() 71 | { 72 | var seed = SeedUtil.GenerateSeed(); 73 | this.sfmt.sfmt_init_by_array(seed); 74 | } 75 | 76 | public SfmtRandom(int seed) 77 | { 78 | this.sfmt.sfmt_init_gen_rand((uint)seed); 79 | } 80 | 81 | public SfmtRandom(uint[] seed) 82 | { 83 | this.sfmt.sfmt_init_by_array(seed); 84 | } 85 | 86 | public override ulong GenerateUInt64() 87 | { 88 | return this.sfmt.sfmt_genrand_uint64(); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /MersenneTwister/README.txt: -------------------------------------------------------------------------------- 1 | ======================================================================= 2 | Mersenne Twitster Pseudorandom Number Generator Nuget Package 3 | ======================================================================= 4 | 5 | USAGE: 6 | 7 | using MersenneTwister; 8 | 9 | Way 1) Easiest Random Number Generation 10 | 11 | - Randoms.Next(...) 12 | - Randoms.NextDouble() 13 | - Randoms.NextBytes() 14 | 15 | Each method uses a inner singleton well-balanced random object 16 | with ajumbo lock. So for fast or multithread, you may use Way 2. 17 | 18 | Way 2) Thread-local Recommended Random objects 19 | 20 | - Randoms.WellBalanced -- totally fast enough 21 | - Randoms.FastestInt32 -- fastest for Next(...) and NextBytes() 22 | - Randoms.FastestDouble -- fastest for NextDouble() 23 | 24 | Each method returns a thread-local System.Random-derived object 25 | with default implementation for purpose. For example, 26 | Randoms.FastestInt32 returns a singleton of MT64Random, a 27 | mt19937_64 original implemetation class, which is the featest for 28 | processing Next(). 29 | 30 | Way 3) Get a Dedicated Instance or Give a Seed for Initialization 31 | 32 | - Randoms.Create(RandomType type = WellBalanced) 33 | - Randoms.Create(Int32 seed, RandomType type = WellBalanced) 34 | 35 | Each method returns a new instance of Random. 36 | You have; 37 | - WellBalanced -> DsfmtRandom 38 | - FastestInt32 -> MT64Random 39 | - FastestDouble -> DsfmtRandom 40 | 41 | Way 3) Get a new instance of a Specific Implementation 42 | 43 | You can use these below to crate a specific object: 44 | - MTRandom.Create 45 | - MT64Random.Create 46 | - SFMTRandom.Create 47 | - DSFMTRandom.Create 48 | 49 | and may give a array of seed for better initialization. 50 | 51 | 52 | EXTRA: 53 | 54 | We provide AccurateRandom that returns more accurate results such that; 55 | - Next(int maxValue) and Next(int minValue, int maxValue) return 56 | more accurate results by discarding insufficient random results. 57 | (Probability Bias with Pigion Hole Principle) 58 | - NextDouble returns double value that has 53 bit precision of fraction 59 | regardless of its exponent. So it returns 4.94065645841247E-324 60 | aka Double.Epsilon at minimum except for zero. 61 | 62 | When you must generate extremely accurate results, use AccurateRandom. 63 | 64 | ======================================================================= 65 | 66 | LICENSE 67 | 68 | This software is licensed under the BSD 3-Clause License. 69 | https://opensource.org/licenses/BSD-3-Clause 70 | 71 | The large part of this program is derived from other OSSs. 72 | You must follow these licenses in addition to this software's. 73 | For further details take a look at LICENSE-MersenneTwister.txt. 74 | 75 | ======================================================================= 76 | -------------------------------------------------------------------------------- /MersenneTwister/BitScanner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | 4 | namespace MersenneTwister 5 | { 6 | #if PUBLIC 7 | public 8 | #else 9 | internal 10 | #endif 11 | static class BitScanner 12 | { 13 | public static int NumberOfBit1(uint x) 14 | { 15 | x = x - ((x >> 1) & 0x55555555); 16 | x = (x & 0x33333333) + ((x >> 2) & 0x33333333); 17 | x = (x + (x >> 4)) & 0x0F0F0F0F; 18 | x = x + (x << 8); 19 | x = x + (x << 16); 20 | return (int)(x >> 24); 21 | } 22 | 23 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 24 | public static int NumberOfBit1(ulong x) 25 | { 26 | return NumberOfBit1((uint)x) + NumberOfBit1((uint)(x >> 32)); 27 | } 28 | 29 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 30 | public static int NumberOfTrailingZeros32(uint x) 31 | { 32 | return NumberOfBit1((x - 1) & ~x); 33 | } 34 | 35 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 36 | public static int NumberOfTrailingZeros64(ulong x) 37 | { 38 | return NumberOfBit1((x - 1) & ~x); 39 | } 40 | 41 | public static int NumberOfLeadingZeros32(uint x) 42 | { 43 | x = x | (x >> 1); 44 | x = x | (x >> 2); 45 | x = x | (x >> 4); 46 | x = x | (x >> 8); 47 | x = x | (x >> 16); 48 | return NumberOfBit1(~x); 49 | } 50 | 51 | public static int NumberOfLeadingZeros64(ulong x) 52 | { 53 | x = x | (x >> 1); 54 | x = x | (x >> 2); 55 | x = x | (x >> 4); 56 | x = x | (x >> 8); 57 | x = x | (x >> 16); 58 | x = x | (x >> 32); 59 | return NumberOfBit1(~x); 60 | } 61 | 62 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 63 | public static int PositionOfMSB(uint b) 64 | { 65 | return 32 - NumberOfLeadingZeros32(b); 66 | } 67 | 68 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 69 | public static int PositionOfMSB(ulong b) 70 | { 71 | return 64 - NumberOfLeadingZeros64(b); 72 | } 73 | 74 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 75 | public static uint Mask(uint b) 76 | { 77 | if (b == 0) { return 0; } 78 | return (((1U << (PositionOfMSB(b) - 1)) - 1) << 1) | 1; 79 | } 80 | 81 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 82 | public static ulong Mask(ulong b) 83 | { 84 | if (b == 0) { return 0; } 85 | return (((1UL << (PositionOfMSB(b) - 1)) - 1) << 1) | 1; 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /MersenneTwister/MT64Random.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | using MersenneTwister.MT; 4 | 5 | namespace MersenneTwister 6 | { 7 | public static class MT64Random 8 | { 9 | public static Random Create() 10 | { 11 | return Create(MT64Edition.Original_19937); 12 | } 13 | 14 | public static Random Create(int seed) 15 | { 16 | return Create(seed, MT64Edition.Original_19937); 17 | } 18 | 19 | public static Random Create(ulong[] seed) 20 | { 21 | return Create(seed, MT64Edition.Original_19937); 22 | } 23 | 24 | public static Random Create(MT64Edition edition) 25 | { 26 | switch (edition) { 27 | case MT64Edition.Original_19937: 28 | return new MT64Random(); 29 | case MT64Edition.Opt_19937: 30 | return new MT64Random(); 31 | default: 32 | throw new ArgumentException(); 33 | } 34 | } 35 | 36 | public static Random Create(int seed, MT64Edition edition) 37 | { 38 | switch (edition) { 39 | case MT64Edition.Original_19937: 40 | return new MT64Random(seed); 41 | case MT64Edition.Opt_19937: 42 | return new MT64Random(seed); 43 | default: 44 | throw new ArgumentException(); 45 | } 46 | } 47 | 48 | public static Random Create(ulong[] seed, MT64Edition edition) 49 | { 50 | switch (edition) { 51 | case MT64Edition.Original_19937: 52 | return new MT64Random(seed); 53 | case MT64Edition.Opt_19937: 54 | return new MT64Random(seed); 55 | default: 56 | throw new ArgumentException(); 57 | } 58 | } 59 | } 60 | 61 | #if PUBLIC 62 | public 63 | #else 64 | internal 65 | #endif 66 | sealed class MT64Random : RandomBase64 where T : Imt19937_64, new() 67 | { 68 | private readonly T mt = new T(); 69 | 70 | public MT64Random() 71 | { 72 | var seed = SeedUtil.GenerateSeed(); 73 | var buf = new ulong[(seed.Length + 1) / 2]; 74 | Buffer.BlockCopy(seed, 0, buf, 0, Buffer.ByteLength(seed)); 75 | this.mt.init_by_array64(buf, (uint)buf.Length); 76 | } 77 | 78 | public MT64Random(int seed) 79 | { 80 | this.mt.init_genrand64((uint)seed); 81 | } 82 | 83 | public MT64Random(ulong[] seed) 84 | { 85 | this.mt.init_by_array64(seed, (uint)seed.Length); 86 | } 87 | 88 | public override ulong GenerateUInt64() 89 | { 90 | return this.mt.genrand64_int64(); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /MersenneTwister/RandomBase64.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.CompilerServices; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace MersenneTwister 9 | { 10 | #if PUBLIC 11 | public 12 | #else 13 | internal 14 | #endif 15 | abstract class RandomBase64 : MersenneTwisterRandom 16 | { 17 | private bool sflag32; 18 | private uint stock32; 19 | 20 | public sealed override uint GenerateUInt32() 21 | { 22 | if (this.sflag32) { 23 | var val = this.stock32; 24 | this.sflag32 = false; 25 | return val; 26 | } 27 | var r = this.GenerateUInt64(); 28 | this.stock32 = (uint)(r >> 32); 29 | this.sflag32 = true; 30 | return (uint)r; 31 | } 32 | 33 | public override double GenerateDouble() 34 | { 35 | return MathUtil.UInt64ToDouble_c0o1(this.GenerateUInt64()); 36 | } 37 | 38 | protected sealed override void GenerateBytes(byte[] buffer) 39 | { 40 | if (buffer == null) { throw new ArgumentNullException(); } 41 | ulong val; 42 | var i = 7; 43 | for (; i < buffer.Length; i += 8) { 44 | val = this.GenerateUInt64(); 45 | buffer[i - 7] = (byte)val; 46 | buffer[i - 6] = (byte)(val >> 8); 47 | buffer[i - 5] = (byte)(val >> 16); 48 | buffer[i - 4] = (byte)(val >> 24); 49 | buffer[i - 3] = (byte)(val >> 32); 50 | buffer[i - 2] = (byte)(val >> 40); 51 | buffer[i - 1] = (byte)(val >> 48); 52 | buffer[i - 0] = (byte)(val >> 56); 53 | } 54 | i -= 7; 55 | val = this.GenerateUInt64(); 56 | switch (buffer.Length - i) { 57 | case 7: 58 | buffer[i++] = Shift(ref val); 59 | goto case 6; 60 | case 6: 61 | buffer[i++] = Shift(ref val); 62 | goto case 5; 63 | case 5: 64 | buffer[i++] = Shift(ref val); 65 | goto case 4; 66 | case 4: 67 | buffer[i++] = Shift(ref val); 68 | goto case 3; 69 | case 3: 70 | buffer[i++] = Shift(ref val); 71 | goto case 2; 72 | case 2: 73 | buffer[i++] = Shift(ref val); 74 | goto case 1; 75 | case 1: 76 | buffer[i++] = Shift(ref val); 77 | break; 78 | } 79 | } 80 | 81 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 82 | private static byte Shift(ref ulong value) 83 | { 84 | var r = (byte)value; 85 | value >>= 8; 86 | return r; 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /MersenneTwister.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.28917.181 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MersenneTwister", "MersenneTwister\MersenneTwister.csproj", "{FBF197EA-E04C-4E0B-99FB-BBB60A4BDB83}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7933780A-6601-4932-B1F8-65F2F73D5F30}" 9 | ProjectSection(SolutionItems) = preProject 10 | .editorconfig = .editorconfig 11 | .gitattributes = .gitattributes 12 | .gitignore = .gitignore 13 | EndProjectSection 14 | EndProject 15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MersenneTwister.Tests", "MersenneTwister.Tests\MersenneTwister.Tests.csproj", "{CE129CFC-57E2-49F3-9C41-22C35BDEFF63}" 16 | EndProject 17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MersenneTwister.Benchmark", "MersenneTwister.Benchmark\MersenneTwister.Benchmark.csproj", "{690F202C-566C-4325-B23C-91F37806078A}" 18 | EndProject 19 | Global 20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 21 | Debug|Any CPU = Debug|Any CPU 22 | Inspection|Any CPU = Inspection|Any CPU 23 | Release|Any CPU = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 26 | {FBF197EA-E04C-4E0B-99FB-BBB60A4BDB83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {FBF197EA-E04C-4E0B-99FB-BBB60A4BDB83}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {FBF197EA-E04C-4E0B-99FB-BBB60A4BDB83}.Inspection|Any CPU.ActiveCfg = Inspection|Any CPU 29 | {FBF197EA-E04C-4E0B-99FB-BBB60A4BDB83}.Inspection|Any CPU.Build.0 = Inspection|Any CPU 30 | {FBF197EA-E04C-4E0B-99FB-BBB60A4BDB83}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {FBF197EA-E04C-4E0B-99FB-BBB60A4BDB83}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {CE129CFC-57E2-49F3-9C41-22C35BDEFF63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {CE129CFC-57E2-49F3-9C41-22C35BDEFF63}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {CE129CFC-57E2-49F3-9C41-22C35BDEFF63}.Inspection|Any CPU.ActiveCfg = Inspection|Any CPU 35 | {CE129CFC-57E2-49F3-9C41-22C35BDEFF63}.Inspection|Any CPU.Build.0 = Inspection|Any CPU 36 | {CE129CFC-57E2-49F3-9C41-22C35BDEFF63}.Release|Any CPU.ActiveCfg = Inspection|Any CPU 37 | {690F202C-566C-4325-B23C-91F37806078A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 38 | {690F202C-566C-4325-B23C-91F37806078A}.Debug|Any CPU.Build.0 = Debug|Any CPU 39 | {690F202C-566C-4325-B23C-91F37806078A}.Inspection|Any CPU.ActiveCfg = Inspection|Any CPU 40 | {690F202C-566C-4325-B23C-91F37806078A}.Inspection|Any CPU.Build.0 = Inspection|Any CPU 41 | {690F202C-566C-4325-B23C-91F37806078A}.Release|Any CPU.ActiveCfg = Inspection|Any CPU 42 | EndGlobalSection 43 | GlobalSection(SolutionProperties) = preSolution 44 | HideSolutionNode = FALSE 45 | EndGlobalSection 46 | GlobalSection(ExtensibilityGlobals) = postSolution 47 | SolutionGuid = {8BED9A59-A2CD-4D68-AB78-47927E56ECF9} 48 | EndGlobalSection 49 | EndGlobal 50 | -------------------------------------------------------------------------------- /MersenneTwister/MTRandom.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | using MersenneTwister.MT; 4 | 5 | namespace MersenneTwister 6 | { 7 | public static class MTRandom 8 | { 9 | public static Random Create() 10 | { 11 | return Create(MTEdition.CokOpt_19937); 12 | } 13 | 14 | public static Random Create(int seed) 15 | { 16 | return Create(seed, MTEdition.CokOpt_19937); 17 | } 18 | 19 | public static Random Create(uint[] seed) 20 | { 21 | return Create(seed, MTEdition.CokOpt_19937); 22 | } 23 | 24 | public static Random Create(MTEdition edition) 25 | { 26 | switch (edition) { 27 | case MTEdition.Original_19937: 28 | return new MTRandom(); 29 | case MTEdition.Cok_19937: 30 | return new MTRandom(); 31 | case MTEdition.CokOpt_19937: 32 | return new MTRandom(); 33 | default: 34 | throw new ArgumentException(); 35 | } 36 | } 37 | 38 | public static Random Create(int seed, MTEdition edition) 39 | { 40 | switch (edition) { 41 | case MTEdition.Original_19937: 42 | return new MTRandom(seed); 43 | case MTEdition.Cok_19937: 44 | return new MTRandom(seed); 45 | case MTEdition.CokOpt_19937: 46 | return new MTRandom(seed); 47 | default: 48 | throw new ArgumentException(); 49 | } 50 | } 51 | 52 | public static Random Create(uint[] seed, MTEdition edition) 53 | { 54 | switch (edition) { 55 | case MTEdition.Original_19937: 56 | return new MTRandom(seed); 57 | case MTEdition.Cok_19937: 58 | return new MTRandom(seed); 59 | case MTEdition.CokOpt_19937: 60 | return new MTRandom(seed); 61 | default: 62 | throw new ArgumentException(); 63 | } 64 | } 65 | } 66 | 67 | #if PUBLIC 68 | public 69 | #else 70 | internal 71 | #endif 72 | sealed class MTRandom : RandomBase32 where T : Imt19937, new() 73 | { 74 | private readonly T mt = new T(); 75 | 76 | public MTRandom() 77 | { 78 | var seed = SeedUtil.GenerateSeed(); 79 | this.mt.init_by_array(seed, seed.Length); 80 | } 81 | 82 | public MTRandom(int seed) 83 | { 84 | this.mt.init_genrand((uint)seed); 85 | } 86 | 87 | public MTRandom(uint[] seed) 88 | { 89 | this.mt.init_by_array(seed, seed.Length); 90 | } 91 | 92 | public override uint GenerateUInt32() 93 | { 94 | return this.mt.genrand_int32(); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /MersenneTwister.Benchmark/MersenneTwister.Benchmark.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {690F202C-566C-4325-B23C-91F37806078A} 8 | Exe 9 | Properties 10 | MersenneTwister.Benchmark 11 | MersenneTwister.Benchmark 12 | v4.5.2 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | true 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | true 32 | bin\Inspection\ 33 | TRACE 34 | prompt 35 | 4 36 | false 37 | true 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | {fbf197ea-e04c-4e0b-99fb-bbb60a4bdb83} 62 | MersenneTwister 63 | 64 | 65 | 66 | 73 | -------------------------------------------------------------------------------- /MersenneTwister/Randoms.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | using System.Threading; 4 | 5 | namespace MersenneTwister 6 | { 7 | public static class Randoms 8 | { 9 | private static readonly ThreadLocal wellBalanced = new ThreadLocal(() => Create(RandomType.WellBalanced), false); 10 | private static readonly ThreadLocal fastestInt32 = new ThreadLocal(() => Create(RandomType.FastestInt32), false); 11 | private static readonly ThreadLocal fastestDouble = new ThreadLocal(() => Create(RandomType.FastestDouble), false); 12 | 13 | private static readonly Lazy shared = new Lazy(() => Create(RandomType.WellBalanced), LazyThreadSafetyMode.ExecutionAndPublication); 14 | 15 | public static Random WellBalanced { 16 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 17 | get { 18 | return wellBalanced.Value; 19 | } 20 | } 21 | 22 | public static Random FastestInt32 { 23 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 24 | get { 25 | return fastestInt32.Value; 26 | } 27 | } 28 | 29 | public static Random FastestDouble { 30 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 31 | get { 32 | return fastestDouble.Value; 33 | } 34 | } 35 | 36 | public static Random Create(RandomType type = RandomType.WellBalanced) 37 | { 38 | switch (type) { 39 | case RandomType.WellBalanced: 40 | return DsfmtRandom.Create(); 41 | case RandomType.FastestInt32: 42 | return MT64Random.Create(); 43 | case RandomType.FastestDouble: 44 | return DsfmtRandom.Create(); 45 | default: 46 | throw new ArgumentException(); 47 | } 48 | } 49 | 50 | public static Random Create(int seed, RandomType type = RandomType.WellBalanced) 51 | { 52 | switch (type) { 53 | case RandomType.WellBalanced: 54 | return DsfmtRandom.Create(seed); 55 | case RandomType.FastestInt32: 56 | return MT64Random.Create(seed); 57 | case RandomType.FastestDouble: 58 | return DsfmtRandom.Create(seed); 59 | default: 60 | throw new ArgumentException(); 61 | } 62 | } 63 | 64 | public static int Next() 65 | { 66 | var rng = shared.Value; 67 | lock (rng) { 68 | return rng.Next(); 69 | } 70 | } 71 | 72 | public static int Next(int maxValue) 73 | { 74 | var rng = shared.Value; 75 | lock (rng) { 76 | return rng.Next(maxValue); 77 | } 78 | } 79 | 80 | public static int Next(int minValue, int maxValue) 81 | { 82 | var rng = shared.Value; 83 | lock (rng) { 84 | return rng.Next(minValue, maxValue); 85 | } 86 | } 87 | 88 | public static double NextDouble() 89 | { 90 | var rng = shared.Value; 91 | lock (rng) { 92 | return rng.NextDouble(); 93 | } 94 | } 95 | 96 | public static void NextBytes(byte[] buffer) 97 | { 98 | var rng = shared.Value; 99 | lock (rng) { 100 | rng.NextBytes(buffer); 101 | } 102 | } 103 | } 104 | 105 | public enum RandomType 106 | { 107 | WellBalanced, 108 | FastestInt32, 109 | FastestDouble, 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /MersenneTwister/AccurateRandom.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | 4 | namespace MersenneTwister 5 | { 6 | public sealed class AccurateRandom : Random 7 | { 8 | private const int BUFFER_SIZE = sizeof(ulong); 9 | 10 | private readonly Random rng; 11 | private readonly byte[] buffer = new byte[BUFFER_SIZE]; 12 | 13 | private uint cachedMaxValue = 0; 14 | private uint cachedValueMask = 0; 15 | 16 | public AccurateRandom(Random baseRandom) 17 | { 18 | this.rng = baseRandom; 19 | } 20 | 21 | public AccurateRandom() : this(MT64Random.Create()) 22 | { 23 | } 24 | 25 | public AccurateRandom(int seed) : this(MT64Random.Create(seed)) 26 | { 27 | } 28 | 29 | public AccurateRandom(ulong[] seed) : this(MT64Random.Create(seed)) 30 | { 31 | } 32 | 33 | private uint NextUInt32() 34 | { 35 | this.rng.NextBytes(this.buffer); 36 | return BitConverter.ToUInt32(this.buffer, 0); 37 | } 38 | 39 | public override int Next() 40 | { 41 | return this.Next(int.MaxValue); 42 | } 43 | 44 | private uint NextUInt32(uint maxValue) 45 | { 46 | if (maxValue == 0) { return 0; } 47 | // determine the position of MSB 48 | uint mask; 49 | if (maxValue == this.cachedMaxValue) { 50 | mask = this.cachedValueMask; 51 | } 52 | else { 53 | this.cachedMaxValue = maxValue; 54 | mask = this.cachedValueMask = BitScanner.Mask(maxValue - 1); 55 | } 56 | // 57 | uint num; 58 | do { 59 | num = this.NextUInt32(); 60 | num &= mask; 61 | } while (num >= maxValue); 62 | return num; 63 | } 64 | 65 | public override int Next(int maxValue) 66 | { 67 | if (maxValue < 0) { throw new ArgumentOutOfRangeException(); } 68 | return (int)this.NextUInt32((uint)maxValue); 69 | } 70 | 71 | public override int Next(int minValue, int maxValue) 72 | { 73 | if (maxValue < minValue) { throw new ArgumentOutOfRangeException(); } 74 | return (int)this.NextUInt32((uint)((long)maxValue - minValue)) + minValue; 75 | } 76 | 77 | public override void NextBytes(byte[] buffer) 78 | { 79 | this.rng.NextBytes(buffer); 80 | } 81 | 82 | public override double NextDouble() 83 | { 84 | return FullPrecisionDouble_c0o1(this.rng, this.buffer); 85 | } 86 | 87 | protected override double Sample() 88 | { 89 | return FullPrecisionDouble_c0o1(this.rng, this.buffer); 90 | } 91 | 92 | private static double FullPrecisionDouble_c0o1(Random rng, byte[] buffer) 93 | { 94 | const int EffectiveBits = BUFFER_SIZE * 8; 95 | // exponent 96 | var e = -1; 97 | do { 98 | rng.NextBytes(buffer); 99 | var r = BitConverter.ToUInt64(buffer, 0); 100 | var ntz = BitScanner.NumberOfTrailingZeros64(r); 101 | if (ntz < EffectiveBits) { 102 | e -= ntz; 103 | break; 104 | } 105 | e -= EffectiveBits; 106 | } while (e > -1024); 107 | // 108 | if (e <= -1024) { 109 | return 0; 110 | } 111 | // fraction 112 | rng.NextBytes(buffer); 113 | var f = (long)(BitConverter.ToUInt64(buffer, 0) >> 12); 114 | // IEEE-754 115 | return BitConverter.Int64BitsToDouble(((long)(e + 1023) << 52) | f); 116 | } 117 | 118 | #if PUBLIC 119 | public static double FullPrecisionDouble_c0o1(Random rng) 120 | { 121 | return FullPrecisionDouble_c0o1(rng, new byte[BUFFER_SIZE]); 122 | } 123 | #endif 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Windows Store app package directory 170 | AppPackages/ 171 | BundleArtifacts/ 172 | 173 | # Visual Studio cache files 174 | # files ending in .cache can be ignored 175 | *.[Cc]ache 176 | # but keep track of directories ending in .cache 177 | !*.[Cc]ache/ 178 | 179 | # Others 180 | ClientBin/ 181 | [Ss]tyle[Cc]op.* 182 | ~$* 183 | *~ 184 | *.dbmdl 185 | *.dbproj.schemaview 186 | *.pfx 187 | *.publishsettings 188 | node_modules/ 189 | orleans.codegen.cs 190 | 191 | # RIA/Silverlight projects 192 | Generated_Code/ 193 | 194 | # Backup & report files from converting an old project file 195 | # to a newer Visual Studio version. Backup files are not needed, 196 | # because we have git ;-) 197 | _UpgradeReport_Files/ 198 | Backup*/ 199 | UpgradeLog*.XML 200 | UpgradeLog*.htm 201 | 202 | # SQL Server files 203 | *.mdf 204 | *.ldf 205 | 206 | # Business Intelligence projects 207 | *.rdl.data 208 | *.bim.layout 209 | *.bim_*.settings 210 | 211 | # Microsoft Fakes 212 | FakesAssemblies/ 213 | 214 | # GhostDoc plugin setting file 215 | *.GhostDoc.xml 216 | 217 | # Node.js Tools for Visual Studio 218 | .ntvs_analysis.dat 219 | 220 | # Visual Studio 6 build log 221 | *.plg 222 | 223 | # Visual Studio 6 workspace options file 224 | *.opt 225 | 226 | # Visual Studio LightSwitch build output 227 | **/*.HTMLClient/GeneratedArtifacts 228 | **/*.DesktopClient/GeneratedArtifacts 229 | **/*.DesktopClient/ModelManifest.xml 230 | **/*.Server/GeneratedArtifacts 231 | **/*.Server/ModelManifest.xml 232 | _Pvt_Extensions 233 | 234 | # LightSwitch generated files 235 | GeneratedArtifacts/ 236 | ModelManifest.xml 237 | 238 | # Paket dependency manager 239 | .paket/paket.exe 240 | 241 | # FAKE - F# Make 242 | .fake/ 243 | nuget/ 244 | 245 | # OpenCover 246 | tools/coverage/ 247 | -------------------------------------------------------------------------------- /MersenneTwister/MersenneTwister.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11.0 6 | Debug 7 | AnyCPU 8 | {FBF197EA-E04C-4E0B-99FB-BBB60A4BDB83} 9 | Library 10 | Properties 11 | MersenneTwister 12 | MersenneTwister 13 | ja-JP 14 | 512 15 | {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 16 | Profile78 17 | v4.5 18 | 19 | 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | TRACE;DEBUG;PUBLIC 25 | prompt 26 | 4 27 | 28 | 29 | none 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | true 38 | 39 | 40 | MersenneTwister.pfx 41 | 42 | 43 | bin\Inspection\ 44 | TRACE;PUBLIC 45 | true 46 | AnyCPU 47 | prompt 48 | MinimumRecommendedRules.ruleset 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 111 | -------------------------------------------------------------------------------- /MersenneTwister.Tests/RandomTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | 8 | namespace MersenneTwister.Tests 9 | { 10 | [TestClass] 11 | public class RandomTest 12 | { 13 | private static void Repeat(Action action) 14 | { 15 | for (var trial = 0; trial < 100000; ++trial) { 16 | action(); 17 | } 18 | } 19 | 20 | private void Test(Random rng) 21 | { 22 | Repeat(delegate { Assert.AreEqual(0, rng.Next(0)); }); 23 | Repeat(delegate { Assert.AreEqual(0, rng.Next(1)); }); 24 | Repeat(delegate { Assert.IsTrue(rng.Next(2) < 2); }); 25 | Repeat(delegate { Assert.AreEqual(0, rng.Next(0, 1)); }); 26 | Repeat(delegate { Assert.AreEqual(1, rng.Next(1, 2)); }); 27 | Repeat(delegate { Assert.IsTrue(rng.Next(0, 2) < 2); }); 28 | Repeat(delegate { Assert.AreEqual(int.MaxValue - 1, rng.Next(int.MaxValue - 1, int.MaxValue)); }); 29 | Repeat(delegate { Assert.IsTrue(0 <= rng.NextDouble()); }); 30 | Repeat(delegate { Assert.IsTrue(1 > rng.NextDouble()); }); 31 | Repeat(delegate { Assert.IsTrue(0 <= rng.Next(int.MaxValue)); }); 32 | Repeat(delegate { Assert.AreEqual(-1, rng.Next(-1, -1)); }); 33 | Repeat(delegate { Assert.AreEqual(-1, rng.Next(-1, -0)); }); 34 | Repeat(delegate { Assert.AreEqual(int.MinValue, rng.Next(int.MinValue, int.MinValue + 1)); }); 35 | var meta = Randoms.FastestInt32; 36 | Repeat(delegate { 37 | var n0 = meta.Next(2); 38 | var n1 = meta.Next(2); 39 | var n2 = meta.Next(2); 40 | var nd = meta.Next(2); 41 | Assert.IsTrue(n0 >= 0 && n0 <= 1); 42 | Assert.IsTrue(n1 >= 0 && n1 <= 1); 43 | Assert.IsTrue(n2 >= 0 && n2 <= 1); 44 | Assert.IsTrue(nd >= 0 && nd <= 1); 45 | if (n0 == 0) { rng.Next(); } 46 | if (n1 == 0) { rng.Next(15); } 47 | if (n2 == 0) { rng.Next(-19, 31); } 48 | if (nd == 0) { rng.NextDouble(); } 49 | }); 50 | TestNextBytes(rng, 0); 51 | TestNextBytes(rng, 1); 52 | TestNextBytes(rng, 2); 53 | TestNextBytes(rng, 4); 54 | TestNextBytes(rng, 7); 55 | TestNextBytes(rng, 8); 56 | TestNextBytes(rng, 9); 57 | TestNextBytes(rng, 15); 58 | TestNextBytes(rng, 16); 59 | TestNextBytes(rng, 17); 60 | TestNextBytes(rng, 127); 61 | TestNextBytes(rng, 128); 62 | TestNextBytes(rng, 129); 63 | TestNextBytes(rng, 255); 64 | TestNextBytes(rng, 256); 65 | TestNextBytes(rng, 257); 66 | } 67 | 68 | private void TestNextBytes(Random rng, int byteSize) 69 | { 70 | var buf = new byte[byteSize]; 71 | var nzf = new bool[byteSize]; 72 | for (var trial = 0; trial < 256; ++trial) { 73 | rng.NextBytes(buf); 74 | var num = 0; 75 | for (var i = 0; i < byteSize; ++i) { 76 | nzf[i] |= (buf[i] != 0); 77 | num += (nzf[i] ? 1 : 0); 78 | } 79 | if (num == byteSize) { 80 | return; 81 | } 82 | } 83 | Assert.Fail("suspicious uninitialized bytes are detected"); 84 | } 85 | 86 | [TestMethod] 87 | public void Random_MT() 88 | { 89 | Test(MTRandom.Create(MTEdition.Original_19937)); 90 | Test(MTRandom.Create(MTEdition.Cok_19937)); 91 | Test(MTRandom.Create(MTEdition.CokOpt_19937)); 92 | } 93 | 94 | [TestMethod] 95 | public void Random_MT64() 96 | { 97 | Test(MT64Random.Create(MT64Edition.Original_19937)); 98 | Test(MT64Random.Create(MT64Edition.Opt_19937)); 99 | } 100 | 101 | [TestMethod] 102 | public void Random_SFMT() 103 | { 104 | Test(SfmtRandom.Create(SfmtEdition.Original_19937)); 105 | Test(SfmtRandom.Create(SfmtEdition.Opt_19937)); 106 | } 107 | 108 | [TestMethod] 109 | public void Random_dSFMT() 110 | { 111 | Test(DsfmtRandom.Create(DsfmtEdition.Original_19937)); 112 | Test(DsfmtRandom.Create(DsfmtEdition.Opt_19937)); 113 | Test(DsfmtRandom.Create(DsfmtEdition.OptGen_521)); 114 | Test(DsfmtRandom.Create(DsfmtEdition.OptGen_1279)); 115 | Test(DsfmtRandom.Create(DsfmtEdition.OptGen_2203)); 116 | Test(DsfmtRandom.Create(DsfmtEdition.OptGen_4253)); 117 | Test(DsfmtRandom.Create(DsfmtEdition.OptGen_11213)); 118 | Test(DsfmtRandom.Create(DsfmtEdition.OptGen_19937)); 119 | Test(DsfmtRandom.Create(DsfmtEdition.OptGen_44497)); 120 | Test(DsfmtRandom.Create(DsfmtEdition.OptGen_86243)); 121 | Test(DsfmtRandom.Create(DsfmtEdition.OptGen_132049)); 122 | Test(DsfmtRandom.Create(DsfmtEdition.OptGen_216091)); 123 | } 124 | 125 | [TestMethod] 126 | public void Random_Accurate() 127 | { 128 | Test(new AccurateRandom(new Random())); 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /MersenneTwister/SFMT/w128_t.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | using uint32_t = System.UInt32; 6 | using uint64_t = System.UInt64; 7 | 8 | namespace MersenneTwister.SFMT 9 | { 10 | [StructLayout(LayoutKind.Explicit, Size = 16)] 11 | #if PUBLIC 12 | public 13 | #else 14 | internal 15 | #endif 16 | struct w128_t 17 | { 18 | [FieldOffset(0)] 19 | public uint32_t u32_0; 20 | [FieldOffset(4)] 21 | public uint32_t u32_1; 22 | [FieldOffset(8)] 23 | public uint32_t u32_2; 24 | [FieldOffset(12)] 25 | public uint32_t u32_3; 26 | 27 | [FieldOffset(0)] 28 | public uint64_t u64_0; 29 | [FieldOffset(8)] 30 | public uint64_t u64_1; 31 | 32 | [FieldOffset(0)] 33 | public double d0; 34 | [FieldOffset(8)] 35 | public double d1; 36 | 37 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 38 | public uint32_t u32(uint index) 39 | { 40 | switch (index) { 41 | case 0: 42 | return u32_0; 43 | case 1: 44 | return u32_1; 45 | case 2: 46 | return u32_2; 47 | case 3: 48 | return u32_3; 49 | default: 50 | throw new ArgumentOutOfRangeException(); 51 | } 52 | } 53 | 54 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 55 | public void u32(uint index, uint32_t value) 56 | { 57 | switch (index) { 58 | case 0: 59 | u32_0 = value; 60 | return; 61 | case 1: 62 | u32_1 = value; 63 | return; 64 | case 2: 65 | u32_2 = value; 66 | return; 67 | case 3: 68 | u32_3 = value; 69 | return; 70 | default: 71 | throw new ArgumentOutOfRangeException(); 72 | } 73 | } 74 | 75 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 76 | public void add32(uint index, uint32_t value) 77 | { 78 | switch (index) { 79 | case 0: 80 | u32_0 += value; 81 | return; 82 | case 1: 83 | u32_1 += value; 84 | return; 85 | case 2: 86 | u32_2 += value; 87 | return; 88 | case 3: 89 | u32_3 += value; 90 | return; 91 | default: 92 | throw new ArgumentOutOfRangeException(); 93 | } 94 | } 95 | 96 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 97 | public void xor32(uint index, uint32_t value) 98 | { 99 | switch (index) { 100 | case 0: 101 | u32_0 ^= value; 102 | return; 103 | case 1: 104 | u32_1 ^= value; 105 | return; 106 | case 2: 107 | u32_2 ^= value; 108 | return; 109 | case 3: 110 | u32_3 ^= value; 111 | return; 112 | default: 113 | throw new ArgumentOutOfRangeException(); 114 | } 115 | } 116 | 117 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 118 | public uint64_t u64(uint index) 119 | { 120 | switch (index) { 121 | case 0: 122 | return u64_0; 123 | case 1: 124 | return u64_1; 125 | default: 126 | throw new ArgumentOutOfRangeException(); 127 | } 128 | } 129 | 130 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 131 | public void u64(uint index, uint64_t value) 132 | { 133 | switch (index) { 134 | case 0: 135 | u64_0 = value; 136 | return; 137 | case 1: 138 | u64_1 = value; 139 | return; 140 | default: 141 | throw new ArgumentOutOfRangeException(); 142 | } 143 | } 144 | 145 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 146 | public void add64(uint index, uint64_t value) 147 | { 148 | switch (index) { 149 | case 0: 150 | u64_0 += value; 151 | return; 152 | case 1: 153 | u64_1 += value; 154 | return; 155 | default: 156 | throw new ArgumentOutOfRangeException(); 157 | } 158 | } 159 | 160 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 161 | public void xor64(uint index, uint64_t value) 162 | { 163 | switch (index) { 164 | case 0: 165 | u64_0 ^= value; 166 | return; 167 | case 1: 168 | u64_1 ^= value; 169 | return; 170 | default: 171 | throw new ArgumentOutOfRangeException(); 172 | } 173 | } 174 | 175 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 176 | public double d(uint index) 177 | { 178 | switch (index) { 179 | case 0: 180 | return d0; 181 | case 1: 182 | return d1; 183 | default: 184 | throw new ArgumentOutOfRangeException(); 185 | } 186 | } 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /MersenneTwister.Tests/MathUtilTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | 4 | namespace MersenneTwister.Tests 5 | { 6 | [TestClass] 7 | public class MathUtilTest 8 | { 9 | [TestMethod] 10 | public void MathUtil_UInt64ToDouble_c0c1() 11 | { 12 | Assert.AreEqual(0, MathUtil.UInt64ToDouble_c0c1(ulong.MinValue)); 13 | Assert.AreEqual(1, MathUtil.UInt64ToDouble_c0c1(ulong.MaxValue)); 14 | Assert.IsTrue(MathUtil.UInt64ToDouble_c0c1(ulong.MinValue + 1) >= MathUtil.UInt64ToDouble_c0c1(ulong.MinValue)); 15 | Assert.IsTrue(MathUtil.UInt64ToDouble_c0c1(ulong.MaxValue - 1) <= MathUtil.UInt64ToDouble_c0c1(ulong.MaxValue)); 16 | } 17 | 18 | [TestMethod] 19 | public void MathUtil_UInt64ToDouble_c0o1() 20 | { 21 | Assert.AreEqual(0, MathUtil.UInt64ToDouble_c0o1(ulong.MinValue)); 22 | Assert.IsTrue(1 > MathUtil.UInt64ToDouble_c0o1(ulong.MaxValue)); 23 | Assert.AreEqual(0, MathUtil.UInt64ToDouble_c0o1(ulong.MinValue), 1e-15); 24 | Assert.AreEqual(1, MathUtil.UInt64ToDouble_c0o1(ulong.MaxValue), 1e-15); 25 | Assert.IsTrue(MathUtil.UInt64ToDouble_c0o1(ulong.MinValue + 1) >= MathUtil.UInt64ToDouble_c0o1(ulong.MinValue)); 26 | Assert.IsTrue(MathUtil.UInt64ToDouble_c0o1(ulong.MaxValue - 1) <= MathUtil.UInt64ToDouble_c0o1(ulong.MaxValue)); 27 | } 28 | 29 | [TestMethod] 30 | public void MathUtil_UInt64ToDouble_o0o1() 31 | { 32 | Assert.IsTrue(0 < MathUtil.UInt64ToDouble_o0o1(ulong.MinValue)); 33 | Assert.IsTrue(1 > MathUtil.UInt64ToDouble_o0o1(ulong.MaxValue)); 34 | Assert.AreEqual(0, MathUtil.UInt64ToDouble_o0o1(ulong.MinValue), 1e-15); 35 | Assert.AreEqual(1, MathUtil.UInt64ToDouble_o0o1(ulong.MaxValue), 1e-15); 36 | Assert.IsTrue(MathUtil.UInt64ToDouble_o0o1(ulong.MinValue + 1) >= MathUtil.UInt64ToDouble_o0o1(ulong.MinValue)); 37 | Assert.IsTrue(MathUtil.UInt64ToDouble_o0o1(ulong.MaxValue - 1) <= MathUtil.UInt64ToDouble_o0o1(ulong.MaxValue)); 38 | } 39 | [TestMethod] 40 | public void MathUtil_UInt32ToDouble_c0c1() 41 | { 42 | Assert.AreEqual(0, MathUtil.UInt32ToDouble_c0c1(uint.MinValue)); 43 | Assert.AreEqual(1, MathUtil.UInt32ToDouble_c0c1(uint.MaxValue)); 44 | Assert.IsTrue(MathUtil.UInt32ToDouble_c0c1(uint.MinValue + 1) >= MathUtil.UInt32ToDouble_c0c1(uint.MinValue)); 45 | Assert.IsTrue(MathUtil.UInt32ToDouble_c0c1(uint.MaxValue - 1) <= MathUtil.UInt32ToDouble_c0c1(uint.MaxValue)); 46 | } 47 | 48 | [TestMethod] 49 | public void MathUtil_UInt32ToDouble_c0o1() 50 | { 51 | Assert.AreEqual(0, MathUtil.UInt32ToDouble_c0o1(uint.MinValue)); 52 | Assert.IsTrue(1 > MathUtil.UInt32ToDouble_c0o1(uint.MaxValue)); 53 | Assert.AreEqual(1, MathUtil.UInt32ToDouble_c0o1(uint.MaxValue), 1e-9); 54 | Assert.IsTrue(MathUtil.UInt32ToDouble_c0o1(uint.MinValue + 1) >= MathUtil.UInt32ToDouble_c0o1(uint.MinValue)); 55 | Assert.IsTrue(MathUtil.UInt32ToDouble_c0o1(uint.MaxValue - 1) <= MathUtil.UInt32ToDouble_c0o1(uint.MaxValue)); 56 | } 57 | 58 | [TestMethod] 59 | public void MathUtil_UInt32ToDouble_o0o1() 60 | { 61 | Assert.IsTrue(0 < MathUtil.UInt32ToDouble_o0o1(uint.MinValue)); 62 | Assert.IsTrue(1 > MathUtil.UInt32ToDouble_o0o1(uint.MaxValue)); 63 | Assert.AreEqual(0, MathUtil.UInt32ToDouble_o0o1(uint.MinValue), 1e-9); 64 | Assert.AreEqual(1, MathUtil.UInt32ToDouble_o0o1(uint.MaxValue), 1e-9); 65 | Assert.IsTrue(MathUtil.UInt32ToDouble_o0o1(uint.MinValue + 1) >= MathUtil.UInt32ToDouble_o0o1(uint.MinValue)); 66 | Assert.IsTrue(MathUtil.UInt32ToDouble_o0o1(uint.MaxValue - 1) <= MathUtil.UInt32ToDouble_o0o1(uint.MaxValue)); 67 | } 68 | 69 | [TestMethod] 70 | public void MathUtil_Next_1() 71 | { 72 | Assert.AreEqual(0, MathUtil.Next(0, uint.MinValue)); 73 | Assert.AreEqual(0, MathUtil.Next(0, uint.MaxValue)); 74 | Assert.AreEqual(0, MathUtil.Next(int.MaxValue, uint.MinValue)); 75 | Assert.AreEqual(int.MaxValue - 1, MathUtil.Next(int.MaxValue, uint.MaxValue)); 76 | } 77 | 78 | [TestMethod] 79 | public void MathUtil_Next_2() 80 | { 81 | // [0,0) 82 | Assert.AreEqual(0, MathUtil.Next(0, 0, uint.MinValue)); 83 | Assert.AreEqual(0, MathUtil.Next(0, 0, uint.MaxValue)); 84 | // [max,max) 85 | Assert.AreEqual(int.MinValue, MathUtil.Next(int.MinValue, int.MinValue, uint.MinValue)); 86 | Assert.AreEqual(int.MinValue, MathUtil.Next(int.MinValue, int.MinValue, uint.MaxValue)); 87 | // [max,max) 88 | Assert.AreEqual(int.MaxValue, MathUtil.Next(int.MaxValue, int.MaxValue, uint.MinValue)); 89 | Assert.AreEqual(int.MaxValue, MathUtil.Next(int.MaxValue, int.MaxValue, uint.MaxValue)); 90 | // [0,max) 91 | Assert.AreEqual(0, MathUtil.Next(0, int.MaxValue, uint.MinValue)); 92 | Assert.AreEqual(int.MaxValue - 1, MathUtil.Next(0, int.MaxValue, uint.MaxValue)); 93 | // [min,0) 94 | Assert.AreEqual(int.MinValue, MathUtil.Next(int.MinValue, 0, uint.MinValue)); 95 | Assert.AreEqual(-1, MathUtil.Next(int.MinValue, 0, uint.MaxValue)); 96 | // [min,max) 97 | Assert.AreEqual(int.MinValue, MathUtil.Next(int.MinValue, int.MaxValue, uint.MinValue)); 98 | Assert.AreEqual(int.MaxValue - 1, MathUtil.Next(int.MinValue, int.MaxValue, uint.MaxValue)); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /MersenneTwister.Tests/AccurateRandomTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | 6 | namespace MersenneTwister.Tests 7 | { 8 | [TestClass] 9 | public class AccurateRandomTest 10 | { 11 | private sealed class ConstRandom : Random 12 | { 13 | private readonly uint[] array; 14 | private int index; 15 | 16 | public ConstRandom(params uint[] array) 17 | { 18 | this.array = array; 19 | this.index = array.Length - 1; 20 | Array.Reverse(this.array); 21 | } 22 | 23 | private uint next() 24 | { 25 | if (this.index == 0) { 26 | this.index = this.array.Length - 1; 27 | return this.array[0]; 28 | } 29 | return this.array[this.index--]; 30 | } 31 | 32 | public override int Next() 33 | { 34 | throw new NotSupportedException(); 35 | } 36 | 37 | public override int Next(int maxValue) 38 | { 39 | throw new NotSupportedException(); 40 | } 41 | 42 | public override int Next(int minValue, int maxValue) 43 | { 44 | throw new NotSupportedException(); 45 | } 46 | 47 | public override void NextBytes(byte[] buffer) 48 | { 49 | if (buffer.Length % 4 != 0) { throw new NotSupportedException(); } 50 | for (var i = 0; i < buffer.Length; i += 4) { 51 | var val = this.next(); 52 | buffer[i + 0] = (byte)(val >> 0); 53 | buffer[i + 1] = (byte)(val >> 8); 54 | buffer[i + 2] = (byte)(val >> 16); 55 | buffer[i + 3] = (byte)(val >> 24); 56 | } 57 | } 58 | 59 | public override double NextDouble() 60 | { 61 | throw new NotSupportedException(); 62 | } 63 | 64 | protected override double Sample() 65 | { 66 | throw new NotSupportedException(); 67 | } 68 | } 69 | 70 | [TestMethod] 71 | public void AccurateRandom_FullPrecisionDouble_c0o1() 72 | { 73 | Random bits; 74 | bits = new ConstRandom(1, 0, 0, 0); 75 | Assert.AreEqual(BitConverter.Int64BitsToDouble(0x3FE0000000000000L), AccurateRandom.FullPrecisionDouble_c0o1(bits)); 76 | bits = new ConstRandom(1, 0, 0xFFFFFFFF, 0xFFFFFFFF); 77 | Assert.IsTrue(1 > AccurateRandom.FullPrecisionDouble_c0o1(bits)); 78 | Assert.AreEqual(BitConverter.Int64BitsToDouble(0x3FEFFFFFFFFFFFFFL), AccurateRandom.FullPrecisionDouble_c0o1(bits)); 79 | bits = new ConstRandom(Enumerable.Repeat(0U, 30).Append(0U, 0x80000000U, 0U, 0U).ToArray()); 80 | Assert.AreEqual(BitConverter.Int64BitsToDouble(0x0000000000000000), AccurateRandom.FullPrecisionDouble_c0o1(bits)); 81 | bits = new ConstRandom(Enumerable.Repeat(0U, 30).Append(0U, 0x40000000U, 0U, 0U).ToArray()); 82 | Assert.AreEqual(BitConverter.Int64BitsToDouble(0x0000000000000000), AccurateRandom.FullPrecisionDouble_c0o1(bits)); 83 | bits = new ConstRandom(Enumerable.Repeat(0U, 30).Append(0U, 0x40000000U, 0xFFFFFFFFU, 0xFFFFFFFFU).ToArray()); 84 | Assert.IsTrue(0 < AccurateRandom.FullPrecisionDouble_c0o1(bits)); 85 | Assert.AreEqual(BitConverter.Int64BitsToDouble((1L << 52) - 1), AccurateRandom.FullPrecisionDouble_c0o1(bits)); 86 | } 87 | 88 | [TestMethod] 89 | public void AccurateRandom_Next0() 90 | { 91 | var rng0 = new AccurateRandom(new ConstRandom(0)); 92 | Assert.AreEqual(0, rng0.Next()); 93 | var rng1 = new AccurateRandom(new ConstRandom(uint.MaxValue - 1)); 94 | Assert.AreEqual(int.MaxValue - 1, rng1.Next()); 95 | } 96 | 97 | [TestMethod] 98 | public void AccurateRandom_Next1() 99 | { 100 | var rng0 = new AccurateRandom(new ConstRandom(0)); 101 | Assert.AreEqual(0, rng0.Next(1)); 102 | Assert.AreEqual(0, rng0.Next(3)); 103 | Assert.AreEqual(0, rng0.Next(7)); 104 | Assert.AreEqual(0, rng0.Next(17)); 105 | var rng1 = new AccurateRandom(new ConstRandom(uint.MaxValue)); 106 | Assert.AreEqual(0, rng1.Next(1)); 107 | Assert.AreEqual(7, rng1.Next(8)); 108 | Assert.AreEqual(31, rng1.Next(32)); 109 | Assert.AreEqual(0x3FFFFFFF, rng1.Next(0x40000000)); 110 | } 111 | 112 | [TestMethod] 113 | public void AccurateRandom_Next2() 114 | { 115 | var rng0 = new AccurateRandom(new ConstRandom(0)); 116 | Assert.AreEqual(-1, rng0.Next(-1, 1)); 117 | Assert.AreEqual(int.MinValue, rng0.Next(int.MinValue, int.MaxValue)); 118 | var rng1 = new AccurateRandom(new ConstRandom(uint.MaxValue)); 119 | Assert.AreEqual(0, rng1.Next(-1, 1)); 120 | Assert.AreEqual(0x3FFFFFFF + int.MinValue, rng1.Next(int.MinValue, (int)(0x40000000L + int.MinValue))); 121 | } 122 | 123 | [TestMethod] 124 | public void AccurateRandom_NextDouble() 125 | { 126 | var rng0 = new AccurateRandom(new ConstRandom(0)); 127 | Assert.AreEqual(0, rng0.NextDouble()); 128 | var rng1 = new AccurateRandom(new ConstRandom(uint.MaxValue)); 129 | Assert.AreEqual(BitConverter.Int64BitsToDouble(0x3FEFFFFFFFFFFFFFL), rng1.NextDouble()); 130 | } 131 | } 132 | 133 | internal static class IEnumerableExtensions 134 | { 135 | public static IEnumerable Append(this IEnumerable collection, params T[] values) 136 | { 137 | foreach (var val in collection) { 138 | yield return val; 139 | } 140 | foreach (var val in values) { 141 | yield return val; 142 | } 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /MersenneTwister/SFMT/sfmt_base_t.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | 4 | using uint32_t = System.UInt32; 5 | using uint64_t = System.UInt64; 6 | 7 | namespace MersenneTwister.SFMT 8 | { 9 | #if PUBLIC 10 | public 11 | #else 12 | internal 13 | #endif 14 | abstract class sfmt_base_t : MT.mt_base_t 15 | { 16 | [System.Diagnostics.Conditional("DEBUG")] 17 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 18 | protected static void assert(bool condition) 19 | { 20 | System.Diagnostics.Debug.Assert(condition); 21 | } 22 | 23 | protected static void copy32(w128_t[] src, uint32_t[] dst) 24 | { 25 | for (var i = 0; i < src.Length; ++i) { 26 | var x = src[i]; 27 | var j = i * 4; 28 | dst[j + 0] = x.u32_0; 29 | dst[j + 1] = x.u32_1; 30 | dst[j + 2] = x.u32_2; 31 | dst[j + 3] = x.u32_3; 32 | } 33 | } 34 | 35 | protected static void copy64(w128_t[] src, uint64_t[] dst) 36 | { 37 | for (var i = 0; i < src.Length; ++i) { 38 | var x = src[i]; 39 | var j = i * 2; 40 | dst[j + 0] = x.u64_0; 41 | dst[j + 1] = x.u64_1; 42 | } 43 | } 44 | 45 | protected static void copy64(w128_t[] src, double[] dst) 46 | { 47 | for (var i = 0; i < src.Length; ++i) { 48 | var x = src[i]; 49 | var j = i * 2; 50 | dst[j + 0] = x.d0; 51 | dst[j + 1] = x.d1; 52 | } 53 | } 54 | 55 | protected static void copy64(uint64_t[] src, double[] dst) 56 | { 57 | for (var i = 0; i < src.Length; ++i) { 58 | dst[i] = BitConverter.Int64BitsToDouble((long)src[i]); 59 | } 60 | } 61 | 62 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 63 | protected static uint32_t get32(w128_t[] state, uint index) 64 | { 65 | return state[index >> 2].u32(index & 3); 66 | } 67 | 68 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 69 | protected static void set32(w128_t[] state, uint index, uint32_t value) 70 | { 71 | state[index >> 2].u32(index & 3, value); 72 | } 73 | 74 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 75 | protected static void add32(w128_t[] state, uint index, uint32_t value) 76 | { 77 | state[index >> 2].add32(index & 3, value); 78 | } 79 | 80 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 81 | protected static void xor32(w128_t[] state, uint index, uint32_t value) 82 | { 83 | state[index >> 2].xor32(index & 3, value); 84 | } 85 | 86 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 87 | protected static uint64_t get64(w128_t[] state, uint index) 88 | { 89 | return state[index >> 1].u64(index & 1); 90 | } 91 | 92 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 93 | protected static void set64(w128_t[] state, uint index, uint64_t value) 94 | { 95 | state[index >> 1].u64(index & 1, value); 96 | } 97 | 98 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 99 | protected static void add64(w128_t[] state, uint index, uint64_t value) 100 | { 101 | state[index >> 1].add64(index & 1, value); 102 | } 103 | 104 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 105 | protected static void xor64(w128_t[] state, uint index, uint64_t value) 106 | { 107 | state[index >> 1].xor64(index & 1, value); 108 | } 109 | 110 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 111 | protected static double getd(w128_t[] state, uint index) 112 | { 113 | return state[index >> 1].d(index & 1); 114 | } 115 | 116 | private static readonly int[] shift = new int[] { 0, 32 }; 117 | private static readonly uint64_t[] mask = new uint64_t[] { ~0xFFFFFFFFUL, ~0xFFFFFFFF00000000UL }; 118 | 119 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 120 | protected static uint32_t get32(uint64_t[] state, uint index) 121 | { 122 | return (uint32_t)(state[index >> 1] >> shift[index & 1]); 123 | } 124 | 125 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 126 | protected static void set32(uint64_t[] state, uint index, uint32_t value) 127 | { 128 | var flg = index & 1; 129 | index >>= 1; 130 | var m = mask[flg]; 131 | var s = shift[flg]; 132 | state[index] = (state[index] & m) | ((uint64_t)value << s); 133 | } 134 | 135 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 136 | protected static void add32(uint64_t[] state, uint index, uint32_t value) 137 | { 138 | var flg = index & 1; 139 | index >>= 1; 140 | var m = mask[flg]; 141 | var s = shift[flg]; 142 | state[index] = (state[index] & m) | ((uint64_t)((uint32_t)(state[index] >> s) + value) << s); 143 | } 144 | 145 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 146 | protected static void xor32(uint64_t[] state, uint index, uint32_t value) 147 | { 148 | var flg = index & 1; 149 | index >>= 1; 150 | var m = mask[flg]; 151 | var s = shift[flg]; 152 | state[index] = (state[index] & m) | ((uint64_t)((uint32_t)(state[index] >> s) ^ value) << s); 153 | } 154 | 155 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 156 | protected static uint64_t get64(uint64_t[] state, uint index) 157 | { 158 | return state[index]; 159 | } 160 | 161 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 162 | protected static void set64(uint64_t[] state, uint index, uint64_t value) 163 | { 164 | state[index] = value; 165 | } 166 | 167 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 168 | protected static double getd(uint64_t[] state, uint index) 169 | { 170 | return BitConverter.Int64BitsToDouble((long)state[index]); 171 | } 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /MersenneTwister.Tests/sfmt_t_Test.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Text; 5 | using MersenneTwister.SFMT; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | 8 | using uint32_t = System.UInt32; 9 | using uint64_t = System.UInt64; 10 | 11 | namespace MersenneTwister.Tests 12 | { 13 | [TestClass] 14 | public class sfmt_t_Test : TestBase 15 | { 16 | /** 17 | * @file test.c 18 | * @brief test program for 32-bit and 64-bit output of SFMT. 19 | * 20 | * @author Mutsuo Saito (Hiroshima-univ) 21 | * 22 | * Copyright (C) 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima 23 | * University and The University of Tokyo. 24 | * All rights reserved. 25 | * 26 | * The new BSD License is applied to this software, see LICENSE.txt 27 | */ 28 | 29 | const int BLOCK_SIZE = 100000; 30 | const int BLOCK_SIZE64 = 50000; 31 | const int COUNT = 1000; 32 | 33 | w128_t[] array1 = new w128_t[BLOCK_SIZE / 4]; 34 | w128_t[] array2 = new w128_t[10000 / 4]; 35 | 36 | unsafe void check32(T sfmt) where T : Isfmt 37 | { 38 | var array32 = new uint32_t[10000]; 39 | var array32_2 = new uint32_t[10000]; 40 | 41 | uint32_t r32; 42 | uint32_t[] ini = new uint32_t[] { 0x1234, 0x5678, 0x9abc, 0xdef0 }; 43 | 44 | Assert.IsFalse(sfmt.sfmt_get_min_array_size32() > 10000); 45 | 46 | printf("{0}\n32 bit generated randoms\n", sfmt.sfmt_get_idstring()); 47 | printf("init_gen_rand__________\n"); 48 | /* 32 bit generation */ 49 | sfmt.sfmt_init_gen_rand(1234); 50 | sfmt.sfmt_fill_array32(array32, 10000); 51 | sfmt.sfmt_fill_array32(array32_2, 10000); 52 | sfmt.sfmt_init_gen_rand(1234); 53 | for (var i = 0; i < 10000; i++) { 54 | if (i < 1000) { 55 | printf("{0,10} ", array32[i]); 56 | if (i % 5 == 4) { 57 | printf("\n"); 58 | } 59 | } 60 | r32 = sfmt.sfmt_genrand_uint32(); 61 | Assert.AreEqual(array32[i], r32); 62 | } 63 | for (var i = 0; i < 700; i++) { 64 | r32 = sfmt.sfmt_genrand_uint32(); 65 | Assert.AreEqual(array32_2[i], r32); 66 | } 67 | printf("\n"); 68 | sfmt.sfmt_init_by_array(ini); 69 | printf("init_by_array__________\n"); 70 | sfmt.sfmt_fill_array32(array32, 10000); 71 | sfmt.sfmt_fill_array32(array32_2, 10000); 72 | sfmt.sfmt_init_by_array(ini); 73 | for (var i = 0; i < 10000; i++) { 74 | if (i < 1000) { 75 | printf("{0,10} ", array32[i]); 76 | if (i % 5 == 4) { 77 | printf("\n"); 78 | } 79 | } 80 | r32 = sfmt.sfmt_genrand_uint32(); 81 | Assert.AreEqual(array32[i], r32); 82 | } 83 | for (var i = 0; i < 700; i++) { 84 | r32 = sfmt.sfmt_genrand_uint32(); 85 | Assert.AreEqual(array32_2[i], r32); 86 | } 87 | } 88 | 89 | unsafe void check64(T sfmt) where T : Isfmt 90 | { 91 | var array64 = new uint64_t[5000]; 92 | var array64_2 = new uint64_t[5000]; 93 | 94 | uint64_t r64; 95 | uint32_t[] ini = new uint32_t[] { 5, 4, 3, 2, 1 }; 96 | 97 | Assert.IsFalse(sfmt.sfmt_get_min_array_size64() > 5000); 98 | 99 | printf("%s\n64 bit generated randoms\n", sfmt.sfmt_get_idstring()); 100 | printf("init_gen_rand__________\n"); 101 | /* 64 bit generation */ 102 | sfmt.sfmt_init_gen_rand(4321); 103 | sfmt.sfmt_fill_array64(array64, 5000); 104 | sfmt.sfmt_fill_array64(array64_2, 5000); 105 | sfmt.sfmt_init_gen_rand(4321); 106 | for (var i = 0; i < 5000; i++) { 107 | if (i < 1000) { 108 | printf("{0:X16}", array64[i]); 109 | if (i % 3 == 2) { 110 | printf("\n"); 111 | } 112 | } 113 | r64 = sfmt.sfmt_genrand_uint64(); 114 | Assert.AreEqual(array64[i], r64); 115 | } 116 | printf("\n"); 117 | for (var i = 0; i < 700; i++) { 118 | r64 = sfmt.sfmt_genrand_uint64(); 119 | Assert.AreEqual(array64_2[i], r64); 120 | } 121 | printf("init_by_array__________\n"); 122 | /* 64 bit generation */ 123 | sfmt.sfmt_init_by_array(ini); 124 | sfmt.sfmt_fill_array64(array64, 5000); 125 | sfmt.sfmt_fill_array64(array64_2, 5000); 126 | sfmt.sfmt_init_by_array(ini); 127 | for (var i = 0; i < 5000; i++) { 128 | if (i < 1000) { 129 | printf("{0:X16}", array64[i]); 130 | if (i % 3 == 2) { 131 | printf("\n"); 132 | } 133 | } 134 | r64 = sfmt.sfmt_genrand_uint64(); 135 | Assert.AreEqual(array64[i], r64); 136 | } 137 | printf("\n"); 138 | for (var i = 0; i < 700; i++) { 139 | r64 = sfmt.sfmt_genrand_uint64(); 140 | Assert.AreEqual(array64_2[i], r64); 141 | } 142 | } 143 | 144 | private void MersenneTwister_SFMT_32(T sfmt) where T : Isfmt 145 | { 146 | check32(sfmt); 147 | var expected = File.ReadAllText(Path.Combine("SFMT", "SFMT.19937.out.txt")); 148 | expected = expected.Replace("\r\n", "\n"); 149 | var actual = this.GetOutput(); 150 | AssertResults(expected, actual, 1e-14); 151 | } 152 | 153 | private void MersenneTwister_SFMT_64(T sfmt) where T : Isfmt 154 | { 155 | check64(sfmt); 156 | } 157 | 158 | [TestMethod] 159 | public void MersenneTwister_SFMT_32() 160 | { 161 | MersenneTwister_SFMT_32(new sfmt_t()); 162 | } 163 | 164 | [TestMethod] 165 | public void MersenneTwister_SFMT_64() 166 | { 167 | MersenneTwister_SFMT_64(new sfmt_t()); 168 | } 169 | 170 | [TestMethod] 171 | public void MersenneTwister_SFMT_opt_32() 172 | { 173 | MersenneTwister_SFMT_32(new sfmt_opt_t()); 174 | } 175 | 176 | [TestMethod] 177 | public void MersenneTwister_SFMT_opt_64() 178 | { 179 | MersenneTwister_SFMT_64(new sfmt_opt_t()); 180 | } 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /MersenneTwister.Tests/BitScannerTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | 4 | namespace MersenneTwister.Tests 5 | { 6 | [TestClass] 7 | public class BitScannerTest 8 | { 9 | private readonly Random rng = DsfmtRandom.Create(); 10 | 11 | [TestMethod] 12 | public void BitScanner_NB1_32() 13 | { 14 | Assert.AreEqual(0, BitScanner.NumberOfBit1(0U)); 15 | Assert.AreEqual(1, BitScanner.NumberOfBit1(1U)); 16 | Assert.AreEqual(1, BitScanner.NumberOfBit1(0x40000000U)); 17 | Assert.AreEqual(2, BitScanner.NumberOfBit1(0x40000001U)); 18 | Assert.AreEqual(31, BitScanner.NumberOfBit1(0x7FFFFFFFU)); 19 | Assert.AreEqual(31, BitScanner.NumberOfBit1(0xFFFFFFFEU)); 20 | Assert.AreEqual(32, BitScanner.NumberOfBit1(0xFFFFFFFFU)); 21 | } 22 | 23 | [TestMethod] 24 | public void BitScanner_NB1_64() 25 | { 26 | Assert.AreEqual(0, BitScanner.NumberOfBit1(0UL)); 27 | Assert.AreEqual(1, BitScanner.NumberOfBit1(1UL)); 28 | Assert.AreEqual(1, BitScanner.NumberOfBit1(0x4000000000000000UL)); 29 | Assert.AreEqual(2, BitScanner.NumberOfBit1(0x4000000000000001UL)); 30 | Assert.AreEqual(63, BitScanner.NumberOfBit1(0x7FFFFFFFFFFFFFFFUL)); 31 | Assert.AreEqual(63, BitScanner.NumberOfBit1(0xFFFFFFFFFFFFFFFEUL)); 32 | Assert.AreEqual(64, BitScanner.NumberOfBit1(0xFFFFFFFFFFFFFFFFUL)); 33 | } 34 | 35 | [TestMethod] 36 | public void BitScanner_NTZ_32() 37 | { 38 | Assert.AreEqual(0, BitScanner.NumberOfTrailingZeros32(0x00000001U)); 39 | Assert.AreEqual(1, BitScanner.NumberOfTrailingZeros32(0x00000002U)); 40 | Assert.AreEqual(0, BitScanner.NumberOfTrailingZeros32(0x00000003U)); 41 | Assert.AreEqual(0, BitScanner.NumberOfTrailingZeros32(0x80000001U)); 42 | Assert.AreEqual(0, BitScanner.NumberOfTrailingZeros32(0x40000001U)); 43 | Assert.AreEqual(0, BitScanner.NumberOfTrailingZeros32(0xFFFFFFF1U)); 44 | Assert.AreEqual(0, BitScanner.NumberOfTrailingZeros32(0xFFFFFFFFU)); 45 | Assert.AreEqual(32, BitScanner.NumberOfTrailingZeros32(0x00000000U)); 46 | Assert.AreEqual(31, BitScanner.NumberOfTrailingZeros32(0x80000000U)); 47 | Assert.AreEqual(30, BitScanner.NumberOfTrailingZeros32(0x40000000U)); 48 | } 49 | 50 | [TestMethod] 51 | public void BitScanner_NTZ_64() 52 | { 53 | Assert.AreEqual(0, BitScanner.NumberOfTrailingZeros64(0x0000000000000001UL)); 54 | Assert.AreEqual(1, BitScanner.NumberOfTrailingZeros64(0x0000000000000002UL)); 55 | Assert.AreEqual(0, BitScanner.NumberOfTrailingZeros64(0x0000000000000003UL)); 56 | Assert.AreEqual(0, BitScanner.NumberOfTrailingZeros64(0x8000000000000001UL)); 57 | Assert.AreEqual(0, BitScanner.NumberOfTrailingZeros64(0x4000000000000001UL)); 58 | Assert.AreEqual(0, BitScanner.NumberOfTrailingZeros64(0xFFFFFFFFFFFFFFF1UL)); 59 | Assert.AreEqual(0, BitScanner.NumberOfTrailingZeros64(0xFFFFFFFFFFFFFFFFUL)); 60 | Assert.AreEqual(64, BitScanner.NumberOfTrailingZeros64(0x0000000000000000UL)); 61 | Assert.AreEqual(63, BitScanner.NumberOfTrailingZeros64(0x8000000000000000UL)); 62 | Assert.AreEqual(62, BitScanner.NumberOfTrailingZeros64(0x4000000000000000UL)); 63 | } 64 | 65 | [TestMethod] 66 | public void BitScanner_NLZ_32() 67 | { 68 | Assert.AreEqual(32, BitScanner.NumberOfLeadingZeros32(0)); 69 | Assert.AreEqual(31, BitScanner.NumberOfLeadingZeros32(1)); 70 | Assert.AreEqual(30, BitScanner.NumberOfLeadingZeros32(2)); 71 | Assert.AreEqual(30, BitScanner.NumberOfLeadingZeros32(3)); 72 | Assert.AreEqual(0, BitScanner.NumberOfLeadingZeros32(0xFFFFFFFFU)); 73 | Assert.AreEqual(0, BitScanner.NumberOfLeadingZeros32(0x80000000U)); 74 | Assert.AreEqual(1, BitScanner.NumberOfLeadingZeros32(0x7FFFFFFFU)); 75 | Assert.AreEqual(1, BitScanner.NumberOfLeadingZeros32(0x40000000U)); 76 | } 77 | 78 | [TestMethod] 79 | public void BitScanner_NLZ_64() 80 | { 81 | Assert.AreEqual(64, BitScanner.NumberOfLeadingZeros64(0)); 82 | Assert.AreEqual(63, BitScanner.NumberOfLeadingZeros64(1)); 83 | Assert.AreEqual(62, BitScanner.NumberOfLeadingZeros64(2)); 84 | Assert.AreEqual(62, BitScanner.NumberOfLeadingZeros64(3)); 85 | Assert.AreEqual(0, BitScanner.NumberOfLeadingZeros64(0xFFFFFFFFFFFFFFFFUL)); 86 | Assert.AreEqual(0, BitScanner.NumberOfLeadingZeros64(0x8000000000000000UL)); 87 | Assert.AreEqual(1, BitScanner.NumberOfLeadingZeros64(0x7FFFFFFFFFFFFFFFUL)); 88 | Assert.AreEqual(1, BitScanner.NumberOfLeadingZeros64(0x4000000000000000UL)); 89 | } 90 | 91 | [TestMethod] 92 | public void BitScanner_Mask() 93 | { 94 | Assert.AreEqual(1U, BitScanner.Mask(1)); 95 | Assert.AreEqual(3U, BitScanner.Mask(2)); 96 | Assert.AreEqual(3U, BitScanner.Mask(3)); 97 | Assert.AreEqual(7U, BitScanner.Mask(4)); 98 | Assert.AreEqual(7U, BitScanner.Mask(5)); 99 | Assert.AreEqual(7U, BitScanner.Mask(6)); 100 | Assert.AreEqual(7U, BitScanner.Mask(7)); 101 | Assert.AreEqual(0x7FFFFFFFU, BitScanner.Mask(0x7FFFFFFF)); 102 | Assert.AreEqual(0xFFFFFFFFU, BitScanner.Mask(0x80000000)); 103 | Assert.AreEqual(0xFFFFFFFFU, BitScanner.Mask(0x80000001)); 104 | Assert.AreEqual(0xFFFFFFFFU, BitScanner.Mask(0xFFFFFFFF)); 105 | Assert.AreEqual(0U, BitScanner.Mask(0)); 106 | } 107 | 108 | [TestMethod] 109 | public void BitScanner_Scan() 110 | { 111 | Test(1); 112 | Test(3); 113 | Test(4); 114 | Test(7); 115 | Test(int.MaxValue); 116 | Test(uint.MaxValue); 117 | for (var trial = 0; trial < 1000000; ++trial) { 118 | Test((uint)rng.Next()); 119 | } 120 | } 121 | 122 | private static void Test(uint value) 123 | { 124 | Assert.AreEqual(1UL << (CalcReverse(value) + 1), (ulong)BitScanner.Mask(value) + 1); 125 | } 126 | 127 | private static int CalcForward(ulong value) 128 | { 129 | var pos = 0; 130 | while ((value & 1) == 0) { 131 | pos++; 132 | value >>= 1; 133 | } 134 | return pos; 135 | } 136 | 137 | private static int CalcReverse(ulong value) 138 | { 139 | var pos = 0; 140 | while ((value >>= 1) != 0) { 141 | pos++; 142 | } 143 | return pos; 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /MersenneTwister/DsfmtRandom.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | using MersenneTwister.dSFMT; 4 | 5 | namespace MersenneTwister 6 | { 7 | public static class DsfmtRandom 8 | { 9 | public static Random Create() 10 | { 11 | return Create(DsfmtEdition.Opt_19937); 12 | } 13 | 14 | public static Random Create(int seed) 15 | { 16 | return Create(seed, DsfmtEdition.Opt_19937); 17 | } 18 | 19 | public static Random Create(uint[] seed) 20 | { 21 | return Create(seed, DsfmtEdition.Opt_19937); 22 | } 23 | 24 | public static Random Create(DsfmtEdition edition) 25 | { 26 | switch (edition) { 27 | case DsfmtEdition.Original_19937: 28 | return new DsfmtRandom(); 29 | case DsfmtEdition.Opt_19937: 30 | return new DsfmtRandom(); 31 | case DsfmtEdition.OptGen_521: 32 | return new DsfmtRandom>(); 33 | case DsfmtEdition.OptGen_1279: 34 | return new DsfmtRandom>(); 35 | case DsfmtEdition.OptGen_2203: 36 | return new DsfmtRandom>(); 37 | case DsfmtEdition.OptGen_4253: 38 | return new DsfmtRandom>(); 39 | case DsfmtEdition.OptGen_11213: 40 | return new DsfmtRandom>(); 41 | case DsfmtEdition.OptGen_19937: 42 | return new DsfmtRandom>(); 43 | case DsfmtEdition.OptGen_44497: 44 | return new DsfmtRandom>(); 45 | case DsfmtEdition.OptGen_86243: 46 | return new DsfmtRandom>(); 47 | case DsfmtEdition.OptGen_132049: 48 | return new DsfmtRandom>(); 49 | case DsfmtEdition.OptGen_216091: 50 | return new DsfmtRandom>(); 51 | default: 52 | throw new ArgumentException(); 53 | } 54 | } 55 | 56 | public static Random Create(int seed, DsfmtEdition edition) 57 | { 58 | switch (edition) { 59 | case DsfmtEdition.Original_19937: 60 | return new DsfmtRandom(seed); 61 | case DsfmtEdition.Opt_19937: 62 | return new DsfmtRandom(seed); 63 | case DsfmtEdition.OptGen_521: 64 | return new DsfmtRandom>(seed); 65 | case DsfmtEdition.OptGen_1279: 66 | return new DsfmtRandom>(seed); 67 | case DsfmtEdition.OptGen_2203: 68 | return new DsfmtRandom>(seed); 69 | case DsfmtEdition.OptGen_4253: 70 | return new DsfmtRandom>(seed); 71 | case DsfmtEdition.OptGen_11213: 72 | return new DsfmtRandom>(seed); 73 | case DsfmtEdition.OptGen_19937: 74 | return new DsfmtRandom>(seed); 75 | case DsfmtEdition.OptGen_44497: 76 | return new DsfmtRandom>(seed); 77 | case DsfmtEdition.OptGen_86243: 78 | return new DsfmtRandom>(seed); 79 | case DsfmtEdition.OptGen_132049: 80 | return new DsfmtRandom>(seed); 81 | case DsfmtEdition.OptGen_216091: 82 | return new DsfmtRandom>(seed); 83 | default: 84 | throw new ArgumentException(); 85 | } 86 | } 87 | 88 | public static Random Create(uint[] seed, DsfmtEdition edition) 89 | { 90 | switch (edition) { 91 | case DsfmtEdition.Original_19937: 92 | return new DsfmtRandom(seed); 93 | case DsfmtEdition.Opt_19937: 94 | return new DsfmtRandom(seed); 95 | case DsfmtEdition.OptGen_521: 96 | return new DsfmtRandom>(seed); 97 | case DsfmtEdition.OptGen_1279: 98 | return new DsfmtRandom>(seed); 99 | case DsfmtEdition.OptGen_2203: 100 | return new DsfmtRandom>(seed); 101 | case DsfmtEdition.OptGen_4253: 102 | return new DsfmtRandom>(seed); 103 | case DsfmtEdition.OptGen_11213: 104 | return new DsfmtRandom>(seed); 105 | case DsfmtEdition.OptGen_19937: 106 | return new DsfmtRandom>(seed); 107 | case DsfmtEdition.OptGen_44497: 108 | return new DsfmtRandom>(seed); 109 | case DsfmtEdition.OptGen_86243: 110 | return new DsfmtRandom>(seed); 111 | case DsfmtEdition.OptGen_132049: 112 | return new DsfmtRandom>(seed); 113 | case DsfmtEdition.OptGen_216091: 114 | return new DsfmtRandom>(seed); 115 | default: 116 | throw new ArgumentException(); 117 | } 118 | } 119 | } 120 | 121 | #if PUBLIC 122 | public 123 | #else 124 | internal 125 | #endif 126 | sealed class DsfmtRandom : RandomBase32 where T : Idsfmt, new() 127 | { 128 | private readonly T dsfmt = new T(); 129 | 130 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 131 | public DsfmtRandom() 132 | { 133 | var seed = SeedUtil.GenerateSeed(); 134 | this.dsfmt.dsfmt_init_by_array(seed); 135 | } 136 | 137 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 138 | public DsfmtRandom(int seed) 139 | { 140 | this.dsfmt.dsfmt_init_gen_rand((uint)seed); 141 | } 142 | 143 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 144 | public DsfmtRandom(uint[] seed) 145 | { 146 | this.dsfmt.dsfmt_init_by_array(seed); 147 | } 148 | 149 | public override uint GenerateUInt32() 150 | { 151 | return this.dsfmt.dsfmt_genrand_uint32(); 152 | } 153 | 154 | public override double GenerateDouble() 155 | { 156 | return this.dsfmt.dsfmt_genrand_close_open(); 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /MersenneTwister.Tests/StatisticsTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.VisualStudio.TestTools.UnitTesting; 6 | 7 | namespace MersenneTwister.Tests 8 | { 9 | [TestClass] 10 | public class StatisticsTest 11 | { 12 | private static int Seed { 13 | get { 14 | #if DEBUG 15 | return 2016103113; 16 | #else 17 | return Environment.TickCount; 18 | #endif 19 | } 20 | } 21 | 22 | private static IEnumerable EnumRandoms() 23 | { 24 | var seed = Seed; 25 | System.Diagnostics.Trace.WriteLine("SEED: " + seed); 26 | yield return new Random(); 27 | yield return MTRandom.Create(seed, MTEdition.Original_19937); 28 | yield return MTRandom.Create(seed, MTEdition.Cok_19937); 29 | yield return MTRandom.Create(seed, MTEdition.CokOpt_19937); 30 | yield return MT64Random.Create(seed, MT64Edition.Original_19937); 31 | yield return MT64Random.Create(seed, MT64Edition.Opt_19937); 32 | yield return SfmtRandom.Create(seed, SfmtEdition.Original_19937); 33 | yield return SfmtRandom.Create(seed, SfmtEdition.Opt_19937); 34 | yield return DsfmtRandom.Create(seed, DsfmtEdition.Original_19937); 35 | yield return DsfmtRandom.Create(seed, DsfmtEdition.Opt_19937); 36 | yield return DsfmtRandom.Create(seed, DsfmtEdition.OptGen_521); 37 | yield return DsfmtRandom.Create(seed, DsfmtEdition.OptGen_1279); 38 | yield return DsfmtRandom.Create(seed, DsfmtEdition.OptGen_2203); 39 | yield return DsfmtRandom.Create(seed, DsfmtEdition.OptGen_4253); 40 | yield return DsfmtRandom.Create(seed, DsfmtEdition.OptGen_11213); 41 | yield return DsfmtRandom.Create(seed, DsfmtEdition.OptGen_19937); 42 | yield return DsfmtRandom.Create(seed, DsfmtEdition.OptGen_44497); 43 | yield return DsfmtRandom.Create(seed, DsfmtEdition.OptGen_86243); 44 | yield return DsfmtRandom.Create(seed, DsfmtEdition.OptGen_132049); 45 | yield return DsfmtRandom.Create(seed, DsfmtEdition.OptGen_216091); 46 | } 47 | 48 | private const int N = 1000000; 49 | 50 | private static IEnumerable Generate(Func function, int n = N) 51 | { 52 | #if DEBUG 53 | n /= 10; 54 | #endif 55 | return Enumerable.Range(0, n).Select(i => function()); 56 | } 57 | 58 | [TestMethod] 59 | public void Stats_MinMax() 60 | { 61 | #if DEBUG 62 | foreach (var rng in EnumRandoms()) { 63 | System.Diagnostics.Trace.WriteLine(rng.GetType().FullName); 64 | this.TestMinMax(rng); 65 | } 66 | #else 67 | Parallel.ForEach(EnumRandoms(), rng => { 68 | this.TestMinMax(rng); 69 | }); 70 | #endif 71 | } 72 | 73 | private void TestMinMax(Random rng) 74 | { 75 | Assert.IsTrue(Generate(() => rng.Next()).Min() >= 0x00000000); 76 | Assert.IsTrue(Generate(() => rng.Next()).Max() <= 0x7FFFFFFE); 77 | Assert.IsTrue(Generate(() => rng.Next(0)).Unique() == 0x00000000); 78 | Assert.IsTrue(Generate(() => rng.Next(1)).Unique() == 0x00000000); 79 | Assert.IsTrue(Generate(() => rng.Next(int.MaxValue)).Max() >= 0x00000000); 80 | // 81 | Assert.IsTrue(Generate(() => rng.Next(0, 0)).Unique() == 0); 82 | Assert.IsTrue(Generate(() => rng.Next(int.MinValue, int.MinValue)).Unique() == int.MinValue); 83 | Assert.IsTrue(Generate(() => rng.Next(int.MaxValue, int.MaxValue)).Unique() == int.MaxValue); 84 | // 85 | Assert.IsTrue(Generate(() => rng.Next(0, int.MaxValue)).Min() >= 0); 86 | Assert.IsTrue(Generate(() => rng.Next(0, int.MaxValue)).Max() <= int.MaxValue - 1); 87 | Assert.IsTrue(Generate(() => rng.Next(int.MinValue, 0)).Min() >= int.MinValue); 88 | Assert.IsTrue(Generate(() => rng.Next(int.MinValue, 0)).Max() <= -1); 89 | Assert.IsTrue(Generate(() => rng.Next(int.MinValue, int.MaxValue)).Min() >= int.MinValue); 90 | Assert.IsTrue(Generate(() => rng.Next(int.MinValue, int.MaxValue)).Max() <= int.MaxValue - 1); 91 | // 92 | Assert.IsTrue(Generate(() => rng.NextDouble()).Min() >= 0); 93 | Assert.IsTrue(Generate(() => rng.NextDouble()).Max() < 1); 94 | } 95 | 96 | [TestMethod] 97 | public void Stats_Mean() 98 | { 99 | foreach (var rng in EnumRandoms()) { 100 | AssertMean(int.MaxValue / 2.0, Generate(() => rng.Next())); 101 | AssertMean(int.MaxValue / 2.0, Generate(() => rng.Next(int.MaxValue))); 102 | AssertMean(int.MaxValue / 2.0 / 7, Generate(() => rng.Next(int.MaxValue / 7))); 103 | AssertMean(int.MaxValue / 2.0 / 10181, Generate(() => rng.Next(int.MaxValue / 10181))); 104 | AssertMean(0, Generate(() => rng.Next(int.MinValue, int.MaxValue))); 105 | AssertMean(0.5, Generate(() => rng.NextDouble())); 106 | } 107 | } 108 | 109 | private static void AssertMean(double mu, IEnumerable rng) 110 | { 111 | AssertMean(mu, rng, n => n); 112 | } 113 | 114 | private static void AssertMean(double mu, IEnumerable rng) 115 | { 116 | AssertMean(mu, rng, n => n); 117 | } 118 | 119 | private static void AssertMean(double mu, IEnumerable rng, Func converter) 120 | { 121 | var lv1_num = 0; 122 | var lv1_sum = 0d; 123 | var lv2_num = 0; 124 | var lv2_sum = 0d; 125 | var lv2_std = 0d; 126 | foreach (var val in rng) { 127 | lv1_num += 1; 128 | lv1_sum += converter(val); 129 | if (lv1_num >= 64) { 130 | var dx = (lv1_sum / lv1_num) - mu; 131 | lv2_num += 1; 132 | lv2_sum += dx; 133 | lv2_std += dx * dx; 134 | lv1_sum = 0; 135 | lv1_num = 0; 136 | } 137 | } 138 | var mean = lv2_sum / lv2_num + mu; 139 | var stdev = Math.Sqrt(lv2_std); 140 | var sigma = (mean - mu) / stdev; 141 | Assert.IsTrue(sigma <= 1); 142 | } 143 | 144 | private static readonly double SQRT_2_PI = Math.Sqrt(2 * Math.PI); 145 | 146 | private static double normpdf(double x, double mu, double sigma) 147 | { 148 | var alpha = (x - mu) / sigma; 149 | return Math.Exp(-(alpha * alpha) * 0.5) / (sigma * SQRT_2_PI); 150 | } 151 | } 152 | 153 | public static class IEnumerableUnique 154 | { 155 | public static T Unique(this IEnumerable collection) 156 | { 157 | var it = collection.GetEnumerator(); 158 | if (!it.MoveNext()) { 159 | throw new ArgumentException(); 160 | } 161 | var val = it.Current; 162 | while (it.MoveNext()) { 163 | if (!val.Equals(it.Current)) { 164 | throw new ArgumentException("Multiple Values Found"); 165 | } 166 | } 167 | return val; 168 | } 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /MersenneTwister/MT/mt19937_64_t.cs: -------------------------------------------------------------------------------- 1 | /* 2 | A C-program for MT19937-64 (2014/2/23 version). 3 | Coded by Takuji Nishimura and Makoto Matsumoto. 4 | 5 | This is a 64-bit version of Mersenne Twister pseudorandom number 6 | generator. 7 | 8 | Before using, initialize the state by using init_genrand64(seed) 9 | or init_by_array64(init_key, key_length). 10 | 11 | Copyright (C) 2004, 2014, Makoto Matsumoto and Takuji Nishimura, 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions 16 | are met: 17 | 18 | 1. Redistributions of source code must retain the above copyright 19 | notice, this list of conditions and the following disclaimer. 20 | 21 | 2. Redistributions in binary form must reproduce the above copyright 22 | notice, this list of conditions and the following disclaimer in the 23 | documentation and/or other materials provided with the distribution. 24 | 25 | 3. The names of its contributors may not be used to endorse or promote 26 | products derived from this software without specific prior written 27 | permission. 28 | 29 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 33 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 34 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 35 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 36 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 37 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 38 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 39 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | 41 | References: 42 | T. Nishimura, ``Tables of 64-bit Mersenne Twisters'' 43 | ACM Transactions on Modeling and 44 | Computer Simulation 10. (2000) 348--357. 45 | M. Matsumoto and T. Nishimura, 46 | ``Mersenne Twister: a 623-dimensionally equidistributed 47 | uniform pseudorandom number generator'' 48 | ACM Transactions on Modeling and 49 | Computer Simulation 8. (Jan. 1998) 3--30. 50 | 51 | Any feedback is very welcome. 52 | http://www.math.hiroshima-u.ac.jp/~m-mat/MT/emt.html 53 | email: m-mat @ math.sci.hiroshima-u.ac.jp (remove spaces) 54 | */ 55 | 56 | using System; 57 | using System.Runtime.CompilerServices; 58 | 59 | using uint32_t = System.UInt32; 60 | using uint64_t = System.UInt64; 61 | 62 | namespace MersenneTwister.MT 63 | { 64 | #if PUBLIC 65 | public 66 | #else 67 | internal 68 | #endif 69 | sealed class mt19937_64_t : mt_base_t, Imt19937_64 70 | { 71 | private const int NN = 312; 72 | private const int MM = 156; 73 | private const uint64_t MATRIX_A = 0xB5026F5AA96619E9UL; 74 | private const uint64_t UM = 0xFFFFFFFF80000000UL; /* Most significant 33 bits */ 75 | private const uint64_t LM = 0x7FFFFFFFUL; /* Least significant 31 bits */ 76 | 77 | /* The array for the state vector */ 78 | private readonly uint64_t[] mt = new uint64_t[NN]; 79 | /* mti==NN+1 means mt[NN] is not initialized */ 80 | private uint mti = NN + 1; 81 | 82 | /* initializes mt[NN] with a seed */ 83 | public void init_genrand64(uint64_t seed) 84 | { 85 | var mt = this.mt; 86 | mt[0] = seed; 87 | for (mti = 1; mti < NN; mti++) { 88 | mt[mti] = (6364136223846793005UL * (mt[mti - 1] ^ (mt[mti - 1] >> 62)) + mti); 89 | } 90 | } 91 | 92 | /* initialize by an array with array-length */ 93 | /* init_key is the array for initializing keys */ 94 | /* key_length is its length */ 95 | public void init_by_array64(uint64_t[] init_key, uint64_t key_length) 96 | { 97 | var mt = this.mt; 98 | uint i, j; 99 | uint64_t k; 100 | init_genrand64(19650218UL); 101 | i = 1; 102 | j = 0; 103 | k = (NN > key_length ? NN : key_length); 104 | for (; k != 0; k--) { 105 | mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 62)) * 3935559000370003845UL)) + init_key[j] + j; /* non linear */ 106 | i++; 107 | j++; 108 | if (i >= NN) { mt[0] = mt[NN - 1]; i = 1; } 109 | if (j >= key_length) { 110 | j = 0; 111 | } 112 | } 113 | for (k = NN - 1; k != 0; k--) { 114 | mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 62)) * 2862933555777941757UL)) - i; /* non linear */ 115 | i++; 116 | if (i >= NN) { mt[0] = mt[NN - 1]; i = 1; } 117 | } 118 | 119 | mt[0] = 1UL << 63; /* MSB is 1; assuring non-zero initial array */ 120 | } 121 | 122 | private static readonly uint64_t[] mag01 = new[] { 0UL, MATRIX_A }; 123 | 124 | /* generates a random number on [0, 2^64-1]-interval */ 125 | public uint64_t genrand64_int64() 126 | { 127 | var mt = this.mt; 128 | int i; 129 | uint64_t x; 130 | 131 | if (mti >= NN) { /* generate NN words at one time */ 132 | 133 | /* if init_genrand64() has not been called, */ 134 | /* a default initial seed is used */ 135 | if (mti == NN + 1) { 136 | init_genrand64(5489UL); 137 | } 138 | 139 | for (i = 0; i < NN - MM; i++) { 140 | x = (mt[i] & UM) | (mt[i + 1] & LM); 141 | mt[i] = mt[i + MM] ^ (x >> 1) ^ mag01[(uint)x & 1]; 142 | } 143 | for (; i < NN - 1; i++) { 144 | x = (mt[i] & UM) | (mt[i + 1] & LM); 145 | mt[i] = mt[i + (MM - NN)] ^ (x >> 1) ^ mag01[(uint)x & 1]; 146 | } 147 | x = (mt[NN - 1] & UM) | (mt[0] & LM); 148 | mt[NN - 1] = mt[MM - 1] ^ (x >> 1) ^ mag01[(uint)x & 1]; 149 | 150 | mti = 0; 151 | } 152 | 153 | x = mt[mti++]; 154 | 155 | x ^= (x >> 29) & 0x5555555555555555UL; 156 | x ^= (x << 17) & 0x71D67FFFEDA60000UL; 157 | x ^= (x << 37) & 0xFFF7EEE000000000UL; 158 | x ^= (x >> 43); 159 | 160 | return x; 161 | } 162 | 163 | /* generates a random number on [0, 2^63-1]-interval */ 164 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 165 | public long genrand64_int63() 166 | { 167 | return (long)(genrand64_int64() >> 1); 168 | } 169 | 170 | /* generates a random number on [0,1]-real-interval */ 171 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 172 | public double genrand64_real1() 173 | { 174 | return (genrand64_int64() >> 11) * (1.0 / 9007199254740991.0); 175 | } 176 | 177 | /* generates a random number on [0,1)-real-interval */ 178 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 179 | public double genrand64_real2() 180 | { 181 | return (genrand64_int64() >> 11) * (1.0 / 9007199254740992.0); 182 | } 183 | 184 | /* generates a random number on (0,1)-real-interval */ 185 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 186 | public double genrand64_real3() 187 | { 188 | return ((genrand64_int64() >> 12) + 0.5) * (1.0 / 4503599627370496.0); 189 | } 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # 上位ディレクトリから .editorconfig 設定を継承する場合は、以下の行を削除します 2 | root = true 3 | 4 | # C# ファイル 5 | [*.cs] 6 | 7 | #### コア EditorConfig オプション #### 8 | 9 | # インデントと間隔 10 | indent_size = 4 11 | indent_style = space 12 | tab_width = 4 13 | 14 | # 改行設定 15 | end_of_line = crlf 16 | insert_final_newline = true 17 | 18 | #### .NET コーディング規則 #### 19 | 20 | # using の整理 21 | dotnet_separate_import_directive_groups = false 22 | dotnet_sort_system_directives_first = true 23 | 24 | # this. と Me. の設定 25 | dotnet_style_qualification_for_event = true:silent 26 | dotnet_style_qualification_for_field = true:silent 27 | dotnet_style_qualification_for_method = true:silent 28 | dotnet_style_qualification_for_property = true:silent 29 | 30 | # 言語キーワードと BCL の種類の設定 31 | dotnet_style_predefined_type_for_locals_parameters_members = true:silent 32 | dotnet_style_predefined_type_for_member_access = true:silent 33 | 34 | # かっこの設定 35 | dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent 36 | dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent 37 | dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent 38 | dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent 39 | 40 | # 修飾子設定 41 | dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent 42 | 43 | # 式レベルの設定 44 | csharp_style_deconstructed_variable_declaration = true:suggestion 45 | csharp_style_inlined_variable_declaration = true:suggestion 46 | csharp_style_throw_expression = false:suggestion 47 | dotnet_style_coalesce_expression = true:suggestion 48 | dotnet_style_collection_initializer = true:suggestion 49 | dotnet_style_explicit_tuple_names = true:suggestion 50 | dotnet_style_null_propagation = true:suggestion 51 | dotnet_style_object_initializer = true:suggestion 52 | dotnet_style_prefer_auto_properties = true:silent 53 | dotnet_style_prefer_compound_assignment = true:suggestion 54 | dotnet_style_prefer_conditional_expression_over_assignment = true:silent 55 | dotnet_style_prefer_conditional_expression_over_return = true:silent 56 | dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion 57 | dotnet_style_prefer_inferred_tuple_names = true:suggestion 58 | dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion 59 | 60 | # フィールド設定 61 | dotnet_style_readonly_field = true:suggestion 62 | 63 | # パラメーターの設定 64 | dotnet_code_quality_unused_parameters = all:suggestion 65 | 66 | #### C# コーディング規則 #### 67 | 68 | # var を優先 69 | csharp_style_var_elsewhere = true:silent 70 | csharp_style_var_for_built_in_types = true:silent 71 | csharp_style_var_when_type_is_apparent = true:silent 72 | 73 | # 式のようなメンバー 74 | csharp_style_expression_bodied_accessors = true:silent 75 | csharp_style_expression_bodied_constructors = false:silent 76 | csharp_style_expression_bodied_indexers = true:silent 77 | csharp_style_expression_bodied_lambdas = true:silent 78 | csharp_style_expression_bodied_local_functions = false:silent 79 | csharp_style_expression_bodied_methods = false:silent 80 | csharp_style_expression_bodied_operators = false:silent 81 | csharp_style_expression_bodied_properties = true:silent 82 | 83 | # パターン マッチング設定 84 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion 85 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion 86 | 87 | # Null チェック設定 88 | csharp_style_conditional_delegate_call = true:suggestion 89 | 90 | # 修飾子設定 91 | csharp_prefer_static_local_function = true:suggestion 92 | csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async 93 | 94 | # コード ブロックの設定 95 | csharp_prefer_braces = true:silent 96 | csharp_prefer_simple_using_statement = false:silent 97 | 98 | # 式レベルの設定 99 | csharp_prefer_simple_default_expression = true:suggestion 100 | csharp_style_pattern_local_over_anonymous_function = true:suggestion 101 | csharp_style_prefer_index_operator = true:suggestion 102 | csharp_style_prefer_range_operator = true:suggestion 103 | csharp_style_unused_value_assignment_preference = discard_variable:suggestion 104 | csharp_style_unused_value_expression_statement_preference = discard_variable:silent 105 | 106 | # 'using' ディレクティブの基本設定 107 | csharp_using_directive_placement = outside_namespace:silent 108 | 109 | #### C# 書式ルール #### 110 | 111 | # 改行設定 112 | csharp_new_line_before_catch = true 113 | csharp_new_line_before_else = true 114 | csharp_new_line_before_finally = true 115 | csharp_new_line_before_members_in_anonymous_types = true 116 | csharp_new_line_before_members_in_object_initializers = true 117 | csharp_new_line_before_open_brace = methods,types 118 | csharp_new_line_between_query_expression_clauses = true 119 | 120 | # インデント設定 121 | csharp_indent_block_contents = true 122 | csharp_indent_braces = false 123 | csharp_indent_case_contents = true 124 | csharp_indent_case_contents_when_block = true 125 | csharp_indent_labels = one_less_than_current 126 | csharp_indent_switch_labels = false 127 | 128 | # スペース設定 129 | csharp_space_after_cast = false 130 | csharp_space_after_colon_in_inheritance_clause = true 131 | csharp_space_after_comma = true 132 | csharp_space_after_dot = false 133 | csharp_space_after_keywords_in_control_flow_statements = true 134 | csharp_space_after_semicolon_in_for_statement = true 135 | csharp_space_around_binary_operators = before_and_after 136 | csharp_space_around_declaration_statements = false 137 | csharp_space_before_colon_in_inheritance_clause = true 138 | csharp_space_before_comma = false 139 | csharp_space_before_dot = false 140 | csharp_space_before_open_square_brackets = false 141 | csharp_space_before_semicolon_in_for_statement = false 142 | csharp_space_between_empty_square_brackets = false 143 | csharp_space_between_method_call_empty_parameter_list_parentheses = false 144 | csharp_space_between_method_call_name_and_opening_parenthesis = false 145 | csharp_space_between_method_call_parameter_list_parentheses = false 146 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false 147 | csharp_space_between_method_declaration_name_and_open_parenthesis = false 148 | csharp_space_between_method_declaration_parameter_list_parentheses = false 149 | csharp_space_between_parentheses = false 150 | csharp_space_between_square_brackets = false 151 | 152 | # 折り返しの設定 153 | csharp_preserve_single_line_blocks = true 154 | csharp_preserve_single_line_statements = false 155 | 156 | #### 命名スタイル #### 157 | 158 | # 命名規則 159 | 160 | dotnet_naming_rule.interface_should_be_i_で始まる.severity = suggestion 161 | dotnet_naming_rule.interface_should_be_i_で始まる.symbols = interface 162 | dotnet_naming_rule.interface_should_be_i_で始まる.style = i_で始まる 163 | 164 | dotnet_naming_rule.型_should_be_パスカル_ケース.severity = suggestion 165 | dotnet_naming_rule.型_should_be_パスカル_ケース.symbols = 型 166 | dotnet_naming_rule.型_should_be_パスカル_ケース.style = パスカル_ケース 167 | 168 | dotnet_naming_rule.フィールド以外のメンバー_should_be_パスカル_ケース.severity = suggestion 169 | dotnet_naming_rule.フィールド以外のメンバー_should_be_パスカル_ケース.symbols = フィールド以外のメンバー 170 | dotnet_naming_rule.フィールド以外のメンバー_should_be_パスカル_ケース.style = パスカル_ケース 171 | 172 | # 記号の仕様 173 | 174 | dotnet_naming_symbols.interface.applicable_kinds = interface 175 | dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal 176 | dotnet_naming_symbols.interface.required_modifiers = 177 | 178 | dotnet_naming_symbols.型.applicable_kinds = class, struct, interface, enum 179 | dotnet_naming_symbols.型.applicable_accessibilities = public, internal, private, protected, protected_internal 180 | dotnet_naming_symbols.型.required_modifiers = 181 | 182 | dotnet_naming_symbols.フィールド以外のメンバー.applicable_kinds = property, event, method 183 | dotnet_naming_symbols.フィールド以外のメンバー.applicable_accessibilities = public, internal, private, protected, protected_internal 184 | dotnet_naming_symbols.フィールド以外のメンバー.required_modifiers = 185 | 186 | # 命名スタイル 187 | 188 | dotnet_naming_style.パスカル_ケース.required_prefix = 189 | dotnet_naming_style.パスカル_ケース.required_suffix = 190 | dotnet_naming_style.パスカル_ケース.word_separator = 191 | dotnet_naming_style.パスカル_ケース.capitalization = pascal_case 192 | 193 | dotnet_naming_style.i_で始まる.required_prefix = I 194 | dotnet_naming_style.i_で始まる.required_suffix = 195 | dotnet_naming_style.i_で始まる.word_separator = 196 | dotnet_naming_style.i_で始まる.capitalization = pascal_case 197 | -------------------------------------------------------------------------------- /MersenneTwister/MT/mt19937ar_t.cs: -------------------------------------------------------------------------------- 1 | /* 2 | A C-program for MT19937, with initialization improved 2002/1/26. 3 | Coded by Takuji Nishimura and Makoto Matsumoto. 4 | 5 | Before using, initialize the state by using init_genrand(seed) 6 | or init_by_array(init_key, key_length). 7 | 8 | Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions 13 | are met: 14 | 15 | 1. Redistributions of source code must retain the above copyright 16 | notice, this list of conditions and the following disclaimer. 17 | 18 | 2. Redistributions in binary form must reproduce the above copyright 19 | notice, this list of conditions and the following disclaimer in the 20 | documentation and/or other materials provided with the distribution. 21 | 22 | 3. The names of its contributors may not be used to endorse or promote 23 | products derived from this software without specific prior written 24 | permission. 25 | 26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 30 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 31 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 32 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 33 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 34 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 35 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 36 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | 38 | 39 | Any feedback is very welcome. 40 | http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html 41 | email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) 42 | */ 43 | 44 | using System; 45 | using System.Runtime.CompilerServices; 46 | 47 | namespace MersenneTwister.MT 48 | { 49 | #if PUBLIC 50 | public 51 | #else 52 | internal 53 | #endif 54 | sealed class mt19937ar_t : mt_base_t, Imt19937 55 | { 56 | /* Period parameters */ 57 | private const int N = 624; 58 | private const int M = 397; 59 | private const uint MATRIX_A = 0x9908b0dfU; /* constant vector a */ 60 | private const uint UPPER_MASK = 0x80000000U; /* most significant w-r bits */ 61 | private const uint LOWER_MASK = 0x7fffffffU; /* least significant r bits */ 62 | 63 | private readonly uint[] mt = new uint[N]; /* the array for the state vector */ 64 | 65 | private uint mti = N + 1; /* mti==N+1 means mt[N] is not initialized */ 66 | 67 | /* initializes mt[N] with a seed */ 68 | public void init_genrand(uint s) 69 | { 70 | var mt = this.mt; 71 | mt[0] = s & 0xffffffffU; 72 | for (mti = 1; mti < N; mti++) { 73 | mt[mti] = (1812433253U * (mt[mti - 1] ^ (mt[mti - 1] >> 30)) + mti); 74 | /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ 75 | /* In the previous versions, MSBs of the seed affect */ 76 | /* only MSBs of the array mt[]. */ 77 | /* 2002/01/09 modified by Makoto Matsumoto */ 78 | mt[mti] &= 0xffffffffU; 79 | /* for >32 bit machines */ 80 | } 81 | } 82 | 83 | /* initialize by an array with array-length */ 84 | /* init_key is the array for initializing keys */ 85 | /* key_length is its length */ 86 | /* slight change for C++, 2004/2/26 */ 87 | public void init_by_array(uint[] init_key, int key_length) 88 | { 89 | var mt = this.mt; 90 | init_genrand(19650218U); 91 | uint i = 1; 92 | uint j = 0; 93 | int k = (N > key_length ? N : key_length); 94 | for (; k != 0; k--) { 95 | mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1664525U)) + init_key[j] + j; /* non linear */ 96 | mt[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */ 97 | i++; 98 | j++; 99 | if (i >= N) { mt[0] = mt[N - 1]; i = 1; } 100 | if (j >= key_length) { 101 | j = 0; 102 | } 103 | } 104 | for (k = N - 1; k != 0; k--) { 105 | mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1566083941U)) - i; /* non linear */ 106 | mt[i] &= 0xffffffffU; /* for WORDSIZE > 32 machines */ 107 | i++; 108 | if (i >= N) { mt[0] = mt[N - 1]; i = 1; } 109 | } 110 | 111 | mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */ 112 | } 113 | 114 | private static readonly uint[] mag01 = new[] { 0x0U, MATRIX_A }; 115 | 116 | /* generates a random number on [0,0xffffffff]-interval */ 117 | public uint genrand_int32() 118 | { 119 | var mt = this.mt; 120 | uint y; 121 | /* mag01[x] = x * MATRIX_A for x=0,1 */ 122 | 123 | if (mti >= N) { /* generate N words at one time */ 124 | int kk; 125 | 126 | if (mti == N + 1) { /* if init_genrand() has not been called, */ 127 | init_genrand(5489U); /* a default initial seed is used */ 128 | } 129 | 130 | for (kk = 0; kk < N - M; kk++) { 131 | y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK); 132 | mt[kk] = mt[kk + M] ^ (y >> 1) ^ mag01[y & 0x1U]; 133 | } 134 | for (; kk < N - 1; kk++) { 135 | y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK); 136 | mt[kk] = mt[kk + (M - N)] ^ (y >> 1) ^ mag01[y & 0x1U]; 137 | } 138 | y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK); 139 | mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ mag01[y & 0x1U]; 140 | 141 | mti = 0; 142 | } 143 | 144 | y = mt[mti++]; 145 | 146 | /* Tempering */ 147 | y ^= (y >> 11); 148 | y ^= (y << 7) & 0x9d2c5680U; 149 | y ^= (y << 15) & 0xefc60000U; 150 | y ^= (y >> 18); 151 | 152 | return y; 153 | } 154 | 155 | /* generates a random number on [0,0x7fffffff]-interval */ 156 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 157 | public int genrand_int31() 158 | { 159 | return (int)(genrand_int32() >> 1); 160 | } 161 | 162 | /* generates a random number on [0,1]-real-interval */ 163 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 164 | public double genrand_real1() 165 | { 166 | return genrand_int32() * (1.0 / 4294967295.0); 167 | /* divided by 2^32-1 */ 168 | } 169 | 170 | /* generates a random number on [0,1)-real-interval */ 171 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 172 | public double genrand_real2() 173 | { 174 | return genrand_int32() * (1.0 / 4294967296.0); 175 | /* divided by 2^32 */ 176 | } 177 | 178 | /* generates a random number on (0,1)-real-interval */ 179 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 180 | public double genrand_real3() 181 | { 182 | return (genrand_int32() + 0.5) * (1.0 / 4294967296.0); 183 | /* divided by 2^32 */ 184 | } 185 | /* These real versions are due to Isaku Wada, 2002/01/09 added */ 186 | 187 | /* generates a random number on [0,1) with 53-bit resolution*/ 188 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 189 | public double genrand_res53() 190 | { 191 | uint a = genrand_int32() >> 5, b = genrand_int32() >> 6; 192 | return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0); 193 | } 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /MersenneTwister/MT/mt19937ar_cok_t.cs: -------------------------------------------------------------------------------- 1 | /* 2 | A C-program for MT19937, with initialization improved 2002/2/10. 3 | Coded by Takuji Nishimura and Makoto Matsumoto. 4 | This is a faster version by taking Shawn Cokus's optimization, 5 | Matthe Bellew's simplification, Isaku Wada's real version. 6 | 7 | Before using, initialize the mt by using init_genrand(seed) 8 | or init_by_array(init_key, key_length). 9 | 10 | Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, 11 | All rights reserved. 12 | 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions 15 | are met: 16 | 17 | 1. Redistributions of source code must retain the above copyright 18 | notice, this list of conditions and the following disclaimer. 19 | 20 | 2. Redistributions in binary form must reproduce the above copyright 21 | notice, this list of conditions and the following disclaimer in the 22 | documentation and/or other materials provided with the distribution. 23 | 24 | 3. The names of its contributors may not be used to endorse or promote 25 | products derived from this software without specific prior written 26 | permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 32 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 33 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 34 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 35 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 36 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 37 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 38 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 | 40 | 41 | Any feedback is very welcome. 42 | http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html 43 | email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) 44 | */ 45 | 46 | using System; 47 | using System.Runtime.CompilerServices; 48 | 49 | namespace MersenneTwister.MT 50 | { 51 | #if PUBLIC 52 | public 53 | #else 54 | internal 55 | #endif 56 | sealed class mt19937ar_cok_t : mt_base_t, Imt19937 57 | { 58 | /* Period parameters */ 59 | private const int N = 624; 60 | private const int M = 397; 61 | private const uint MATRIX_A = 0x9908b0dfU; /* constant vector a */ 62 | private const uint UMASK = 0x80000000U; /* most significant w-r bits */ 63 | private const uint LMASK = 0x7fffffffU; /* least significant r bits */ 64 | 65 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 66 | private static uint MIXBITS(uint u, uint v) 67 | { 68 | return (((u) & UMASK) | ((v) & LMASK)); 69 | } 70 | 71 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 72 | private static uint TWIST(uint u, uint v) 73 | { 74 | return ((MIXBITS(u, v) >> 1) ^ (((v & 1U) != 0) ? MATRIX_A : 0U)); 75 | } 76 | 77 | private readonly uint[] mt = new uint[N]; /* the array for the state vector */ 78 | private int left = 1; 79 | private int initf = 0; 80 | private uint next; 81 | 82 | /* initializes mt[N] with a seed */ 83 | public void init_genrand(uint s) 84 | { 85 | var mt = this.mt; 86 | uint j; 87 | mt[0] = s; 88 | for (j = 1; j < N; j++) { 89 | mt[j] = (1812433253U * (mt[j - 1] ^ (mt[j - 1] >> 30)) + j); 90 | /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ 91 | /* In the previous versions, MSBs of the seed affect */ 92 | /* only MSBs of the array mt[]. */ 93 | /* 2002/01/09 modified by Makoto Matsumoto */ 94 | } 95 | left = 1; 96 | initf = 1; 97 | } 98 | 99 | /* initialize by an array with array-length */ 100 | /* init_key is the array for initializing keys */ 101 | /* key_length is its length */ 102 | /* slight change for C++, 2004/2/26 */ 103 | public void init_by_array(uint[] init_key, int key_length) 104 | { 105 | var mt = this.mt; 106 | init_genrand(19650218U); 107 | uint i = 1; 108 | uint j = 0; 109 | int k = (N > key_length ? N : key_length); 110 | for (; k != 0; k--) { 111 | mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1664525U)) + init_key[j] + j; /* non linear */ 112 | i++; 113 | j++; 114 | if (i >= N) { mt[0] = mt[N - 1]; i = 1; } 115 | if (j >= key_length) { 116 | j = 0; 117 | } 118 | } 119 | for (k = N - 1; k != 0; k--) { 120 | mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1566083941U)) - i; /* non linear */ 121 | i++; 122 | if (i >= N) { mt[0] = mt[N - 1]; i = 1; } 123 | } 124 | 125 | mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */ 126 | left = 1; 127 | initf = 1; 128 | } 129 | 130 | private void next_state() 131 | { 132 | var mt = this.mt; 133 | 134 | /* if init_genrand() has not been called, */ 135 | /* a default initial seed is used */ 136 | if (initf == 0) { 137 | init_genrand(5489U); 138 | } 139 | 140 | left = N; 141 | next = 0; 142 | 143 | uint p = 0; 144 | for (int j = N - M + 1; --j > 0; p++) { 145 | mt[p] = mt[p + M] ^ TWIST(mt[p], mt[p + 1]); 146 | } 147 | 148 | for (int j = M; --j > 0; p++) { 149 | mt[p] = mt[p + (M - N)] ^ TWIST(mt[p], mt[p + 1]); 150 | } 151 | 152 | mt[p] = mt[p + (M - N)] ^ TWIST(mt[p], mt[0]); 153 | } 154 | 155 | private static readonly uint[] mag01 = new[] { 0x0U, MATRIX_A }; 156 | 157 | /* generates a random number on [0,0xffffffff]-interval */ 158 | public uint genrand_int32() 159 | { 160 | uint y; 161 | if (--left == 0) { 162 | next_state(); 163 | } 164 | 165 | y = this.mt[next++]; 166 | 167 | /* Tempering */ 168 | y ^= (y >> 11); 169 | y ^= (y << 7) & 0x9d2c5680U; 170 | y ^= (y << 15) & 0xefc60000U; 171 | y ^= (y >> 18); 172 | 173 | return y; 174 | } 175 | 176 | /* generates a random number on [0,0x7fffffff]-interval */ 177 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 178 | public int genrand_int31() 179 | { 180 | return (int)(genrand_int32() >> 1); 181 | } 182 | 183 | /* generates a random number on [0,1]-real-interval */ 184 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 185 | public double genrand_real1() 186 | { 187 | return genrand_int32() * (1.0 / 4294967295.0); 188 | /* divided by 2^32-1 */ 189 | } 190 | 191 | /* generates a random number on [0,1)-real-interval */ 192 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 193 | public double genrand_real2() 194 | { 195 | return genrand_int32() * (1.0 / 4294967296.0); 196 | /* divided by 2^32 */ 197 | } 198 | 199 | /* generates a random number on (0,1)-real-interval */ 200 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 201 | public double genrand_real3() 202 | { 203 | return (genrand_int32() + 0.5) * (1.0 / 4294967296.0); 204 | /* divided by 2^32 */ 205 | } 206 | /* These real versions are due to Isaku Wada, 2002/01/09 added */ 207 | 208 | /* generates a random number on [0,1) with 53-bit resolution*/ 209 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 210 | public double genrand_res53() 211 | { 212 | uint a = genrand_int32() >> 5, b = genrand_int32() >> 6; 213 | return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0); 214 | } 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /MersenneTwister/MT/mt19937ar_cok_opt_t.cs: -------------------------------------------------------------------------------- 1 | /* 2 | A C-program for MT19937, with initialization improved 2002/2/10. 3 | Coded by Takuji Nishimura and Makoto Matsumoto. 4 | This is a faster version by taking Shawn Cokus's optimization, 5 | Matthe Bellew's simplification, Isaku Wada's real version. 6 | 7 | Before using, initialize the mt by using init_genrand(seed) 8 | or init_by_array(init_key, key_length). 9 | 10 | Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, 11 | All rights reserved. 12 | 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions 15 | are met: 16 | 17 | 1. Redistributions of source code must retain the above copyright 18 | notice, this list of conditions and the following disclaimer. 19 | 20 | 2. Redistributions in binary form must reproduce the above copyright 21 | notice, this list of conditions and the following disclaimer in the 22 | documentation and/or other materials provided with the distribution. 23 | 24 | 3. The names of its contributors may not be used to endorse or promote 25 | products derived from this software without specific prior written 26 | permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 32 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 33 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 34 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 35 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 36 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 37 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 38 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 | 40 | 41 | Any feedback is very welcome. 42 | http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html 43 | email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) 44 | */ 45 | 46 | using System; 47 | using System.Runtime.CompilerServices; 48 | 49 | namespace MersenneTwister.MT 50 | { 51 | #if PUBLIC 52 | public 53 | #else 54 | internal 55 | #endif 56 | sealed class mt19937ar_cok_opt_t : mt_base_t, Imt19937 57 | { 58 | /* Period parameters */ 59 | private const int N = 624; 60 | private const int M = 397; 61 | private const uint MATRIX_A = 0x9908b0dfU; /* constant vector a */ 62 | private const uint UMASK = 0x80000000U; /* most significant w-r bits */ 63 | private const uint LMASK = 0x7fffffffU; /* least significant r bits */ 64 | 65 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 66 | private static uint MIXBITS(uint u, uint v) 67 | { 68 | return (((u) & UMASK) | ((v) & LMASK)); 69 | } 70 | 71 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 72 | private static uint TWIST(uint u, uint v) 73 | { 74 | return ((MIXBITS(u, v) >> 1) ^ mag01[v & 1U]); 75 | } 76 | 77 | private readonly uint[] mt = new uint[N]; /* the array for the state vector */ 78 | private int left = 1; 79 | private int initf = 0; 80 | private uint next; 81 | 82 | /* initializes mt[N] with a seed */ 83 | public void init_genrand(uint s) 84 | { 85 | var mt = this.mt; 86 | uint j; 87 | mt[0] = s; 88 | for (j = 1; j < N; j++) { 89 | mt[j] = (1812433253U * (mt[j - 1] ^ (mt[j - 1] >> 30)) + j); 90 | /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ 91 | /* In the previous versions, MSBs of the seed affect */ 92 | /* only MSBs of the array mt[]. */ 93 | /* 2002/01/09 modified by Makoto Matsumoto */ 94 | } 95 | left = 1; 96 | initf = 1; 97 | } 98 | 99 | /* initialize by an array with array-length */ 100 | /* init_key is the array for initializing keys */ 101 | /* key_length is its length */ 102 | /* slight change for C++, 2004/2/26 */ 103 | public void init_by_array(uint[] init_key, int key_length) 104 | { 105 | var mt = this.mt; 106 | init_genrand(19650218U); 107 | uint i = 1; 108 | uint j = 0; 109 | int k = (N > key_length ? N : key_length); 110 | for (; k != 0; k--) { 111 | mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1664525U)) + init_key[j] + j; /* non linear */ 112 | i++; 113 | j++; 114 | if (i >= N) { mt[0] = mt[N - 1]; i = 1; } 115 | if (j >= key_length) { 116 | j = 0; 117 | } 118 | } 119 | for (k = N - 1; k != 0; k--) { 120 | mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 1566083941U)) - i; /* non linear */ 121 | i++; 122 | if (i >= N) { mt[0] = mt[N - 1]; i = 1; } 123 | } 124 | 125 | mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */ 126 | left = 1; 127 | initf = 1; 128 | } 129 | 130 | private void next_state() 131 | { 132 | var mt = this.mt; 133 | 134 | /* if init_genrand() has not been called, */ 135 | /* a default initial seed is used */ 136 | if (initf == 0) { 137 | init_genrand(5489U); 138 | } 139 | 140 | left = N; 141 | next = 0; 142 | 143 | uint p = 0; 144 | for (int j = N - M + 1; --j > 0; p++) { 145 | mt[p] = mt[p + M] ^ TWIST(mt[p], mt[p + 1]); 146 | } 147 | 148 | for (int j = M; --j > 0; p++) { 149 | mt[p] = mt[p + (M - N)] ^ TWIST(mt[p], mt[p + 1]); 150 | } 151 | 152 | mt[p] = mt[p + (M - N)] ^ TWIST(mt[p], mt[0]); 153 | } 154 | 155 | private static readonly uint[] mag01 = new[] { 0x0U, MATRIX_A }; 156 | 157 | /* generates a random number on [0,0xffffffff]-interval */ 158 | public uint genrand_int32() 159 | { 160 | uint y; 161 | if (--left == 0) { 162 | next_state(); 163 | } 164 | 165 | y = this.mt[next++]; 166 | 167 | /* Tempering */ 168 | y ^= (y >> 11); 169 | y ^= (y << 7) & 0x9d2c5680U; 170 | y ^= (y << 15) & 0xefc60000U; 171 | y ^= (y >> 18); 172 | 173 | return y; 174 | } 175 | 176 | /* generates a random number on [0,0x7fffffff]-interval */ 177 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 178 | public int genrand_int31() 179 | { 180 | return (int)(genrand_int32() >> 1); 181 | } 182 | 183 | /* generates a random number on [0,1]-real-interval */ 184 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 185 | public double genrand_real1() 186 | { 187 | return genrand_int32() * (1.0 / 4294967295.0); 188 | /* divided by 2^32-1 */ 189 | } 190 | 191 | /* generates a random number on [0,1)-real-interval */ 192 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 193 | public double genrand_real2() 194 | { 195 | return genrand_int32() * (1.0 / 4294967296.0); 196 | /* divided by 2^32 */ 197 | } 198 | 199 | /* generates a random number on (0,1)-real-interval */ 200 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 201 | public double genrand_real3() 202 | { 203 | return (genrand_int32() + 0.5) * (1.0 / 4294967296.0); 204 | /* divided by 2^32 */ 205 | } 206 | /* These real versions are due to Isaku Wada, 2002/01/09 added */ 207 | 208 | /* generates a random number on [0,1) with 53-bit resolution*/ 209 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 210 | public double genrand_res53() 211 | { 212 | uint a = genrand_int32() >> 5, b = genrand_int32() >> 6; 213 | //return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0); 214 | return (((ulong)a << 26) | b) * (1.0 / 9007199254740992.0); 215 | } 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /MersenneTwister.Tests/MersenneTwister.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {CE129CFC-57E2-49F3-9C41-22C35BDEFF63} 7 | Library 8 | Properties 9 | MersenneTwister.Tests 10 | MersenneTwister.Tests 11 | v4.5 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 10.0 15 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 16 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 17 | False 18 | UnitTest 19 | 20 | 21 | 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | true 30 | 31 | 32 | pdbonly 33 | true 34 | bin\Inspection\ 35 | TRACE 36 | prompt 37 | 4 38 | true 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | False 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | PreserveNewest 74 | 75 | 76 | PreserveNewest 77 | 78 | 79 | PreserveNewest 80 | 81 | 82 | PreserveNewest 83 | 84 | 85 | PreserveNewest 86 | 87 | 88 | PreserveNewest 89 | 90 | 91 | PreserveNewest 92 | 93 | 94 | PreserveNewest 95 | 96 | 97 | PreserveNewest 98 | 99 | 100 | PreserveNewest 101 | 102 | 103 | PreserveNewest 104 | 105 | 106 | PreserveNewest 107 | 108 | 109 | PreserveNewest 110 | 111 | 112 | PreserveNewest 113 | 114 | 115 | PreserveNewest 116 | 117 | 118 | PreserveNewest 119 | 120 | 121 | PreserveNewest 122 | 123 | 124 | PreserveNewest 125 | 126 | 127 | PreserveNewest 128 | 129 | 130 | PreserveNewest 131 | 132 | 133 | PreserveNewest 134 | 135 | 136 | PreserveNewest 137 | 138 | 139 | 140 | 141 | {fbf197ea-e04c-4e0b-99fb-bbb60a4bdb83} 142 | MersenneTwister 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | False 153 | 154 | 155 | False 156 | 157 | 158 | False 159 | 160 | 161 | False 162 | 163 | 164 | 165 | 166 | 167 | 168 | 175 | -------------------------------------------------------------------------------- /MersenneTwister/MT/mt19937_64_opt_t.cs: -------------------------------------------------------------------------------- 1 | /* 2 | A C-program for MT19937-64 (2014/2/23 version). 3 | Coded by Takuji Nishimura and Makoto Matsumoto. 4 | 5 | This is a 64-bit version of Mersenne Twister pseudorandom number 6 | generator. 7 | 8 | Before using, initialize the state by using init_genrand64(seed) 9 | or init_by_array64(init_key, key_length). 10 | 11 | Copyright (C) 2004, 2014, Makoto Matsumoto and Takuji Nishimura, 12 | All rights reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions 16 | are met: 17 | 18 | 1. Redistributions of source code must retain the above copyright 19 | notice, this list of conditions and the following disclaimer. 20 | 21 | 2. Redistributions in binary form must reproduce the above copyright 22 | notice, this list of conditions and the following disclaimer in the 23 | documentation and/or other materials provided with the distribution. 24 | 25 | 3. The names of its contributors may not be used to endorse or promote 26 | products derived from this software without specific prior written 27 | permission. 28 | 29 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 33 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 34 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 35 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 36 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 37 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 38 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 39 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 | 41 | References: 42 | T. Nishimura, ``Tables of 64-bit Mersenne Twisters'' 43 | ACM Transactions on Modeling and 44 | Computer Simulation 10. (2000) 348--357. 45 | M. Matsumoto and T. Nishimura, 46 | ``Mersenne Twister: a 623-dimensionally equidistributed 47 | uniform pseudorandom number generator'' 48 | ACM Transactions on Modeling and 49 | Computer Simulation 8. (Jan. 1998) 3--30. 50 | 51 | Any feedback is very welcome. 52 | http://www.math.hiroshima-u.ac.jp/~m-mat/MT/emt.html 53 | email: m-mat @ math.sci.hiroshima-u.ac.jp (remove spaces) 54 | */ 55 | 56 | using System; 57 | using System.Runtime.CompilerServices; 58 | 59 | using uint32_t = System.UInt32; 60 | using uint64_t = System.UInt64; 61 | 62 | namespace MersenneTwister.MT 63 | { 64 | #if PUBLIC 65 | public 66 | #else 67 | internal 68 | #endif 69 | sealed class mt19937_64_opt_t : mt_base_t, Imt19937_64 70 | { 71 | private const int NN = 312; 72 | private const int MM = 156; 73 | private const uint64_t MATRIX_A = 0xB5026F5AA96619E9UL; 74 | private const uint64_t UM = 0xFFFFFFFF80000000UL; /* Most significant 33 bits */ 75 | private const uint64_t LM = 0x7FFFFFFFUL; /* Least significant 31 bits */ 76 | 77 | /* The array for the state vector */ 78 | private readonly uint64_t[] mt = new uint64_t[NN]; 79 | /* mti==NN+1 means mt[NN] is not initialized */ 80 | private uint mti = NN + 1; 81 | 82 | /* initializes mt[NN] with a seed */ 83 | public void init_genrand64(uint64_t seed) 84 | { 85 | var mt = this.mt; 86 | mt[0] = seed; 87 | for (mti = 1; mti < NN; mti++) { 88 | mt[mti] = (6364136223846793005UL * (mt[mti - 1] ^ (mt[mti - 1] >> 62)) + mti); 89 | } 90 | } 91 | 92 | /* initialize by an array with array-length */ 93 | /* init_key is the array for initializing keys */ 94 | /* key_length is its length */ 95 | public void init_by_array64(uint64_t[] init_key, uint64_t key_length) 96 | { 97 | var mt = this.mt; 98 | uint i, j; 99 | uint64_t k; 100 | init_genrand64(19650218UL); 101 | i = 1; 102 | j = 0; 103 | k = (NN > key_length ? NN : key_length); 104 | for (; k != 0; k--) { 105 | mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 62)) * 3935559000370003845UL)) + init_key[j] + j; /* non linear */ 106 | i++; 107 | j++; 108 | if (i >= NN) { mt[0] = mt[NN - 1]; i = 1; } 109 | if (j >= key_length) { 110 | j = 0; 111 | } 112 | } 113 | for (k = NN - 1; k != 0; k--) { 114 | mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 62)) * 2862933555777941757UL)) - i; /* non linear */ 115 | i++; 116 | if (i >= NN) { mt[0] = mt[NN - 1]; i = 1; } 117 | } 118 | 119 | mt[0] = 1UL << 63; /* MSB is 1; assuring non-zero initial array */ 120 | } 121 | 122 | private static readonly uint64_t[] mag01 = new[] { 0UL, MATRIX_A }; 123 | 124 | /* generates a random number on [0, 2^64-1]-interval */ 125 | public uint64_t genrand64_int64() 126 | { 127 | var mt = this.mt; 128 | int i; 129 | uint64_t x; 130 | 131 | if (mti >= NN) { /* generate NN words at one time */ 132 | for (i = 0; i < NN - MM; i += 4) { 133 | x = (mt[i + 0] & UM) | (mt[i + 1] & LM); 134 | mt[i + 0] = mt[i + (MM + 0)] ^ (x >> 1) ^ mag01[(uint)x & 1]; 135 | x = (mt[i + 1] & UM) | (mt[i + 2] & LM); 136 | mt[i + 1] = mt[i + (MM + 1)] ^ (x >> 1) ^ mag01[(uint)x & 1]; 137 | x = (mt[i + 2] & UM) | (mt[i + 3] & LM); 138 | mt[i + 2] = mt[i + (MM + 2)] ^ (x >> 1) ^ mag01[(uint)x & 1]; 139 | x = (mt[i + 3] & UM) | (mt[i + 4] & LM); 140 | mt[i + 3] = mt[i + (MM + 3)] ^ (x >> 1) ^ mag01[(uint)x & 1]; 141 | } 142 | for (; i < NN - 5; i += 4) { 143 | x = (mt[i + 0] & UM) | (mt[i + 1] & LM); 144 | mt[i + 0] = mt[i + (MM - NN + 0)] ^ (x >> 1) ^ mag01[(uint)x & 1]; 145 | x = (mt[i + 1] & UM) | (mt[i + 2] & LM); 146 | mt[i + 1] = mt[i + (MM - NN + 1)] ^ (x >> 1) ^ mag01[(uint)x & 1]; 147 | x = (mt[i + 2] & UM) | (mt[i + 3] & LM); 148 | mt[i + 2] = mt[i + (MM - NN + 2)] ^ (x >> 1) ^ mag01[(uint)x & 1]; 149 | x = (mt[i + 3] & UM) | (mt[i + 4] & LM); 150 | mt[i + 3] = mt[i + (MM - NN + 3)] ^ (x >> 1) ^ mag01[(uint)x & 1]; 151 | } 152 | x = (mt[i + 0] & UM) | (mt[i + 1] & LM); 153 | mt[i + 0] = mt[i + (MM - NN + 0)] ^ (x >> 1) ^ mag01[(uint)x & 1]; 154 | x = (mt[i + 1] & UM) | (mt[i + 2] & LM); 155 | mt[i + 1] = mt[i + (MM - NN + 1)] ^ (x >> 1) ^ mag01[(uint)x & 1]; 156 | x = (mt[i + 2] & UM) | (mt[i + 3] & LM); 157 | mt[i + 2] = mt[i + (MM - NN + 2)] ^ (x >> 1) ^ mag01[(uint)x & 1]; 158 | 159 | x = (mt[NN - 1] & UM) | (mt[0] & LM); 160 | mt[NN - 1] = mt[MM - 1] ^ (x >> 1) ^ mag01[(uint)x & 1]; 161 | 162 | mti = 0; 163 | } 164 | 165 | x = mt[mti++]; 166 | 167 | x ^= (x >> 29) & 0x5555555555555555UL; 168 | x ^= (x << 17) & 0x71D67FFFEDA60000UL; 169 | x ^= (x << 37) & 0xFFF7EEE000000000UL; 170 | x ^= (x >> 43); 171 | 172 | return x; 173 | } 174 | 175 | /* generates a random number on [0, 2^63-1]-interval */ 176 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 177 | public long genrand64_int63() 178 | { 179 | return (long)(genrand64_int64() >> 1); 180 | } 181 | 182 | /* generates a random number on [0,1]-real-interval */ 183 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 184 | public double genrand64_real1() 185 | { 186 | return (genrand64_int64() >> 11) * (1.0 / 9007199254740991.0); 187 | } 188 | 189 | /* generates a random number on [0,1)-real-interval */ 190 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 191 | public double genrand64_real2() 192 | { 193 | return (genrand64_int64() >> 11) * (1.0 / 9007199254740992.0); 194 | } 195 | 196 | /* generates a random number on (0,1)-real-interval */ 197 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 198 | public double genrand64_real3() 199 | { 200 | return ((genrand64_int64() >> 12) + 0.5) * (1.0 / 4503599627370496.0); 201 | } 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /MersenneTwister.Tests/dsfmt_t_Test.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Runtime.InteropServices; 4 | using MersenneTwister.dSFMT; 5 | using MersenneTwister.SFMT; 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | 8 | using uint32_t = System.UInt32; 9 | using uint64_t = System.UInt64; 10 | 11 | namespace MersenneTwister.Tests 12 | { 13 | [TestClass] 14 | public class dsfmt_t_Test 15 | { 16 | [TestMethod] 17 | public void MersenneTwister_DSFMT() 18 | { 19 | new dsfmt_t_Test().Test(); 20 | } 21 | 22 | [TestMethod] 23 | public void MersenneTwister_DSFMT_opt() 24 | { 25 | new dsfmt_t_Test().Test(); 26 | } 27 | 28 | [TestMethod] 29 | public void MersenneTwister_DSFMT_opt_gen() 30 | { 31 | new dsfmt_t_Test>().Test(); 32 | new dsfmt_t_Test>().Test(); 33 | new dsfmt_t_Test>().Test(); 34 | new dsfmt_t_Test>().Test(); 35 | new dsfmt_t_Test>().Test(); 36 | new dsfmt_t_Test>().Test(); 37 | new dsfmt_t_Test>().Test(); 38 | new dsfmt_t_Test>().Test(); 39 | new dsfmt_t_Test>().Test(); 40 | new dsfmt_t_Test>().Test(); 41 | } 42 | } 43 | 44 | [StructLayout(LayoutKind.Explicit)] 45 | internal struct W64_T 46 | { 47 | [FieldOffset(0)] 48 | public uint64_t u; 49 | [FieldOffset(0)] 50 | public double d; 51 | } 52 | 53 | public class dsfmt_t_Test : TestBase where T : Idsfmt, new() 54 | { 55 | private const int NUM_RANDS = 50000; 56 | private int DSFMT_N { get { return gv.DSFMT_N; } } 57 | 58 | private delegate double genrand_t(); 59 | private delegate double st_genrand_t(T dsfmt); 60 | private unsafe delegate void fill_array_t(double* array, int size); 61 | private unsafe delegate void st_fill_array_t(T dsfmt, double* array, int size); 62 | 63 | private T gv = new T(); 64 | 65 | unsafe void check(string range_str, genrand_t genrand, fill_array_t fill_array, 66 | st_genrand_t st_genrand, st_fill_array_t st_fill_array, 67 | uint32_t seed, int print_size) 68 | { 69 | int i; 70 | w128_t* little = stackalloc w128_t[DSFMT_N + 1]; 71 | W64_T* plittle = (W64_T*)little; 72 | var dummy = new W64_T[(NUM_RANDS / 2 + 1) * 2]; 73 | fixed (W64_T* array = dummy) { 74 | W64_T r = new W64_T(); 75 | W64_T r_st = new W64_T(); 76 | int lsize = DSFMT_N * 2 + 2; 77 | 78 | var dsfmt = new T(); 79 | 80 | printf("generated randoms {0}\n", range_str); 81 | gv.dsfmt_init_gen_rand(seed); 82 | fill_array(&plittle[0].d, lsize); 83 | fill_array(&array[0].d, 5000); 84 | gv.dsfmt_init_gen_rand(seed); 85 | dsfmt.dsfmt_init_gen_rand(seed); 86 | for (i = 0; i < lsize; i++) { 87 | r.d = genrand(); 88 | r_st.d = st_genrand(dsfmt); 89 | Assert.AreEqual(r.u, r_st.u); 90 | Assert.AreEqual(r.u, plittle[i].u); 91 | if (i < print_size) { 92 | printf("{0} ", d2s(plittle[i].d)); 93 | if (i % 4 == 3) { 94 | printf("\n"); 95 | } 96 | } 97 | } 98 | for (i = 0; i < 5000; i++) { 99 | r.d = genrand(); 100 | Assert.AreEqual(r.u, array[i].u); 101 | if (i + lsize < print_size) { 102 | printf("{0} ", d2s(array[i].d)); 103 | if ((i + lsize) % 4 == 3) { 104 | printf("\n"); 105 | } 106 | } 107 | } 108 | 109 | dsfmt.dsfmt_init_gen_rand(seed); 110 | st_fill_array(dsfmt, &plittle[0].d, lsize); 111 | st_fill_array(dsfmt, &array[0].d, 5000); 112 | dsfmt.dsfmt_init_gen_rand(seed); 113 | for (i = 0; i < lsize; i++) { 114 | r_st.d = st_genrand(dsfmt); 115 | Assert.AreEqual(r_st.u, plittle[i].u); 116 | } 117 | for (i = 0; i < 5000; i++) { 118 | r_st.d = st_genrand(dsfmt); 119 | Assert.AreEqual(r_st.u, array[i].u); 120 | } 121 | } 122 | } 123 | 124 | unsafe void check_ar(string range_str, genrand_t genrand, 125 | fill_array_t fill_array, 126 | st_genrand_t st_genrand, 127 | st_fill_array_t st_fill_array, 128 | int print_size) 129 | { 130 | int i; 131 | w128_t* little = stackalloc w128_t[DSFMT_N + 1]; 132 | W64_T* plittle = (W64_T*)little; 133 | var dummy = new W64_T[(NUM_RANDS / 2 + 1) * 2]; 134 | fixed (W64_T* array = dummy) { 135 | W64_T r = new W64_T(); 136 | W64_T r_st = new W64_T(); 137 | int lsize = DSFMT_N * 2 + 2; 138 | uint32_t[] ar = new uint32_t[] { 1, 2, 3, 4 }; 139 | 140 | var dsfmt = new T(); 141 | 142 | printf("generated randoms {0}\n", range_str); 143 | gv.dsfmt_init_by_array(ar); 144 | fill_array(&plittle[0].d, lsize); 145 | fill_array(&array[0].d, 5000); 146 | gv.dsfmt_init_by_array(ar); 147 | dsfmt.dsfmt_init_by_array(ar); 148 | for (i = 0; i < lsize; i++) { 149 | r.d = genrand(); 150 | r_st.d = st_genrand(dsfmt); 151 | Assert.AreEqual(r.u, r_st.u); 152 | Assert.AreEqual(r.u, plittle[i].u); 153 | if (i < print_size) { 154 | printf("{0} ", d2s(plittle[i].d)); 155 | if (i % 4 == 3) { 156 | printf("\n"); 157 | } 158 | } 159 | } 160 | for (i = 0; i < 5000; i++) { 161 | r.d = genrand(); 162 | Assert.AreEqual(r.u, array[i].u); 163 | if (i + lsize < print_size) { 164 | printf("{0} ", d2s(array[i].d)); 165 | if ((i + lsize) % 4 == 3) { 166 | printf("\n"); 167 | } 168 | } 169 | } 170 | 171 | dsfmt.dsfmt_init_by_array(ar); 172 | st_fill_array(dsfmt, &plittle[0].d, lsize); 173 | st_fill_array(dsfmt, &array[0].d, 5000); 174 | dsfmt.dsfmt_init_by_array(ar); 175 | for (i = 0; i < lsize; i++) { 176 | r_st.d = st_genrand(dsfmt); 177 | Assert.AreEqual(r_st.u, plittle[i].u); 178 | } 179 | for (i = 0; i < 5000; i++) { 180 | r_st.d = st_genrand(dsfmt); 181 | Assert.AreEqual(r_st.u, array[i].u); 182 | } 183 | } 184 | } 185 | 186 | double s_genrand_close_open() { return gv.dsfmt_genrand_close_open(); } 187 | double s_genrand_open_close() { return gv.dsfmt_genrand_open_close(); } 188 | double s_genrand_open_open() { return gv.dsfmt_genrand_open_open(); } 189 | double s_genrand_close1_open2() { return gv.dsfmt_genrand_close1_open2(); } 190 | double sst_genrand_close_open(T dsfmt) { return dsfmt.dsfmt_genrand_close_open(); } 191 | double sst_genrand_open_close(T dsfmt) { return dsfmt.dsfmt_genrand_open_close(); } 192 | double sst_genrand_open_open(T dsfmt) { return dsfmt.dsfmt_genrand_open_open(); } 193 | double sst_genrand_close1_open2(T dsfmt) { return dsfmt.dsfmt_genrand_close1_open2(); } 194 | unsafe void s_fill_array_close_open(double[] array, int size) { gv.dsfmt_fill_array_close_open(array, size); } 195 | unsafe void s_fill_array_open_close(double[] array, int size) { gv.dsfmt_fill_array_open_close(array, size); } 196 | unsafe void s_fill_array_open_open(double[] array, int size) { gv.dsfmt_fill_array_open_open(array, size); } 197 | unsafe void s_fill_array_close1_open2(double[] array, int size) { gv.dsfmt_fill_array_close1_open2(array, size); } 198 | unsafe void sst_fill_array_close_open(T dsfmt, double[] array, int size) { dsfmt.dsfmt_fill_array_close_open(array, size); } 199 | unsafe void sst_fill_array_open_close(T dsfmt, double[] array, int size) { dsfmt.dsfmt_fill_array_open_close(array, size); } 200 | unsafe void sst_fill_array_open_open(T dsfmt, double[] array, int size) { dsfmt.dsfmt_fill_array_open_open(array, size); } 201 | unsafe void sst_fill_array_close1_open2(T dsfmt, double[] array, int size) { dsfmt.dsfmt_fill_array_close1_open2(array, size); } 202 | 203 | static unsafe fill_array_t conv(Action f) 204 | { 205 | return (arr, sz) => { 206 | var buf = new double[sz]; 207 | f(buf, sz); 208 | for (var i = 0; i < sz; ++i) { 209 | arr[i] = buf[i]; 210 | } 211 | }; 212 | } 213 | 214 | static unsafe st_fill_array_t conv(Action f) 215 | { 216 | return (dsfmt, arr, sz) => { 217 | var buf = new double[sz]; 218 | f(dsfmt, buf, sz); 219 | for (var i = 0; i < sz; ++i) { 220 | arr[i] = buf[i]; 221 | } 222 | }; 223 | } 224 | 225 | int main() 226 | { 227 | printf("{0}\n", gv.dsfmt_get_idstring()); 228 | printf("init_gen_rand(0) "); 229 | check("[1, 2)", s_genrand_close1_open2, conv(s_fill_array_close1_open2), sst_genrand_close1_open2, conv(sst_fill_array_close1_open2), 0, 1000); 230 | for (uint i = 0; i < 20; i++) { 231 | printf("init_gen_rand({0}) ", i); 232 | switch (i % 4) { 233 | case 0: 234 | check("[0, 1)", s_genrand_close_open, conv(s_fill_array_close_open), sst_genrand_close_open, conv(sst_fill_array_close_open), i, 12); 235 | break; 236 | case 1: 237 | check("(0, 1]", s_genrand_open_close, conv(s_fill_array_open_close), sst_genrand_open_close, conv(sst_fill_array_open_close), i, 12); 238 | break; 239 | case 2: 240 | check("(0, 1)", s_genrand_open_open, conv(s_fill_array_open_open), sst_genrand_open_open, conv(sst_fill_array_open_open), i, 12); 241 | break; 242 | case 3: 243 | default: 244 | check("[1, 2)", s_genrand_close1_open2, 245 | conv(s_fill_array_close1_open2), 246 | sst_genrand_close1_open2, 247 | conv(sst_fill_array_close1_open2), i, 12); 248 | break; 249 | } 250 | } 251 | printf("init_by_array {1, 2, 3, 4} "); 252 | check_ar("[1, 2)", s_genrand_close1_open2, 253 | conv(s_fill_array_close1_open2), 254 | sst_genrand_close1_open2, 255 | conv(sst_fill_array_close1_open2), 256 | 1000); 257 | return 0; 258 | } 259 | 260 | public void Test() 261 | { 262 | main(); 263 | var mexp = gv.MEXP; 264 | var expected = File.ReadAllText(Path.Combine("dSFMT", $"dSFMT.{mexp}.out.txt")); 265 | expected = expected.Replace("\r\n", "\n"); 266 | var actual = this.GetOutput(); 267 | AssertResults(expected, actual, 1e-14); 268 | } 269 | } 270 | } 271 | --------------------------------------------------------------------------------