Browse Source

Random: static Samples routine, de-parallelize palf because parallel version is not consistent

pull/184/head
Christoph Ruegg 13 years ago
parent
commit
46ca6b6348
  1. 20
      src/Numerics/Random/Mcg31m1.cs
  2. 20
      src/Numerics/Random/Mcg59.cs
  3. 56
      src/Numerics/Random/MersenneTwister.cs
  4. 44
      src/Numerics/Random/Mrg32k3a.cs
  5. 129
      src/Numerics/Random/Palf.cs
  6. 22
      src/Numerics/Random/RandomExtensions.cs
  7. 26
      src/Numerics/Random/WH1982.cs
  8. 28
      src/Numerics/Random/WH2006.cs
  9. 29
      src/Numerics/Random/Xorshift.cs
  10. 17
      src/UnitTests/Random/CryptoRandomSourceTests.cs
  11. 20
      src/UnitTests/Random/Mcg31m1Tests.cs
  12. 20
      src/UnitTests/Random/Mcg59Tests.cs
  13. 20
      src/UnitTests/Random/MersenneTwisterTests.cs
  14. 21
      src/UnitTests/Random/Mrg32k3aTests.cs
  15. 23
      src/UnitTests/Random/PalfTests.cs
  16. 23
      src/UnitTests/Random/RandomExtensionTests.cs
  17. 42
      src/UnitTests/Random/RandomTests.cs
  18. 23
      src/UnitTests/Random/WH1982Tests.cs
  19. 23
      src/UnitTests/Random/WH2006Tests.cs
  20. 21
      src/UnitTests/Random/XorshiftTests.cs
  21. 4
      src/UnitTests/UnitTests.csproj

20
src/Numerics/Random/Mcg31m1.cs

@ -99,5 +99,25 @@ namespace MathNet.Numerics.Random
_xn = (_xn*Multiplier)%Modulus;
return ret;
}
/// <summary>
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary>
public static double[] Samples(int length, int seed)
{
if (seed == 0)
{
seed = 1;
}
ulong xn = (uint)seed%Modulus;
var data = new double[length];
for (int i = 0; i < data.Length; i++)
{
data[i] = xn*Reciprocal;
xn = (xn*Multiplier)%Modulus;
}
return data;
}
}
}

20
src/Numerics/Random/Mcg59.cs

@ -101,5 +101,25 @@ namespace MathNet.Numerics.Random
_xn = (_xn*Multiplier)%Modulus;
return ret;
}
/// <summary>
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary>
public static double[] Samples(int length, int seed)
{
if (seed == 0)
{
seed = 1;
}
ulong xn = (uint)seed%Modulus;
var data = new double[length];
for (int i = 0; i < data.Length; i++)
{
data[i] = xn*Reciprocal;
xn = (xn*Multiplier)%Modulus;
}
return data;
}
}
}

56
src/Numerics/Random/MersenneTwister.cs

@ -66,6 +66,7 @@
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
*/
using System;
using System.Threading;
namespace MathNet.Numerics.Random
@ -113,7 +114,7 @@ namespace MathNet.Numerics.Random
/// <summary>
/// Mersenne twister constant.
/// </summary>
readonly uint[] _mt = new uint[624];
readonly uint[] _mt = new uint[N];
/// <summary>
/// Mersenne twister constant.
@ -329,5 +330,58 @@ namespace MathNet.Numerics.Random
ulong a = genrand_int32() >> 5, b = genrand_int32() >> 6;
return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0);
}*/
/// <summary>
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary>
public static double[] Samples(int length, int seed)
{
uint[] t = new uint[624];
int k;
uint s = (uint)seed;
t[0] = s & 0xffffffff;
for (k = 1; k < N; k++)
{
t[k] = (1812433253*(t[k - 1] ^ (t[k - 1] >> 30)) + (uint)k);
t[k] &= 0xffffffff;
}
var data = new double[length];
for (int i = 0; i < data.Length; i++)
{
uint y;
if (k >= N)
{
int kk;
for (kk = 0; kk < N - M; kk++)
{
y = (t[kk] & UpperMask) | (t[kk + 1] & LowerMask);
t[kk] = t[kk + M] ^ (y >> 1) ^ Mag01[y & 0x1];
}
for (; kk < N - 1; kk++)
{
y = (t[kk] & UpperMask) | (t[kk + 1] & LowerMask);
t[kk] = t[kk + (M - N)] ^ (y >> 1) ^ Mag01[y & 0x1];
}
y = (t[N - 1] & UpperMask) | (t[0] & LowerMask);
t[N - 1] = t[M - 1] ^ (y >> 1) ^ Mag01[y & 0x1];
k = 0;
}
y = t[k++];
/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680;
y ^= (y << 15) & 0xefc60000;
y ^= (y >> 18);
data[i] = y*Reciprocal;
}
return data;
}
}
}

