diff --git a/src/Examples/RandomNumberGeneration.cs b/src/Examples/RandomNumberGeneration.cs
index fe5885ae..25a7bb51 100644
--- a/src/Examples/RandomNumberGeneration.cs
+++ b/src/Examples/RandomNumberGeneration.cs
@@ -89,7 +89,7 @@ namespace Examples
// 1. Multiplicative congruential generator using a modulus of 2^31-1 and a multiplier of 1132489760
var mcg31M1 = new Mcg31m1(1);
Console.WriteLine(@"1. Generate 10 random double values using Multiplicative congruential generator with a modulus of 2^31-1 and a multiplier of 1132489760");
- var randomValues = mcg31M1.NextDouble(10);
+ var randomValues = mcg31M1.NextDoubles(10);
for (var i = 0; i < randomValues.Length; i++)
{
Console.Write(randomValues[i].ToString("N") + @" ");
@@ -145,11 +145,11 @@ namespace Examples
Console.WriteLine();
// 6. A random number generator based on the "System.Security.Cryptography.RandomNumberGenerator" class in the .NET library
- var systemCryptoRandomNumberGenerator = new SystemCryptoRandomNumberGenerator();
+ var systemCrypto = new CryptoRandomSource();
Console.WriteLine(@"6. Generate 10 random decimal values using RNG based on the 'System.Security.Cryptography.RandomNumberGenerator'");
for (var i = 0; i < 10; i++)
{
- Console.Write(systemCryptoRandomNumberGenerator.NextDecimal().ToString("N") + @" ");
+ Console.Write(systemCrypto.NextDecimal().ToString("N") + @" ");
}
Console.WriteLine();
diff --git a/src/FSharp/Random.fs b/src/FSharp/Random.fs
index ebd64895..3a05bad4 100644
--- a/src/FSharp/Random.fs
+++ b/src/FSharp/Random.fs
@@ -43,8 +43,8 @@ module Random =
#if PORTABLE
#else
/// Creates a default .Net cryptographic system pRNG
- let crypto () = new SystemCryptoRandomNumberGenerator() :> System.Random
- let cryptoWith (threadSafe:bool) = new SystemCryptoRandomNumberGenerator(threadSafe) :> System.Random
+ let crypto () = new CryptoRandomSource() :> System.Random
+ let cryptoWith (threadSafe:bool) = new CryptoRandomSource(threadSafe) :> System.Random
#endif
/// Creates a Mersenne Twister 19937 pRNG with a custom seed based on uinque GUIDs
diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj
index 6b6fad24..c77fb776 100644
--- a/src/Numerics/Numerics.csproj
+++ b/src/Numerics/Numerics.csproj
@@ -395,14 +395,14 @@
True
Resources.resx
-
+
-
-
+
+
diff --git a/src/Numerics/Random/SystemCrypto.cs b/src/Numerics/Random/CryptoRandomSource.cs
similarity index 76%
rename from src/Numerics/Random/SystemCrypto.cs
rename to src/Numerics/Random/CryptoRandomSource.cs
index 4f29462d..b1de66b9 100644
--- a/src/Numerics/Random/SystemCrypto.cs
+++ b/src/Numerics/Random/CryptoRandomSource.cs
@@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
-// Copyright (c) 2009-2012 Math.NET
+// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@@ -38,19 +38,19 @@ namespace MathNet.Numerics.Random
///
/// A random number generator based on the class in the .NET library.
///
- public class SystemCryptoRandomNumberGenerator : AbstractRandomNumberGenerator, IDisposable
+ public class CryptoRandomSource : RandomSource, IDisposable
{
- private const double Reciprocal = 1.0 / uint.MaxValue;
- private readonly RandomNumberGenerator _random;
+ const double Reciprocal = 1.0/uint.MaxValue;
+ readonly RandomNumberGenerator _crypto;
///
/// Construct a new random number generator with a random seed.
///
/// Uses and uses the value of
/// to set whether the instance is thread safe.
- public SystemCryptoRandomNumberGenerator(): this(new RNGCryptoServiceProvider(), Control.ThreadSafeRandomNumberGenerators)
+ public CryptoRandomSource()
{
- _random = new RNGCryptoServiceProvider();
+ _crypto = new RNGCryptoServiceProvider();
}
///
@@ -58,8 +58,9 @@ namespace MathNet.Numerics.Random
///
/// The to use.
/// Uses the value of to set whether the instance is thread safe.
- public SystemCryptoRandomNumberGenerator(RandomNumberGenerator rng) : this(rng, Control.ThreadSafeRandomNumberGenerators)
+ public CryptoRandomSource(RandomNumberGenerator rng)
{
+ _crypto = rng;
}
///
@@ -67,8 +68,9 @@ namespace MathNet.Numerics.Random
///
/// Uses
/// if set to true , the class is thread safe.
- public SystemCryptoRandomNumberGenerator(bool threadSafe): this(new RNGCryptoServiceProvider(), threadSafe)
+ public CryptoRandomSource(bool threadSafe) : base(threadSafe)
{
+ _crypto = new RNGCryptoServiceProvider();
}
///
@@ -76,13 +78,9 @@ namespace MathNet.Numerics.Random
///
/// The to use.
/// if set to true , the class is thread safe.
- public SystemCryptoRandomNumberGenerator(RandomNumberGenerator rng, bool threadSafe) : base(threadSafe)
+ public CryptoRandomSource(RandomNumberGenerator rng, bool threadSafe) : base(threadSafe)
{
- if (rng == null)
- {
- throw new ArgumentNullException("rng");
- }
- _random = rng;
+ _crypto = rng;
}
@@ -95,14 +93,14 @@ namespace MathNet.Numerics.Random
protected override double DoSample()
{
var bytes = new byte[4];
- _random.GetBytes(bytes);
- return BitConverter.ToUInt32(bytes, 0) * Reciprocal;
+ _crypto.GetBytes(bytes);
+ return BitConverter.ToUInt32(bytes, 0)*Reciprocal;
}
public void Dispose()
{
#if !NET35
- _random.Dispose();
+ _crypto.Dispose();
#endif
}
}
diff --git a/src/Numerics/Random/Mcg31m1.cs b/src/Numerics/Random/Mcg31m1.cs
index 93fd6ef6..a37b9b5b 100644
--- a/src/Numerics/Random/Mcg31m1.cs
+++ b/src/Numerics/Random/Mcg31m1.cs
@@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
-// Copyright (c) 2009-2010 Math.NET
+// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@@ -28,36 +28,33 @@
// OTHER DEALINGS IN THE SOFTWARE.
//
-using System;
-
namespace MathNet.Numerics.Random
{
///
/// Multiplicative congruential generator using a modulus of 2^31-1 and a multiplier of 1132489760.
///
- public class Mcg31m1 : AbstractRandomNumberGenerator
+ public class Mcg31m1 : RandomSource
{
- private const ulong Modulus = 2147483647;
- private const ulong Multiplier = 1132489760;
- private const double Reciprocal = 1.0 / Modulus;
- private ulong _xn;
+ const ulong Modulus = 2147483647;
+ const ulong Multiplier = 1132489760;
+ const double Reciprocal = 1.0/Modulus;
+ ulong _xn;
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
- public Mcg31m1() : this((int) DateTime.Now.Ticks)
+ public Mcg31m1() : this(RandomSeed.Guid())
{
}
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
/// if set to true , the class is thread safe.
- public Mcg31m1(bool threadSafe) : this((int)DateTime.Now.Ticks, threadSafe)
+ public Mcg31m1(bool threadSafe) : this(RandomSeed.Guid(), threadSafe)
{
-
}
///
@@ -67,8 +64,13 @@ namespace MathNet.Numerics.Random
/// If the seed value is zero, it is set to one. Uses the
/// value of to
/// set whether the instance is thread safe.
- public Mcg31m1(int seed) : this(seed, Control.ThreadSafeRandomNumberGenerators)
+ public Mcg31m1(int seed)
{
+ if (seed == 0)
+ {
+ seed = 1;
+ }
+ _xn = (uint)seed%Modulus;
}
///
@@ -82,7 +84,7 @@ namespace MathNet.Numerics.Random
{
seed = 1;
}
- _xn = (uint) seed%Modulus;
+ _xn = (uint)seed%Modulus;
}
///
@@ -98,4 +100,4 @@ namespace MathNet.Numerics.Random
return ret;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Numerics/Random/Mcg59.cs b/src/Numerics/Random/Mcg59.cs
index 650c57dd..099c0c43 100644
--- a/src/Numerics/Random/Mcg59.cs
+++ b/src/Numerics/Random/Mcg59.cs
@@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
-// Copyright (c) 2009-2010 Math.NET
+// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@@ -28,36 +28,34 @@
// OTHER DEALINGS IN THE SOFTWARE.
//
-using System;
-
namespace MathNet.Numerics.Random
{
///
/// Multiplicative congruential generator using a modulus of 2^59 and a multiplier of 13^13.
///
- public class Mcg59 : AbstractRandomNumberGenerator
+ public class Mcg59 : RandomSource
{
- private const double Reciprocal = 1.0 / Modulus;
- private const ulong Modulus = 576460752303423488;
- private const ulong Multiplier = 302875106592253;
- private ulong _xn;
+ const double Reciprocal = 1.0/Modulus;
+ const ulong Modulus = 576460752303423488;
+ const ulong Multiplier = 302875106592253;
+ ulong _xn;
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
- public Mcg59() : this((int) DateTime.Now.Ticks)
+ public Mcg59() : this(RandomSeed.Guid())
{
}
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
/// if set to true , the class is thread safe.
- public Mcg59(bool threadSafe) : this((int)DateTime.Now.Ticks, threadSafe)
+ public Mcg59(bool threadSafe) : this(RandomSeed.Guid(), threadSafe)
{
-
+
}
///
@@ -67,8 +65,13 @@ namespace MathNet.Numerics.Random
/// If the seed value is zero, it is set to one. Uses the
/// value of to
/// set whether the instance is thread safe.
- public Mcg59(int seed) : this(seed, Control.ThreadSafeRandomNumberGenerators)
+ public Mcg59(int seed)
{
+ if (seed == 0)
+ {
+ seed = 1;
+ }
+ _xn = (uint)seed%Modulus;
}
///
@@ -79,11 +82,11 @@ namespace MathNet.Numerics.Random
/// if set to true , the class is thread safe.
public Mcg59(int seed, bool threadSafe) : base(threadSafe)
{
- if( seed == 0)
+ if (seed == 0)
{
seed = 1;
}
- _xn = (uint) seed % Modulus;
+ _xn = (uint)seed%Modulus;
}
///
@@ -94,9 +97,9 @@ namespace MathNet.Numerics.Random
///
protected override double DoSample()
{
- double ret = _xn * Reciprocal;
- _xn = (_xn * Multiplier) % Modulus;
+ double ret = _xn*Reciprocal;
+ _xn = (_xn*Multiplier)%Modulus;
return ret;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Numerics/Random/MersenneTwister.cs b/src/Numerics/Random/MersenneTwister.cs
index c23a8c11..1c8efc2c 100644
--- a/src/Numerics/Random/MersenneTwister.cs
+++ b/src/Numerics/Random/MersenneTwister.cs
@@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
-// Copyright (c) 2009-2010 Math.NET
+// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@@ -66,7 +66,6 @@
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
*/
-using System;
using System.Threading;
namespace MathNet.Numerics.Random
@@ -74,70 +73,70 @@ namespace MathNet.Numerics.Random
///
/// Random number generator using Mersenne Twister 19937 algorithm.
///
- public class MersenneTwister : AbstractRandomNumberGenerator, IDisposable
+ public class MersenneTwister : RandomSource
{
///
/// Mersenne twister constant.
///
- private const uint LowerMask = 0x7fffffff;
+ const uint LowerMask = 0x7fffffff;
///
/// Mersenne twister constant.
///
- private const int M = 397;
+ const int M = 397;
///
/// Mersenne twister constant.
///
- private const uint MatrixA = 0x9908b0df;
+ const uint MatrixA = 0x9908b0df;
///
/// Mersenne twister constant.
///
- private const int N = 624;
+ const int N = 624;
///
/// Mersenne twister constant.
///
- private const double Reciprocal = 1.0/4294967296.0;
+ const double Reciprocal = 1.0/4294967296.0;
///
/// Mersenne twister constant.
///
- private const uint UpperMask = 0x80000000;
+ const uint UpperMask = 0x80000000;
///
/// Mersenne twister constant.
///
- private static readonly uint[] Mag01 = {0x0U, MatrixA};
+ static readonly uint[] Mag01 = { 0x0U, MatrixA };
///
/// Mersenne twister constant.
///
- private readonly uint[] _mt = new uint[624];
+ readonly uint[] _mt = new uint[624];
///
/// Mersenne twister constant.
///
- private int _mti = N + 1;
+ int _mti = N + 1;
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
/// If the seed value is zero, it is set to one. Uses the
/// value of to
/// set whether the instance is thread safe.
- public MersenneTwister() : this((int) DateTime.Now.Ticks)
+ public MersenneTwister() : this(RandomSeed.Guid())
{
}
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
/// if set to true , the class is thread safe.
- public MersenneTwister(bool threadSafe) : this((int) DateTime.Now.Ticks, threadSafe)
+ public MersenneTwister(bool threadSafe) : this(RandomSeed.Guid(), threadSafe)
{
}
@@ -147,8 +146,9 @@ namespace MathNet.Numerics.Random
/// The seed value.
/// Uses the value of to
/// set whether the instance is thread safe.
- public MersenneTwister(int seed) : this(seed, Control.ThreadSafeRandomNumberGenerators)
+ public MersenneTwister(int seed)
{
+ init_genrand((uint)seed);
}
///
@@ -190,7 +190,7 @@ namespace MathNet.Numerics.Random
get { return DefaultInstance.Value; }
}
#endif
-
+
/*///
/// Initializes a new instance of the class.
///
@@ -211,12 +211,12 @@ namespace MathNet.Numerics.Random
*/
/* initializes _mt[_n] with a seed */
- private void init_genrand(uint s)
+ void init_genrand(uint s)
{
_mt[0] = s & 0xffffffff;
for (_mti = 1; _mti < N; _mti++)
{
- _mt[_mti] = (1812433253*(_mt[_mti - 1] ^ (_mt[_mti - 1] >> 30)) + (uint) _mti);
+ _mt[_mti] = (1812433253*(_mt[_mti - 1] ^ (_mt[_mti - 1] >> 30)) + (uint)_mti);
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
/* In the previous versions, MSBs of the seed affect */
/* only MSBs of the array _mt[]. */
@@ -231,7 +231,7 @@ namespace MathNet.Numerics.Random
/* init_key is the array for initializing keys */
/* slight change for C++, 2004/2/26 */
- /* private void init_by_array(uint[] init_key)
+ /* private void init_by_array(uint[] init_key)
{
uint key_length = (uint) init_key.Length;
init_genrand(19650218);
@@ -268,7 +268,7 @@ namespace MathNet.Numerics.Random
/* generates a random number on [0,0xffffffff]-interval */
- private uint genrand_int32()
+ uint genrand_int32()
{
uint y;
@@ -317,10 +317,10 @@ namespace MathNet.Numerics.Random
///
protected override double DoSample()
{
- return genrand_int32() * Reciprocal;
+ return genrand_int32()*Reciprocal;
}
- /* ///
+ /* ///
/// Generates a random number on [0,1) with 53-bit resolution.
///
/// A random number on [0,1) with 53-bit resolution.
@@ -329,17 +329,5 @@ namespace MathNet.Numerics.Random
ulong a = genrand_int32() >> 5, b = genrand_int32() >> 6;
return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0);
}*/
-
- #region IDisposable Members
-
- ///
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- ///
- public void Dispose()
- {
- //do nothing in the managed version.
- }
-
- #endregion
}
-}
\ No newline at end of file
+}
diff --git a/src/Numerics/Random/Mrg32k3a.cs b/src/Numerics/Random/Mrg32k3a.cs
index b54812f2..a8cd9a44 100644
--- a/src/Numerics/Random/Mrg32k3a.cs
+++ b/src/Numerics/Random/Mrg32k3a.cs
@@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
-// Copyright (c) 2009-2010 Math.NET
+// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@@ -36,40 +36,40 @@ namespace MathNet.Numerics.Random
/// A 32-bit combined multiple recursive generator with 2 components of order 3.
///
///Based off of P. L'Ecuyer, "Combined Multiple Recursive Random Number Generators," Operations Research, 44, 5 (1996), 816--822.
- public class Mrg32k3a : AbstractRandomNumberGenerator
+ public class Mrg32k3a : RandomSource
{
- private const double A12 = 1403580;
- private const double A13 = 810728;
- private const double A21 = 527612;
- private const double A23 = 1370589;
- private const double Modulus1 = 4294967087;
- private const double Modulus2 = 4294944443;
+ const double A12 = 1403580;
+ const double A13 = 810728;
+ const double A21 = 527612;
+ const double A23 = 1370589;
+ const double Modulus1 = 4294967087;
+ const double Modulus2 = 4294944443;
- private const double Reciprocal = 1.0 / Modulus1;
- private double _xn1 = 1;
- private double _xn2 = 1;
- private double _xn3;
- private double _yn1 = 1;
- private double _yn2 = 1;
- private double _yn3 = 1;
+ const double Reciprocal = 1.0/Modulus1;
+ double _xn1 = 1;
+ double _xn2 = 1;
+ double _xn3;
+ double _yn1 = 1;
+ double _yn2 = 1;
+ double _yn3 = 1;
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
/// If the seed value is zero, it is set to one. Uses the
/// value of to
/// set whether the instance is thread safe.
- public Mrg32k3a() : this((int)DateTime.Now.Ticks)
+ public Mrg32k3a() : this(RandomSeed.Guid())
{
}
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
/// if set to true , the class is thread safe.
- public Mrg32k3a(bool threadSafe) : this((int)DateTime.Now.Ticks, threadSafe)
+ public Mrg32k3a(bool threadSafe) : this(RandomSeed.Guid(), threadSafe)
{
}
@@ -80,8 +80,13 @@ namespace MathNet.Numerics.Random
/// If the seed value is zero, it is set to one. Uses the
/// value of to
/// set whether the instance is thread safe.
- public Mrg32k3a(int seed) : this(seed, Control.ThreadSafeRandomNumberGenerators)
+ public Mrg32k3a(int seed)
{
+ if (seed == 0)
+ {
+ seed = 1;
+ }
+ _xn3 = (uint)seed;
}
///
@@ -108,7 +113,7 @@ namespace MathNet.Numerics.Random
protected override double DoSample()
{
double xn = A12*_xn2 - A13*_xn3;
- double k = (long) (xn/Modulus1);
+ double k = (long)(xn/Modulus1);
xn -= k*Modulus1;
if (xn < 0)
{
@@ -116,7 +121,7 @@ namespace MathNet.Numerics.Random
}
double yn = A21*_yn1 - A23*_yn3;
- k = (long) (yn/Modulus2);
+ k = (long)(yn/Modulus2);
yn -= k*Modulus2;
if (yn < 0)
{
@@ -136,4 +141,4 @@ namespace MathNet.Numerics.Random
return (xn - yn)*Reciprocal;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Numerics/Random/Palf.cs b/src/Numerics/Random/Palf.cs
index 01ff002a..efa4e036 100644
--- a/src/Numerics/Random/Palf.cs
+++ b/src/Numerics/Random/Palf.cs
@@ -43,7 +43,7 @@ namespace MathNet.Numerics.Random
/// It uses the modulus 232 and by default the "lags" 418 and 1279. Some popular pairs are presented on
/// Wikipedia - Lagged Fibonacci generator.
///
- public class Palf : AbstractRandomNumberGenerator
+ public class Palf : RandomSource
{
///
/// Default value for the ShortLag
@@ -62,23 +62,21 @@ namespace MathNet.Numerics.Random
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
/// If the seed value is zero, it is set to one. Uses the
/// value of to
/// set whether the instance is thread safe.
- public Palf()
- : this((int) DateTime.Now.Ticks)
+ public Palf() : this(RandomSeed.Guid(), Control.ThreadSafeRandomNumberGenerators, DefaultShortLag, DefaultLongLag)
{
}
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
/// if set to true , the class is thread safe.
- public Palf(bool threadSafe)
- : this((int) DateTime.Now.Ticks, threadSafe, DefaultShortLag, DefaultLongLag)
+ public Palf(bool threadSafe) : this(RandomSeed.Guid(), threadSafe, DefaultShortLag, DefaultLongLag)
{
}
@@ -89,8 +87,7 @@ namespace MathNet.Numerics.Random
/// If the seed value is zero, it is set to one. Uses the
/// value of to
/// set whether the instance is thread safe.
- public Palf(int seed)
- : this(seed, Control.ThreadSafeRandomNumberGenerators, DefaultShortLag, DefaultLongLag)
+ public Palf(int seed) : this(seed, Control.ThreadSafeRandomNumberGenerators, DefaultShortLag, DefaultLongLag)
{
}
@@ -101,8 +98,7 @@ namespace MathNet.Numerics.Random
/// if set to true, the class is thread safe.
/// The ShortLag value
/// TheLongLag value
- public Palf(int seed, bool threadSafe, int shortLag, int longLag)
- : base(threadSafe)
+ public Palf(int seed, bool threadSafe, int shortLag, int longLag) : base(threadSafe)
{
if (shortLag < 1)
{
@@ -135,7 +131,7 @@ namespace MathNet.Numerics.Random
var gen = new MersenneTwister(seed, threadSafe);
for (var j = 0; j < LongLag; ++j)
{
- _x[j] = (uint) (gen.NextDouble()*uint.MaxValue);
+ _x[j] = (uint)(gen.NextDouble()*uint.MaxValue);
}
_i = LongLag;
@@ -171,21 +167,21 @@ namespace MathNet.Numerics.Random
void Fill()
{
CommonParallel.For(0, Control.NumberOfParallelWorkerThreads, (u, v) =>
+ {
+ for (int index = u; index < v; index++)
{
- for (int index = u; index < v; index++)
+ // Two loops to avoid costly modulo operations
+ for (var j = index; j < ShortLag; j = j + Control.NumberOfParallelWorkerThreads)
+ {
+ _x[j] += _x[j + (LongLag - ShortLag)];
+ }
+
+ for (var j = ShortLag + index; j < LongLag; j = j + Control.NumberOfParallelWorkerThreads)
{
- // Two loops to avoid costly modulo operations
- for (var j = index; j < ShortLag; j = j + Control.NumberOfParallelWorkerThreads)
- {
- _x[j] += _x[j + (LongLag - ShortLag)];
- }
-
- for (var j = ShortLag + index; j < LongLag; j = j + Control.NumberOfParallelWorkerThreads)
- {
- _x[j] += _x[j - ShortLag - index];
- }
+ _x[j] += _x[j - ShortLag - index];
}
- });
+ }
+ });
_i = 0;
}
@@ -203,7 +199,7 @@ namespace MathNet.Numerics.Random
}
var x = _x[_i++];
- return (int) (x >> 1)*IntToDoubleMultiplier;
+ return (int)(x >> 1)*IntToDoubleMultiplier;
}
}
}
diff --git a/src/Numerics/Random/SystemRandomExtensions.cs b/src/Numerics/Random/RandomExtensions.cs
similarity index 99%
rename from src/Numerics/Random/SystemRandomExtensions.cs
rename to src/Numerics/Random/RandomExtensions.cs
index 4b837d5d..e7af4a92 100644
--- a/src/Numerics/Random/SystemRandomExtensions.cs
+++ b/src/Numerics/Random/RandomExtensions.cs
@@ -36,7 +36,7 @@ namespace MathNet.Numerics.Random
/// This class implements extension methods for the System.Random class. The extension methods generate
/// pseudo-random distributed numbers for types other than double and int32.
///
- public static class SystemRandomExtensions
+ public static class RandomExtensions
{
///
/// Returns a nonnegative random number less than .
diff --git a/src/Numerics/Random/AbstractRandomNumberGenerator.cs b/src/Numerics/Random/RandomSource.cs
similarity index 62%
rename from src/Numerics/Random/AbstractRandomNumberGenerator.cs
rename to src/Numerics/Random/RandomSource.cs
index f80dfd9a..2534ada7 100644
--- a/src/Numerics/Random/AbstractRandomNumberGenerator.cs
+++ b/src/Numerics/Random/RandomSource.cs
@@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
-// Copyright (c) 2009-2010 Math.NET
+// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@@ -28,52 +28,63 @@
// OTHER DEALINGS IN THE SOFTWARE.
//
+using System;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.Random
{
- using System;
-
///
- /// Abstract class for random number generators. This class introduces a layer between
+ /// Base class for random number generators. This class introduces a layer between
/// and the Math.Net Numerics random number generators to provide thread safety.
+ /// When used directly it use the System.Random as random number source.
///
- public abstract class AbstractRandomNumberGenerator : Random
+ public class RandomSource : System.Random
{
- ///
- /// A delegate type that represents a method that generates random numbers.
- ///
- /// Randomly distributed numbers.
- private delegate double SampleMethod();
+ readonly bool _threadSafe;
+ readonly object _lock = new object();
///
- /// The method that actually generates samples.
+ /// Initializes a new instance of the class using
+ /// the value of to set whether
+ /// the instance is thread safe or not.
///
- private readonly SampleMethod _sampleMethod;
+ public RandomSource() : base(RandomSeed.Guid())
+ {
+ _threadSafe = Control.ThreadSafeRandomNumberGenerators;
+ }
///
- /// The object that will be locked for thread safety.
+ /// Initializes a new instance of the class.
///
- private readonly object _lock = new object();
+ /// if set to true , the class is thread safe.
+ /// Thread safe instances are two and half times slower than non-thread
+ /// safe classes.
+ public RandomSource(bool threadSafe) : base(RandomSeed.Guid())
+ {
+ _threadSafe = threadSafe;
+ }
///
- /// Initializes a new instance of the class using
+ /// Initializes a new instance of the class using
/// the value of to set whether
/// the instance is thread safe or not.
///
- protected AbstractRandomNumberGenerator() : this(Control.ThreadSafeRandomNumberGenerators)
+ /// The seed value.
+ public RandomSource(int systemRandomSeed) : base(systemRandomSeed)
{
+ _threadSafe = Control.ThreadSafeRandomNumberGenerators;
}
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
+ /// The seed value.
/// if set to true , the class is thread safe.
/// Thread safe instances are two and half times slower than non-thread
/// safe classes.
- protected AbstractRandomNumberGenerator(bool threadSafe)
+ public RandomSource(int systemRandomSeed, bool threadSafe) : base(systemRandomSeed)
{
- _sampleMethod = threadSafe ? (SampleMethod)ThreadSafeSample : DoSample;
+ _threadSafe = threadSafe;
}
///
@@ -84,7 +95,7 @@ namespace MathNet.Numerics.Random
/// An array of uniformly distributed random doubles in the interval [0.0,1.0].
///
/// if n is not greater than 0.
- public double[] NextDouble(int n)
+ public double[] NextDoubles(int n)
{
if (n < 1)
{
@@ -92,11 +103,23 @@ namespace MathNet.Numerics.Random
}
var ret = new double[n];
- for (var i = 0; i < ret.Length; i++)
+ if (_threadSafe)
{
- ret[i] = Sample();
+ lock (_lock)
+ {
+ for (var i = 0; i < ret.Length; i++)
+ {
+ ret[i] = DoSample();
+ }
+ }
+ }
+ else
+ {
+ for (var i = 0; i < ret.Length; i++)
+ {
+ ret[i] = DoSample();
+ }
}
-
return ret;
}
@@ -106,9 +129,17 @@ namespace MathNet.Numerics.Random
///
/// A 32-bit signed integer greater than or equal to zero and less than .
///
- public override int Next()
+ public override sealed int Next()
{
- return (int)(Sample() * int.MaxValue);
+ if (_threadSafe)
+ {
+ lock (_lock)
+ {
+ return (int)(DoSample()*int.MaxValue);
+ }
+ }
+
+ return (int)(DoSample()*int.MaxValue);
}
///
@@ -117,14 +148,22 @@ namespace MathNet.Numerics.Random
/// The exclusive upper bound of the random number returned.
/// A 32-bit signed integer less than .
/// is negative.
- public override int Next(int maxValue)
+ public override sealed int Next(int maxValue)
{
if (maxValue <= 0)
{
throw new ArgumentOutOfRangeException(Resources.ArgumentMustBePositive);
}
- return (int)(Sample() * maxValue);
+ if (_threadSafe)
+ {
+ lock (_lock)
+ {
+ return (int)(DoSample()*maxValue);
+ }
+ }
+
+ return (int)(DoSample()*maxValue);
}
///
@@ -136,14 +175,22 @@ namespace MathNet.Numerics.Random
/// A 32-bit signed integer greater than or equal to and less than ; that is, the range of return values includes but not . If equals , is returned.
///
/// is greater than .
- public override int Next(int minValue, int maxValue)
+ public override sealed int Next(int minValue, int maxValue)
{
if (minValue > maxValue)
{
throw new ArgumentOutOfRangeException(Resources.ArgumentMinValueGreaterThanMaxValue);
}
- return (int)(Sample() * (maxValue - minValue)) + minValue;
+ if (_threadSafe)
+ {
+ lock (_lock)
+ {
+ return (int)(DoSample()*(maxValue - minValue)) + minValue;
+ }
+ }
+
+ return (int)(DoSample()*(maxValue - minValue)) + minValue;
}
///
@@ -158,9 +205,21 @@ namespace MathNet.Numerics.Random
throw new ArgumentNullException("buffer");
}
+ if (_threadSafe)
+ {
+ lock (_lock)
+ {
+ for (var i = 0; i < buffer.Length; i++)
+ {
+ buffer[i] = (byte)(((int)(DoSample()*int.MaxValue))%256);
+ }
+ }
+ return;
+ }
+
for (var i = 0; i < buffer.Length; i++)
{
- buffer[i] = (byte)(Next() % 256);
+ buffer[i] = (byte)(((int)(DoSample()*int.MaxValue))%256);
}
}
@@ -170,14 +229,22 @@ namespace MathNet.Numerics.Random
/// A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
protected override double Sample()
{
- return _sampleMethod();
+ if (_threadSafe)
+ {
+ lock (_lock)
+ {
+ return DoSample();
+ }
+ }
+
+ return DoSample();
}
///
/// Thread safe version of which returns a random number between 0.0 and 1.0.
///
/// A double-precision floating point number greater than or equal to 0.0, and less than 1.0
- private double ThreadSafeSample()
+ double ThreadSafeSample()
{
lock (_lock)
{
@@ -191,6 +258,9 @@ namespace MathNet.Numerics.Random
///
/// A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
///
- protected abstract double DoSample();
+ protected virtual double DoSample()
+ {
+ return base.Sample();
+ }
}
-}
\ No newline at end of file
+}
diff --git a/src/Numerics/Random/WH1982.cs b/src/Numerics/Random/WH1982.cs
index d4e410fd..5b64e386 100644
--- a/src/Numerics/Random/WH1982.cs
+++ b/src/Numerics/Random/WH1982.cs
@@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
-// Copyright (c) 2009-2010 Math.NET
+// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@@ -28,8 +28,6 @@
// OTHER DEALINGS IN THE SOFTWARE.
//
-using System;
-
namespace MathNet.Numerics.Random
{
///
@@ -38,33 +36,32 @@ namespace MathNet.Numerics.Random
/// See: Wichmann, B. A. & Hill, I. D. (1982), "Algorithm AS 183:
/// An efficient and portable pseudo-random number generator". Applied Statistics 31 (1982) 188-190
///
- public class WH1982 : AbstractRandomNumberGenerator
+ public class WH1982 : RandomSource
{
- private const uint Modx = 30269;
- private const double ModxRecip = 1.0/Modx;
- private const uint Mody = 30307;
- private const double ModyRecip = 1.0/Mody;
- private const uint Modz = 30323;
- private const double ModzRecip = 1.0/Modz;
- private uint _xn;
- private uint _yn = 1;
- private uint _zn = 1;
+ const uint Modx = 30269;
+ const double ModxRecip = 1.0/Modx;
+ const uint Mody = 30307;
+ const double ModyRecip = 1.0/Mody;
+ const uint Modz = 30323;
+ const double ModzRecip = 1.0/Modz;
+ uint _xn;
+ uint _yn = 1;
+ uint _zn = 1;
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
- public WH1982() : this((int) DateTime.Now.Ticks)
+ public WH1982() : this(RandomSeed.Guid())
{
}
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
/// if set to true , the class is thread safe.
- public WH1982(bool threadSafe)
- : this((int) DateTime.Now.Ticks, threadSafe)
+ public WH1982(bool threadSafe) : this(RandomSeed.Guid(), threadSafe)
{
}
@@ -75,8 +72,13 @@ namespace MathNet.Numerics.Random
/// If the seed value is zero, it is set to one. Uses the
/// value of to
/// set whether the instance is thread safe.
- public WH1982(int seed) : this(seed, Control.ThreadSafeRandomNumberGenerators)
+ public WH1982(int seed)
{
+ if (seed == 0)
+ {
+ seed = 1;
+ }
+ _xn = (uint)seed%Modx;
}
///
@@ -92,7 +94,7 @@ namespace MathNet.Numerics.Random
{
seed = 1;
}
- _xn = (uint) seed%Modx;
+ _xn = (uint)seed%Modx;
}
///
@@ -108,8 +110,8 @@ namespace MathNet.Numerics.Random
_zn = (170*_zn)%Modz;
double w = _xn*ModxRecip + _yn*ModyRecip + _zn*ModzRecip;
- w -= (int) w;
+ w -= (int)w;
return w;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Numerics/Random/WH2006.cs b/src/Numerics/Random/WH2006.cs
index 94e5f27b..e0bf71db 100644
--- a/src/Numerics/Random/WH2006.cs
+++ b/src/Numerics/Random/WH2006.cs
@@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
-// Copyright (c) 2009-2010 Math.NET
+// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@@ -28,8 +28,6 @@
// OTHER DEALINGS IN THE SOFTWARE.
//
-using System;
-
namespace MathNet.Numerics.Random
{
///
@@ -38,36 +36,35 @@ namespace MathNet.Numerics.Random
/// See: Wichmann, B. A. & Hill, I. D. (2006), "Generating good pseudo-random numbers".
/// Computational Statistics & Data Analysis 51:3 (2006) 1614-1622
///
- public class WH2006 : AbstractRandomNumberGenerator
+ public class WH2006 : RandomSource
{
- private const uint Modw = 2147483123;
- private const double ModwRecip = 1.0/Modw;
- private const uint Modx = 2147483579;
- private const double ModxRecip = 1.0/Modx;
- private const uint Mody = 2147483543;
- private const double ModyRecip = 1.0/Mody;
- private const uint Modz = 2147483423;
- private const double ModzRecip = 1.0/Modz;
- private ulong _wn = 1;
- private ulong _xn;
- private ulong _yn = 1;
- private ulong _zn = 1;
+ const uint Modw = 2147483123;
+ const double ModwRecip = 1.0/Modw;
+ const uint Modx = 2147483579;
+ const double ModxRecip = 1.0/Modx;
+ const uint Mody = 2147483543;
+ const double ModyRecip = 1.0/Mody;
+ const uint Modz = 2147483423;
+ const double ModzRecip = 1.0/Modz;
+ ulong _wn = 1;
+ ulong _xn;
+ ulong _yn = 1;
+ ulong _zn = 1;
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
- public WH2006() : this((int) DateTime.Now.Ticks)
+ public WH2006() : this(RandomSeed.Guid())
{
}
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
/// if set to true , the class is thread safe.
- public WH2006(bool threadSafe)
- : this((int) DateTime.Now.Ticks, threadSafe)
+ public WH2006(bool threadSafe) : this(RandomSeed.Guid(), threadSafe)
{
}
@@ -78,8 +75,13 @@ namespace MathNet.Numerics.Random
/// If the seed value is zero, it is set to one. Uses the
/// value of to
/// set whether the instance is thread safe.
- public WH2006(int seed) : this(seed, Control.ThreadSafeRandomNumberGenerators)
+ public WH2006(int seed)
{
+ if (seed == 0)
+ {
+ seed = 1;
+ }
+ _xn = (uint)seed%Modx;
}
///
@@ -88,14 +90,13 @@ namespace MathNet.Numerics.Random
/// The seed value.
/// The seed is set to 1, if the zero is used as the seed.
/// if set to true , the class is thread safe.
- public WH2006(int seed, bool threadSafe)
- : base(threadSafe)
+ public WH2006(int seed, bool threadSafe) : base(threadSafe)
{
if (seed == 0)
{
seed = 1;
}
- _xn = (uint) seed%Modx;
+ _xn = (uint)seed%Modx;
}
///
@@ -112,8 +113,8 @@ namespace MathNet.Numerics.Random
_wn = 33000*_wn%Modw;
double u = _xn*ModxRecip + _yn*ModyRecip + _zn*ModzRecip + _wn*ModwRecip;
- u -= (int) u;
+ u -= (int)u;
return u;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Numerics/Random/Xorshift.cs b/src/Numerics/Random/Xorshift.cs
index da38207c..65613703 100644
--- a/src/Numerics/Random/Xorshift.cs
+++ b/src/Numerics/Random/Xorshift.cs
@@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
-// Copyright (c) 2009-2010 Math.NET
+// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@@ -28,8 +28,8 @@
// OTHER DEALINGS IN THE SOFTWARE.
//
-using MathNet.Numerics.Properties;
using System;
+using MathNet.Numerics.Properties;
namespace MathNet.Numerics.Random
{
@@ -38,61 +38,61 @@ namespace MathNet.Numerics.Random
/// Xn = a * Xn−3 + c mod 2^32
/// http://www.jstatsoft.org/v08/i14/paper
///
- public class Xorshift : AbstractRandomNumberGenerator
+ public class Xorshift : RandomSource
{
///
/// The default value for X1.
///
- private const uint YSeed = 362436069;
+ const uint YSeed = 362436069;
///
/// The default value for X2.
///
- private const uint ZSeed = 77465321;
+ const uint ZSeed = 77465321;
///
/// The default value for the multiplier.
///
- private const uint ASeed = 916905990;
+ const uint ASeed = 916905990;
///
/// The default value for the carry over.
///
- private const uint CSeed = 13579;
+ const uint CSeed = 13579;
///
/// The multiplier to compute a double-precision floating point number [0, 1)
///
- private const double UlongToDoubleMultiplier = 1.0 / (uint.MaxValue + 1.0);
+ const double UlongToDoubleMultiplier = 1.0/(uint.MaxValue + 1.0);
///
/// Seed or last but three unsigned random number.
///
- private ulong _x;
+ ulong _x;
///
/// Last but two unsigned random number.
///
- private ulong _y;
+ ulong _y;
///
/// Last but one unsigned random number.
///
- private ulong _z;
+ ulong _z;
///
/// The value of the carry over.
///
- private ulong _c;
+ ulong _c;
///
/// The multiplier.
///
- private readonly ulong _a;
+ readonly ulong _a;
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
/// If the seed value is zero, it is set to one. Uses the
/// value of to
@@ -104,13 +104,13 @@ namespace MathNet.Numerics.Random
/// - X1 = 77465321
/// - X2 = 362436069
///
- public Xorshift() : this((int)DateTime.Now.Ticks)
+ public Xorshift() : this(RandomSeed.Guid())
{
}
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
/// The multiply value
/// The initial carry value.
@@ -121,14 +121,13 @@ namespace MathNet.Numerics.Random
/// set whether the instance is thread safe.
/// Note: must be less than .
///
- public Xorshift(long a, long c, long x1, long x2)
- : this((int)DateTime.Now.Ticks, a, c, x1, x2)
+ public Xorshift(long a, long c, long x1, long x2) : this(RandomSeed.Guid(), a, c, x1, x2)
{
}
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
/// if set to true , the class is thread safe.
///
@@ -139,14 +138,13 @@ namespace MathNet.Numerics.Random
/// - X1 = 77465321
/// - X2 = 362436069
///
- public Xorshift(bool threadSafe)
- : this((int)DateTime.Now.Ticks, threadSafe)
+ public Xorshift(bool threadSafe) : this(RandomSeed.Guid(), threadSafe)
{
}
///
/// Initializes a new instance of the class using
- /// the current time as the seed.
+ /// a seed based on time and unique GUIDs.
///
/// if set to true , the class is thread safe.
/// The multiply value
@@ -154,11 +152,10 @@ namespace MathNet.Numerics.Random
/// The initial value if X1.
/// The initial value if X2.
/// must be less than .
- public Xorshift(bool threadSafe, long a, long c, long x1, long x2)
- : this((int)DateTime.Now.Ticks, threadSafe, a, c, x1, x2)
+ public Xorshift(bool threadSafe, long a, long c, long x1, long x2) : this(RandomSeed.Guid(), threadSafe, a, c, x1, x2)
{
}
-
+
///
/// Initializes a new instance of the class.
///
@@ -189,8 +186,7 @@ namespace MathNet.Numerics.Random
/// The initial value if X1.
/// The initial value if X2.
/// must be less than .
- public Xorshift(int seed, long a, long c, long x1, long x2)
- : this(seed, Control.ThreadSafeRandomNumberGenerators, a, c, x1, x2)
+ public Xorshift(int seed, long a, long c, long x1, long x2) : this(seed, Control.ThreadSafeRandomNumberGenerators, a, c, x1, x2)
{
}
@@ -231,8 +227,7 @@ namespace MathNet.Numerics.Random
/// The initial value if X1.
/// The initial value if X2.
/// must be less than .
- public Xorshift(int seed, bool threadSafe, long a, long c, long x1, long x2)
- : base(threadSafe)
+ public Xorshift(int seed, bool threadSafe, long a, long c, long x1, long x2) : base(threadSafe)
{
if (seed == 0)
{
@@ -259,12 +254,12 @@ namespace MathNet.Numerics.Random
///
protected override double DoSample()
{
- var t = (_a * _x) + _c;
+ var t = (_a*_x) + _c;
_x = _y;
_y = _z;
_c = t >> 32;
_z = t & 0xffffffff;
- return _z * UlongToDoubleMultiplier;
+ return _z*UlongToDoubleMultiplier;
}
}
}
diff --git a/src/UnitTests/Random/SystemCryptoTests.cs b/src/UnitTests/Random/SystemCryptoTests.cs
index 89e3a007..c1bd2955 100644
--- a/src/UnitTests/Random/SystemCryptoTests.cs
+++ b/src/UnitTests/Random/SystemCryptoTests.cs
@@ -34,13 +34,13 @@ namespace MathNet.Numerics.UnitTests.Random
/// Tests for a random number generator based on the class in the .NET library
///
[TestFixture, Category("Random")]
- public class SystemCryptoRandomNumberGeneratorTests : RandomTests
+ public class CryptoRandomSourceTests : RandomTests
{
///
/// Initializes a new instance of the SystemCryptoRandomNumberGeneratorTests class.
///
- public SystemCryptoRandomNumberGeneratorTests()
- : base(typeof(SystemCryptoRandomNumberGenerator))
+ public CryptoRandomSourceTests()
+ : base(typeof(CryptoRandomSource))
{
}
}