├── 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 |
--------------------------------------------------------------------------------