44
src/Numerics/Random/Mrg32k3a.cs

@ -28,8 +28,6 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
namespace MathNet.Numerics.Random
{
/// <summary>
@ -140,5 +138,47 @@ namespace MathNet.Numerics.Random
}
return (xn - yn)*Reciprocal;
}
/// <summary>
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary>
public static double[] Samples(int length, int seed)
{
double x1 = 1;
double x2 = 1;
double x3 = (uint)seed;
double y1 = 1;
double y2 = 1;
double y3 = 1;
var data = new double[length];
for (int i = 0; i < data.Length; i++)
{
double xn = A12*x2 - A13*x3;
double k = (long)(xn/Modulus1);
xn -= k*Modulus1;
if (xn < 0)
{
xn += Modulus1;
}
double yn = A21*y1 - A23*y3;
k = (long)(yn/Modulus2);
yn -= k*Modulus2;
if (yn < 0)
{
yn += Modulus2;
}
x3 = x2;
x2 = x1;
x1 = xn;
y3 = y2;
y2 = y1;
y1 = yn;
data[i] = xn <= yn ? (xn - yn + Modulus1)*Reciprocal : (xn - yn)*Reciprocal;
}
return data;
}
}
}

129
src/Numerics/Random/Palf.cs

@ -30,7 +30,6 @@
using System;
using MathNet.Numerics.Properties;
using MathNet.Numerics.Threading;
namespace MathNet.Numerics.Random
{
@ -38,9 +37,9 @@ namespace MathNet.Numerics.Random
/// Represents a Parallel Additive Lagged Fibonacci pseudo-random number generator.
/// </summary>
/// <remarks>
/// The <see cref="Palf"/> type bases upon the implementation in the
/// The <see cref="Palf"/> type bases upon the implementation in the
/// <a href="http://www.boost.org/libs/random/index.html">Boost Random Number Library</a>.
/// It uses the modulus 2<sup>32</sup> and by default the "lags" 418 and 1279. Some popular pairs are presented on
/// It uses the modulus 2<sup>32</sup> and by default the "lags" 418 and 1279. Some popular pairs are presented on
/// <a href="http://en.wikipedia.org/wiki/Lagged_Fibonacci_generator">Wikipedia - Lagged Fibonacci generator</a>.
/// </remarks>
public class Palf : RandomSource
@ -91,6 +90,15 @@ namespace MathNet.Numerics.Random
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Palf"/> class.
/// </summary>
/// <param name="seed">The seed value.</param>
/// <param name="threadSafe">if set to <c>true</c> , the class is thread safe.</param>
public Palf(int seed, bool threadSafe) : this(seed, threadSafe, DefaultShortLag, DefaultLongLag)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Palf"/> class.
/// </summary>
@ -115,26 +123,21 @@ namespace MathNet.Numerics.Random
seed = 1;
}
_threads = Control.NumberOfParallelWorkerThreads;
ShortLag = shortLag;
// Align LongLag to number of worker threads.
if (longLag%Control.NumberOfParallelWorkerThreads == 0)
// Align LongLag to number of worker threads.
if (longLag%_threads == 0)
{
LongLag = longLag;
}
else
{
LongLag = ((longLag/Control.NumberOfParallelWorkerThreads) + 1)*Control.NumberOfParallelWorkerThreads;
}
_x = new uint[LongLag];
var gen = new MersenneTwister(seed, threadSafe);
for (var j = 0; j < LongLag; ++j)
{
_x[j] = (uint)(gen.NextDouble()*uint.MaxValue);
LongLag = ((longLag/_threads) + 1)*_threads;
}
_i = LongLag;
_x = Generate.Map(MersenneTwister.Samples(LongLag, seed), uniform => (uint)(uniform*uint.MaxValue));
_k = LongLag;
}
/// <summary>
@ -152,10 +155,12 @@ namespace MathNet.Numerics.Random
/// </summary>
readonly uint[] _x;
readonly int _threads;
/// <summary>
/// Stores an index for the random number array element that will be accessed next.
/// </summary>
int _i;
int _k;
/// <summary>
/// Fills the array <see cref="_x"/> with <see cref="LongLag"/> new unsigned random numbers.
@ -166,23 +171,38 @@ namespace MathNet.Numerics.Random
/// </remarks>
void Fill()
{
CommonParallel.For(0, Control.NumberOfParallelWorkerThreads, (u, v) =>
//CommonParallel.For(0, Control.NumberOfParallelWorkerThreads, (u, v) =>
//{
// 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)
// {
// _x[j] += _x[j - ShortLag - index];
// }
// }
//});
for (int index = 0; index < _threads; index++)
{
for (int index = u; index < v; index++)
// Two loops to avoid costly modulo operations
for (var j = index; j < ShortLag; j = j + _threads)
{
// Two loops to avoid costly modulo operations
for (var j = index; j < ShortLag; j = j + Control.NumberOfParallelWorkerThreads)
{
_x[j] += _x[j + (LongLag - ShortLag)];
}
_x[j] += _x[j + (LongLag - ShortLag)];
}
for (var j = ShortLag + index; j < LongLag; j = j + Control.NumberOfParallelWorkerThreads)
{
_x[j] += _x[j - ShortLag - index];
}
for (var j = ShortLag + index; j < LongLag; j = j + _threads)
{
_x[j] += _x[j - ShortLag - index];
}
});
_i = 0;
}
_k = 0;
}
/// <summary>
@ -193,13 +213,62 @@ namespace MathNet.Numerics.Random
/// </returns>
protected override double DoSample()
{
if (_i >= LongLag)
if (_k >= LongLag)
{
Fill();
}
var x = _x[_i++];
var x = _x[_k++];
return (int)(x >> 1)*IntToDoubleMultiplier;
}
/// <summary>
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary>
public static double[] Samples(int length, int seed)
{
if (seed == 0)
{
seed = 1;
}
int threads = Control.NumberOfParallelWorkerThreads;
const int shortLag = DefaultShortLag;
var longLag = DefaultLongLag;
// Align LongLag to number of worker threads.
if (longLag%threads != 0)
{
longLag = ((longLag/threads) + 1)*threads;
}
var x = Generate.Map(MersenneTwister.Samples(longLag, seed), uniform => (uint)(uniform*uint.MaxValue));
var k = longLag;
var data = new double[length];
for (int i = 0; i < data.Length; i++)
{
if (k >= longLag)
{
for (int index = 0; index < threads; index++)
{
// Two loops to avoid costly modulo operations
for (var j = index; j < shortLag; j = j + threads)
{
x[j] += x[j + (longLag - shortLag)];
}
for (var j = shortLag + index; j < longLag; j = j + threads)
{
x[j] += x[j - shortLag - index];
}
}
k = 0;
}
data[i] = (int)(x[k++] >> 1)*IntToDoubleMultiplier;
}
return data;
}
}
}

22
src/Numerics/Random/RandomExtensions.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,9 +28,10 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
namespace MathNet.Numerics.Random
{
using System;
/// <summary>
/// This class implements extension methods for the System.Random class. The extension methods generate
@ -49,9 +50,9 @@ namespace MathNet.Numerics.Random
/// the range of return values includes 0 but not <see cref="Int64.MaxValue"/>.
/// </returns>
/// <seealso cref="NextFullRangeInt64"/>
public static long NextInt64(this Random rnd)
public static long NextInt64(this System.Random rnd)
{
var buffer = new byte[sizeof(long)];
var buffer = new byte[sizeof (long)];
rnd.NextBytes(buffer);
var candidate = BitConverter.ToInt64(buffer, 0);
@ -75,9 +76,9 @@ namespace MathNet.Numerics.Random
/// <see cref="Int32.MaxValue"/> and <see cref="Int32.MinValue"/>.
/// </returns>
/// <seealso cref="System.Random.Next()"/>
public static int NextFullRangeInt32(this Random rnd)
public static int NextFullRangeInt32(this System.Random rnd)
{
var buffer = new byte[sizeof(int)];
var buffer = new byte[sizeof (int)];
rnd.NextBytes(buffer);
return BitConverter.ToInt32(buffer, 0);
}
@ -93,9 +94,9 @@ namespace MathNet.Numerics.Random
/// <see cref="Int64.MaxValue"/> and <see cref="Int64.MinValue"/>.
/// </returns>
/// <seealso cref="NextInt64"/>
public static long NextFullRangeInt64(this Random rnd)
public static long NextFullRangeInt64(this System.Random rnd)
{
var buffer = new byte[sizeof(long)];
var buffer = new byte[sizeof (long)];
rnd.NextBytes(buffer);
return BitConverter.ToInt64(buffer, 0);
}
@ -110,7 +111,7 @@ namespace MathNet.Numerics.Random
/// A decimal floating point number greater than or equal to 0.0, and less than 1.0; that is,
/// the range of return values includes 0.0 but not 1.0.
/// </returns>
public static decimal NextDecimal(this Random rnd)
public static decimal NextDecimal(this System.Random rnd)
{
decimal candidate;
@ -125,8 +126,7 @@ namespace MathNet.Numerics.Random
rnd.NextFullRangeInt32(),
false,
28);
}
while (candidate >= 1.0m);
} while (candidate >= 1.0m);
return candidate;
}

26
src/Numerics/Random/WH1982.cs

@ -113,5 +113,31 @@ namespace MathNet.Numerics.Random
w -= (int)w;
return w;
}
/// <summary>
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary>
public static double[] Samples(int length, int seed)
{
if (seed == 0)
{
seed = 1;
}
uint xn = (uint)seed%Modx;
uint yn = 1;
uint zn = 1;
var data = new double[length];
for (int i = 0; i < data.Length; i++)
{
xn = (171*xn)%Modx;
yn = (172*yn)%Mody;
zn = (170*zn)%Modz;
double w = xn*ModxRecip + yn*ModyRecip + zn*ModzRecip;
data[i] = w - (int)w;
}
return data;
}
}
}

28
src/Numerics/Random/WH2006.cs

@ -116,5 +116,33 @@ namespace MathNet.Numerics.Random
u -= (int)u;
return u;
}
/// <summary>
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary>
public static double[] Samples(int length, int seed)
{
if (seed == 0)
{
seed = 1;
}
ulong wn = 1;
ulong xn = (uint)seed%Modx;
ulong yn = 1;
ulong zn = 1;
var data = new double[length];
for (int i = 0; i < data.Length; i++)
{
xn = 11600*xn%Modx;
yn = 47003*yn%Mody;
zn = 23000*zn%Modz;
wn = 33000*wn%Modw;
double u = xn*ModxRecip + yn*ModyRecip + zn*ModzRecip + wn*ModwRecip;
data[i] = u - (int)u;
}
return data;
}
}
}

29
src/Numerics/Random/Xorshift.cs

@ -261,5 +261,34 @@ namespace MathNet.Numerics.Random
_z = t & 0xffffffff;
return _z*UlongToDoubleMultiplier;
}
/// <summary>
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary>
public static double[] Samples(int length, int seed, ulong a = ASeed, ulong c = CSeed, ulong x1 = YSeed, ulong x2 = ZSeed)
{
if (a <= c)
{
throw new ArgumentException(string.Format(Resources.ArgumentOutOfRangeGreater, "a", "c"), "a");
}
if (seed == 0)
{
seed = 1;
}
ulong x = (uint)seed;
var data = new double[length];
for (int i = 0; i < data.Length; i++)
{
var t = (a*x) + c;
x = x1;
x1 = x2;
c = t >> 32;
x2 = t & 0xffffffff;
data[i] = x2*UlongToDoubleMultiplier;
}
return data;
}
}
}

17
src/UnitTests/Random/SystemCryptoTests.cs → src/UnitTests/Random/CryptoRandomSourceTests.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com
// 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
// files (the "Software"), to deal in the Software without
@ -12,8 +14,10 @@
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -25,11 +29,12 @@
// </copyright>
#if !PORTABLE
using MathNet.Numerics.Random;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.Random
{
using Numerics.Random;
using NUnit.Framework;
/// <summary>
/// Tests for a random number generator based on the <see cref="System.Security.Cryptography.RandomNumberGenerator"/> class in the .NET library
/// </summary>
@ -39,10 +44,10 @@ namespace MathNet.Numerics.UnitTests.Random
/// <summary>
/// Initializes a new instance of the SystemCryptoRandomNumberGeneratorTests class.
/// </summary>
public CryptoRandomSourceTests()
: base(typeof(CryptoRandomSource))
public CryptoRandomSourceTests() : base(typeof (CryptoRandomSource))
{
}
}
}
#endif

20
src/UnitTests/Random/Mcg31m1Tests.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com
// 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
// files (the "Software"), to deal in the Software without
@ -12,8 +14,10 @@
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -24,11 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.Random;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.Random
{
using Numerics.Random;
using NUnit.Framework;
/// <summary>
/// Tests for Multiplicative congruential generator using a modulus of 2^31-1 and a multiplier of 1132489760.
/// </summary>
@ -38,8 +42,14 @@ namespace MathNet.Numerics.UnitTests.Random
/// <summary>
/// Initializes a new instance of the Mcg31M1Tests class.
/// </summary>
public Mcg31M1Tests() : base(typeof(Mcg31m1))
public Mcg31M1Tests() : base(typeof (Mcg31m1))
{
}
[Test]
public void StaticSamplesConsistent()
{
Assert.That(Mcg31m1.Samples(1000, 1), Is.EqualTo(new Mcg31m1(1).NextDoubles(1000)).Within(1e-12).AsCollection);
}
}
}

20
src/UnitTests/Random/Mcg59Tests.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com
// 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
// files (the "Software"), to deal in the Software without
@ -12,8 +14,10 @@
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -24,11 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.Random;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.Random
{
using Numerics.Random;
using NUnit.Framework;
/// <summary>
/// Tests for multiplicative congruential generator using a modulus of 2^59 and a multiplier of 13^13.
/// </summary>
@ -38,8 +42,14 @@ namespace MathNet.Numerics.UnitTests.Random
/// <summary>
/// Initializes a new instance of the Mcg59Tests class.
/// </summary>
public Mcg59Tests() : base(typeof(Mcg59))
public Mcg59Tests() : base(typeof (Mcg59))
{
}
[Test]
public void StaticSamplesConsistent()
{
Assert.That(Mcg59.Samples(1000, 1), Is.EqualTo(new Mcg59(1).NextDoubles(1000)).Within(1e-12).AsCollection);
}
}
}

20
src/UnitTests/Random/MersenneTwisterTests.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com
// 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
// files (the "Software"), to deal in the Software without
@ -12,8 +14,10 @@
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -24,11 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.Random;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.Random
{
using Numerics.Random;
using NUnit.Framework;
/// <summary>
/// Tests for random number generator using Mersenne Twister 19937 algorithm.
/// </summary>
@ -38,7 +42,7 @@ namespace MathNet.Numerics.UnitTests.Random
/// <summary>
/// Initializes a new instance of the MersenneTwisterTests class.
/// </summary>
public MersenneTwisterTests() : base(typeof(MersenneTwister))
public MersenneTwisterTests() : base(typeof (MersenneTwister))
{
}
@ -54,5 +58,11 @@ namespace MathNet.Numerics.UnitTests.Random
Assert.AreEqual(mt.NextDouble(), 0.7151893649715930);
Assert.AreEqual(mt.NextDouble(), 0.8442657440900803);
}
[Test]
public void StaticSamplesConsistent()
{
Assert.That(MersenneTwister.Samples(1000, 1), Is.EqualTo(new MersenneTwister(1).NextDoubles(1000)).Within(1e-12).AsCollection);
}
}
}

21
src/UnitTests/Random/Mrg32k3aTests.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com
// 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
// files (the "Software"), to deal in the Software without
@ -12,8 +14,10 @@
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -24,11 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.Random;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.Random
{
using Numerics.Random;
using NUnit.Framework;
/// <summary>
/// Tests for a 32-bit combined multiple recursive generator with 2 components of order 3.
/// </summary>
@ -38,9 +42,14 @@ namespace MathNet.Numerics.UnitTests.Random
/// <summary>
/// Initializes a new instance of the Mrg32K3ATests class.
/// </summary>
public Mrg32K3ATests()
: base(typeof(Mrg32k3a))
public Mrg32K3ATests() : base(typeof (Mrg32k3a))
{
}
[Test]
public void StaticSamplesConsistent()
{
Assert.That(Mrg32k3a.Samples(1000, 1), Is.EqualTo(new Mrg32k3a(1).NextDoubles(1000)).Within(1e-12).AsCollection);
}
}
}

23
src/UnitTests/Random/PalfTests.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com
// 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
// files (the "Software"), to deal in the Software without
@ -12,8 +14,10 @@
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -24,12 +28,12 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
using MathNet.Numerics.Random;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.Random
{
using System;
using Numerics.Random;
using NUnit.Framework;
/// <summary>
/// Tests for a Parallel Additive Lagged Fibonacci pseudo-random number generator.
/// </summary>
@ -39,8 +43,7 @@ namespace MathNet.Numerics.UnitTests.Random
/// <summary>
/// Initializes a new instance of the PalfTests class.
/// </summary>
public PalfTests()
: base(typeof(Palf))
public PalfTests() : base(typeof (Palf))
{
}
@ -61,5 +64,11 @@ namespace MathNet.Numerics.UnitTests.Random
{
Assert.Throws<ArgumentException>(() => new Palf(1, true, 10, 10));
}
[Test]
public void StaticSamplesConsistent()
{
Assert.That(Palf.Samples(1000, 1), Is.EqualTo(new Palf(1).NextDoubles(1000)).Within(1e-12).AsCollection);
}
}
}

23
src/UnitTests/Random/SystemRandomExtensionTests.cs → src/UnitTests/Random/RandomExtensionTests.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com
// 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
// files (the "Software"), to deal in the Software without
@ -12,8 +14,10 @@
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -24,17 +28,16 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.Random;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.Random
{
using System;
using Numerics.Random;
using NUnit.Framework;
/// <summary>
/// Tests for extension methods of the System.Random.
/// </summary>
[TestFixture, Category("Random")]
public class SystemRandomExtensionTests
public class RandomExtensionTests
{
/// <summary>
/// Can sample int64.
@ -42,7 +45,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test]
public void CanSampleInt64()
{
var rnd = new Random(0);
var rnd = new System.Random(0);
rnd.NextInt64();
}
@ -52,7 +55,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test]
public void CanSampleFullRangeInt32()
{
var rnd = new Random(0);
var rnd = new System.Random(0);
rnd.NextFullRangeInt32();
}
@ -62,7 +65,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test]
public void CanSampleFullRangeInt64()
{
var rnd = new Random(0);
var rnd = new System.Random(0);
rnd.NextFullRangeInt64();
}
@ -72,7 +75,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test]
public void CanSampleDecimal()
{
var rnd = new Random(0);
var rnd = new System.Random(0);
rnd.NextDecimal();
}
}

42
src/UnitTests/Random/RandomTests.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com
// 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
// files (the "Software"), to deal in the Software without
@ -12,8 +14,10 @@
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -24,12 +28,13 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
using System.Threading;
using MathNet.Numerics.Random;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.Random
{
using System;
using System.Threading;
using NUnit.Framework;
/// <summary>
/// Abstract class fro RNG tests.
/// </summary>
@ -38,12 +43,12 @@ namespace MathNet.Numerics.UnitTests.Random
/// <summary>
/// Number of samples.
/// </summary>
private const int N = 10000;
const int N = 10000;
/// <summary>
/// Random generator type.
/// </summary>
private readonly Type _randomType;
readonly Type _randomType;
/// <summary>
/// Initializes a new instance of the RandomTests class.
@ -60,7 +65,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test]
public void Sample()
{
var random = (Random)Activator.CreateInstance(_randomType, new object[] { false });
var random = (System.Random)Activator.CreateInstance(_randomType, new object[] { false });
double sum = 0;
for (var i = 0; i < N; i++)
{
@ -71,21 +76,34 @@ namespace MathNet.Numerics.UnitTests.Random
}
// make sure are within 10% of the expected sum.
Assert.IsTrue(sum >= (N / 2.0) - (.05 * N));
Assert.IsTrue(sum <= (N / 2.0) + (.05 * N));
Assert.IsTrue(sum >= (N/2.0) - (.05*N));
Assert.IsTrue(sum <= (N/2.0) + (.05*N));
if (random is IDisposable)
{
((IDisposable)random).Dispose();
}
}
[Test]
public void Reproducible()
{
if (_randomType == typeof (CryptoRandomSource))
{
Assert.Ignore("CryptoRandomSource does not support seeds and is not reproducible by design.");
}
Assert.That(
((RandomSource)Activator.CreateInstance(_randomType, new object[] { 5, false })).NextDoubles(1000),
Is.EqualTo(((RandomSource)Activator.CreateInstance(_randomType, new object[] { 5, false })).NextDoubles(1000)).Within(1e-12).AsCollection);
}
/// <summary>
/// Can thread-safe sample
/// </summary>
[Test]
public void ThreadSafeSample()
{
var random = (Random)Activator.CreateInstance(_randomType, new object[] { true });
var random = (System.Random)Activator.CreateInstance(_randomType, new object[] { true });
var t1 = new Thread(RunTest);
var t2 = new Thread(RunTest);
@ -101,7 +119,7 @@ namespace MathNet.Numerics.UnitTests.Random
/// <param name="random">RNG object.</param>
public void RunTest(object random)
{
var rng = (Random)random;
var rng = (System.Random)random;
for (var i = 0; i < N; i++)
{
var next = rng.NextDouble();

23
src/UnitTests/Random/WH1982Tests.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com
// 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
// files (the "Software"), to deal in the Software without
@ -12,8 +14,10 @@
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -24,13 +28,13 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.Random;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.Random
{
using Numerics.Random;
using NUnit.Framework;
/// <summary>
/// Tests for a Wichmann-Hill’s 1982 combined multiplicative congruential generator.
/// Tests for a Wichmann-Hill’s 1982 combined multiplicative congruential generator.
/// </summary>
[TestFixture, Category("Random")]
public class Wh1982Tests : RandomTests
@ -38,9 +42,14 @@ namespace MathNet.Numerics.UnitTests.Random
/// <summary>
/// Initializes a new instance of the Wh1982Tests class.
/// </summary>
public Wh1982Tests()
: base(typeof(WH1982))
public Wh1982Tests() : base(typeof (WH1982))
{
}
[Test]
public void StaticSamplesConsistent()
{
Assert.That(WH1982.Samples(1000, 1), Is.EqualTo(new WH1982(1).NextDoubles(1000)).Within(1e-12).AsCollection);
}
}
}

23
src/UnitTests/Random/WH2006Tests.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com
// 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
// files (the "Software"), to deal in the Software without
@ -12,8 +14,10 @@
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -24,13 +28,13 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.Random;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.Random
{
using Numerics.Random;
using NUnit.Framework;
/// <summary>
/// Test for a Wichmann-Hill’s 2006 combined multiplicative congruential generator.
/// Test for a Wichmann-Hill’s 2006 combined multiplicative congruential generator.
/// </summary>
[TestFixture, Category("Random")]
public class Wh2006Tests : RandomTests
@ -38,9 +42,14 @@ namespace MathNet.Numerics.UnitTests.Random
/// <summary>
/// Initializes a new instance of the Wh2006Tests class.
/// </summary>
public Wh2006Tests()
: base(typeof(WH2006))
public Wh2006Tests() : base(typeof (WH2006))
{
}
[Test]
public void StaticSamplesConsistent()
{
Assert.That(WH2006.Samples(1000, 1), Is.EqualTo(new WH2006(1).NextDoubles(1000)).Within(1e-12).AsCollection);
}
}
}

21
src/UnitTests/Random/XorshiftTests.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com
// 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
// files (the "Software"), to deal in the Software without
@ -12,8 +14,10 @@
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -24,11 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.Random;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.Random
{
using Numerics.Random;
using NUnit.Framework;
/// <summary>
/// Tests for a multiply-with-carry Xorshift pseudo random number generator (RNG) specified in Marsaglia, George. (2003). Xorshift RNGs.
/// </summary>
@ -38,9 +42,14 @@ namespace MathNet.Numerics.UnitTests.Random
/// <summary>
/// Initializes a new instance of the XorshiftTests class.
/// </summary>
public XorshiftTests()
: base(typeof(Xorshift))
public XorshiftTests() : base(typeof (Xorshift))
{
}
[Test]
public void StaticSamplesConsistent()
{
Assert.That(Xorshift.Samples(1000, 1), Is.EqualTo(new Xorshift(1).NextDoubles(1000)).Within(1e-12).AsCollection);
}
}
}

4
src/UnitTests/UnitTests.csproj

@ -368,8 +368,8 @@
<Compile Include="Random\Mrg32k3aTests.cs" />
<Compile Include="Random\PalfTests.cs" />
<Compile Include="Random\RandomTests.cs" />
<Compile Include="Random\SystemCryptoTests.cs" />
<Compile Include="Random\SystemRandomExtensionTests.cs" />
<Compile Include="Random\CryptoRandomSourceTests.cs" />
<Compile Include="Random\RandomExtensionTests.cs" />
<Compile Include="Random\WH1982Tests.cs" />
<Compile Include="Random\WH2006Tests.cs" />
<Compile Include="Random\XorshiftTests.cs" />

Loading…
Cancel
Save