Browse Source

Random: api cleanup

optimization-3
Christoph Ruegg 13 years ago
parent
commit
40bad6b301
  1. 111
      src/FSharp/Random.fs
  2. 6
      src/Numerics/Random/CryptoRandomSource.cs
  3. 6
      src/Numerics/Random/Mcg31m1.cs
  4. 8
      src/Numerics/Random/Mcg59.cs
  5. 11
      src/Numerics/Random/MersenneTwister.cs
  6. 6
      src/Numerics/Random/Mrg32k3a.cs
  7. 12
      src/Numerics/Random/Palf.cs
  8. 116
      src/Numerics/Random/RandomExtensions.cs
  9. 27
      src/Numerics/Random/RandomSource.cs
  10. 59
      src/Numerics/Random/SystemRandomSource.cs
  11. 6
      src/Numerics/Random/WH1982.cs
  12. 6
      src/Numerics/Random/WH2006.cs
  13. 6
      src/Numerics/Random/Xorshift.cs
  14. 2
      src/UnitTests/Random/Mcg31m1Tests.cs
  15. 2
      src/UnitTests/Random/Mcg59Tests.cs
  16. 2
      src/UnitTests/Random/MersenneTwisterTests.cs
  17. 2
      src/UnitTests/Random/Mrg32k3aTests.cs
  18. 2
      src/UnitTests/Random/PalfTests.cs
  19. 2
      src/UnitTests/Random/SystemRandomSourceTests.cs
  20. 2
      src/UnitTests/Random/WH1982Tests.cs
  21. 2
      src/UnitTests/Random/WH2006Tests.cs
  22. 2
      src/UnitTests/Random/XorshiftTests.cs

111
src/FSharp/Random.fs

@ -37,78 +37,67 @@ module Random =
let shared = SystemRandomSource.Default :> System.Random let shared = SystemRandomSource.Default :> System.Random
/// Default sampling, efficient but without custom seed (uses robust seeds internally) /// Default sampling, efficient but without custom seed (uses robust seeds internally)
let samples length = SystemRandomSource.Samples(length) let inline doubles (length:int) = SystemRandomSource.Doubles(length)
let sampleSeq () = SystemRandomSource.SampleSequence() let inline doubleSeq () = SystemRandomSource.DoubleSequence()
let inline doubleFill (values:double[]) = SystemRandomSource.Doubles(values)
/// Creates a default .Net system pRNG with a custom seed based on uinque GUIDs let inline doublesSeed (seed:int) (length:int) = SystemRandomSource.Doubles(length, seed)
let system () = new SystemRandomSource() :> System.Random let inline doubleSeqSeed (seed:int) = SystemRandomSource.DoubleSequence(seed)
let systemSeed (seed:int) = new SystemRandomSource(seed) :> System.Random let inline doubleFillSeed (seed:int) (values:double[]) = SystemRandomSource.Doubles(values, seed)
let systemSamples (seed:int) length = SystemRandomSource.Samples(length, seed)
let systemSampleSeq (seed:int) = SystemRandomSource.SampleSequence(seed) /// Creates a default .Net system pRNG with a robust seed
let systemShared = shared
let inline system () = SystemRandomSource() :> System.Random
let inline systemSeed (seed:int) = SystemRandomSource(seed) :> System.Random
#if PORTABLE #if PORTABLE
#else #else
/// Creates a default .Net cryptographic system pRNG /// Creates a default .Net cryptographic system pRNG
let crypto () = new CryptoRandomSource() :> System.Random let inline crypto () = new CryptoRandomSource() :> System.Random
let cryptoWith (threadSafe:bool) = new CryptoRandomSource(threadSafe) :> System.Random let inline cryptoWith (threadSafe:bool) = new CryptoRandomSource(threadSafe) :> System.Random
let cryptoSamples length = CryptoRandomSource.Samples(length) let inline cryptoDoubles length = CryptoRandomSource.Doubles(length)
let cryptoSampleSeq () = CryptoRandomSource.SampleSequence() let inline cryptoDoubleSeq () = CryptoRandomSource.DoubleSequence()
#endif #endif
/// Creates a Mersenne Twister 19937 pRNG with a custom seed based on uinque GUIDs /// Creates a Mersenne Twister 19937 pRNG with a robust seed
let mersenneTwister () = new MersenneTwister() :> System.Random let mersenneTwisterShared = MersenneTwister.Default :> System.Random
let mersenneTwisterSeed (seed:int) = new MersenneTwister(seed) :> System.Random let inline mersenneTwister () = MersenneTwister() :> System.Random
let mersenneTwisterWith seed threadSafe = new MersenneTwister(seed, threadSafe) :> System.Random let inline mersenneTwisterSeed (seed:int) = MersenneTwister(seed) :> System.Random
let mersenneTwisterSamples (seed:int) length = MersenneTwister.Samples(length, seed) let inline mersenneTwisterWith (seed:int) threadSafe = MersenneTwister(seed, threadSafe) :> System.Random
let mersenneTwisterSampleSeq (seed:int) = MersenneTwister.SampleSequence(seed)
/// Creates a multiply-with-carry Xorshift (Xn = a * Xn−3 + c mod 2^32) pRNG with a custom seed based on uinque GUIDs /// Creates a multiply-with-carry Xorshift (Xn = a * Xn−3 + c mod 2^32) pRNG with a robust seed
let xorshift () = new Xorshift() :> System.Random let inline xorshift () = Xorshift() :> System.Random
let xorshiftSeed (seed:int) = new Xorshift(seed) :> System.Random let inline xorshiftSeed (seed:int) = Xorshift(seed) :> System.Random
let xorshiftWith seed threadSafe = new Xorshift(seed, threadSafe) :> System.Random let inline xorshiftWith (seed:int) threadSafe = Xorshift(seed, threadSafe) :> System.Random
let xorshiftCustom seed threadSafe a c x1 x2 = new Xorshift(seed, threadSafe, a, c, x1, x2) :> System.Random let inline xorshiftCustom (seed:int) threadSafe a c x1 x2 = Xorshift(seed, threadSafe, a, c, x1, x2) :> System.Random
let xorshiftSamples (seed:int) length = Xorshift.Samples(length, seed)
let xorshiftSampleSeq (seed:int) = Xorshift.SampleSequence(seed)
/// Creates a Wichmann-Hill’s 1982 combined multiplicative congruential pRNG with a custom seed based on uinque GUIDs /// Creates a Wichmann-Hill’s 1982 combined multiplicative congruential pRNG with a robust seed
let wh1982 () = new WH1982() :> System.Random let inline wh1982 () = WH1982() :> System.Random
let wh1982Seed (seed:int) = new WH1982(seed) :> System.Random let inline wh1982Seed (seed:int) = WH1982(seed) :> System.Random
let wh1982With seed threadSafe = new WH1982(seed, threadSafe) :> System.Random let inline wh1982With (seed:int) threadSafe = WH1982(seed, threadSafe) :> System.Random
let wh1982Samples (seed:int) length = WH1982.Samples(length, seed)
let wh1982SampleSeq (seed:int) = WH1982.SampleSequence(seed)
/// Creates a Wichmann-Hill’s 2006 combined multiplicative congruential pRNG with a custom seed based on uinque GUIDs /// Creates a Wichmann-Hill’s 2006 combined multiplicative congruential pRNG with a robust seed
let wh2006 () = new WH2006() :> System.Random let inline wh2006 () = WH2006() :> System.Random
let wh2006Seed (seed:int) = new WH2006(seed) :> System.Random let inline wh2006Seed (seed:int) = WH2006(seed) :> System.Random
let wh2006With seed threadSafe = new WH2006(seed, threadSafe) :> System.Random let inline wh2006With (seed:int) threadSafe = WH2006(seed, threadSafe) :> System.Random
let wh2006Samples (seed:int) length = WH2006.Samples(length, seed)
let wh2006SampleSeq (seed:int) = WH2006.SampleSequence(seed)
/// Creates a Parallel Additive Lagged Fibonacci pRNG with a custom seed based on uinque GUIDs /// Creates a Parallel Additive Lagged Fibonacci pRNG with a robust seed
let palf () = new Palf() :> System.Random let inline palf () = Palf() :> System.Random
let palfSeed (seed:int) = new Palf(seed) :> System.Random let inline palfSeed (seed:int) = Palf(seed) :> System.Random
let palfWith seed threadSafe = new Palf(seed, threadSafe, 418, 1279) :> System.Random let inline palfWith (seed:int) threadSafe = Palf(seed, threadSafe, 418, 1279) :> System.Random
let palfCustom seed threadSafe shortLag longLag = new Palf(seed, threadSafe, shortLag, longLag) :> System.Random let inline palfCustom (seed:int) threadSafe shortLag longLag = Palf(seed, threadSafe, shortLag, longLag) :> System.Random
let palfSamples (seed:int) length = Palf.Samples(length, seed)
let palfSampleSeq (seed:int) = Palf.SampleSequence(seed)
/// Creates a Multiplicative congruential generator using a modulus of 2^59 and a multiplier of 13^13 pRNG with a custom seed based on uinque GUIDs /// Creates a Multiplicative congruential generator using a modulus of 2^59 and a multiplier of 13^13 pRNG with a robust seed
let mcg59 () = new Mcg59() :> System.Random let inline mcg59 () = Mcg59() :> System.Random
let mcg59Seed (seed:int) = new Mcg59(seed) :> System.Random let inline mcg59Seed (seed:int) = Mcg59(seed) :> System.Random
let mcg59With seed threadSafe = new Mcg59(seed, threadSafe) :> System.Random let inline mcg59With (seed:int) threadSafe = Mcg59(seed, threadSafe) :> System.Random
let mcg59Samples (seed:int) length = Mcg59.Samples(length, seed)
let mcg59SampleSeq (seed:int) = Mcg59.SampleSequence(seed)
/// Creates a Multiplicative congruential generator using a modulus of 2^31-1 and a multiplier of 1132489760 pRNG with a custom seed based on uinque GUIDs /// Creates a Multiplicative congruential generator using a modulus of 2^31-1 and a multiplier of 1132489760 pRNG with a robust seed
let mcg31m1 () = new Mcg31m1() :> System.Random let inline mcg31m1 () = Mcg31m1() :> System.Random
let mcg31m1Seed (seed:int) = new Mcg31m1(seed) :> System.Random let inline mcg31m1Seed (seed:int) = Mcg31m1(seed) :> System.Random
let mcg31m1With seed threadSafe = new Mcg31m1(seed, threadSafe) :> System.Random let inline mcg31m1With (seed:int) threadSafe = Mcg31m1(seed, threadSafe) :> System.Random
let mcg31m1Samples (seed:int) length = Mcg31m1.Samples(length, seed)
let mcg31m1SampleSeq (seed:int) = Mcg31m1.SampleSequence(seed)
/// Creates a 32-bit combined multiple recursive generator with 2 components of order 3 pRNG with a custom seed based on uinque GUIDs /// Creates a 32-bit combined multiple recursive generator with 2 components of order 3 pRNG with a robust seed
let mrg32k3a () = new Mrg32k3a() :> System.Random let inline mrg32k3a () = Mrg32k3a() :> System.Random
let mrg32k3aSeed (seed:int) = new Mrg32k3a(seed) :> System.Random let inline mrg32k3aSeed (seed:int) = Mrg32k3a(seed) :> System.Random
let mrg32k3aWith seed threadSafe = new Mrg32k3a(seed, threadSafe) :> System.Random let inline mrg32k3aWith (seed:int) threadSafe = Mrg32k3a(seed, threadSafe) :> System.Random
let mrg32k3aSamples (seed:int) length = Mrg32k3a.Samples(length, seed)
let mrg32k3aSampleSeq (seed:int) = Mrg32k3a.SampleSequence(seed)

6
src/Numerics/Random/CryptoRandomSource.cs

@ -92,7 +92,7 @@ namespace MathNet.Numerics.Random
/// <returns> /// <returns>
/// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
/// </returns> /// </returns>
protected override double DoSample() protected override sealed double DoSample()
{ {
var bytes = new byte[4]; var bytes = new byte[4];
_crypto.GetBytes(bytes); _crypto.GetBytes(bytes);
@ -109,7 +109,7 @@ namespace MathNet.Numerics.Random
/// <summary> /// <summary>
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
public static double[] Samples(int length) public static double[] Doubles(int length)
{ {
var rnd = new RNGCryptoServiceProvider(); var rnd = new RNGCryptoServiceProvider();
var bytes = new byte[length*4]; var bytes = new byte[length*4];
@ -125,7 +125,7 @@ namespace MathNet.Numerics.Random
/// <summary> /// <summary>
/// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
public static IEnumerable<double> SampleSequence() public static IEnumerable<double> DoubleSequence()
{ {
var rnd = new RNGCryptoServiceProvider(); var rnd = new RNGCryptoServiceProvider();
var buffer = new byte[1024*4]; var buffer = new byte[1024*4];

6
src/Numerics/Random/Mcg31m1.cs

@ -95,7 +95,7 @@ namespace MathNet.Numerics.Random
/// <returns> /// <returns>
/// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
/// </returns> /// </returns>
protected override double DoSample() protected override sealed double DoSample()
{ {
double ret = _xn*Reciprocal; double ret = _xn*Reciprocal;
_xn = (_xn*Multiplier)%Modulus; _xn = (_xn*Multiplier)%Modulus;
@ -106,7 +106,7 @@ namespace MathNet.Numerics.Random
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads.</remarks> /// <remarks>Supports being called in parallel from multiple threads.</remarks>
public static double[] Samples(int length, int seed) public static double[] Doubles(int length, int seed)
{ {
if (seed == 0) if (seed == 0)
{ {
@ -127,7 +127,7 @@ namespace MathNet.Numerics.Random
/// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks> /// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks>
public static IEnumerable<double> SampleSequence(int seed) public static IEnumerable<double> DoubleSequence(int seed)
{ {
if (seed == 0) if (seed == 0)
{ {

8
src/Numerics/Random/Mcg59.cs

@ -37,9 +37,9 @@ namespace MathNet.Numerics.Random
/// </summary> /// </summary>
public class Mcg59 : RandomSource public class Mcg59 : RandomSource
{ {
const double Reciprocal = 1.0/Modulus;
const ulong Modulus = 576460752303423488; const ulong Modulus = 576460752303423488;
const ulong Multiplier = 302875106592253; const ulong Multiplier = 302875106592253;
const double Reciprocal = 1.0/Modulus;
ulong _xn; ulong _xn;
/// <summary> /// <summary>
@ -97,7 +97,7 @@ namespace MathNet.Numerics.Random
/// <returns> /// <returns>
/// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
/// </returns> /// </returns>
protected override double DoSample() protected override sealed double DoSample()
{ {
double ret = _xn*Reciprocal; double ret = _xn*Reciprocal;
_xn = (_xn*Multiplier)%Modulus; _xn = (_xn*Multiplier)%Modulus;
@ -108,7 +108,7 @@ namespace MathNet.Numerics.Random
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads.</remarks> /// <remarks>Supports being called in parallel from multiple threads.</remarks>
public static double[] Samples(int length, int seed) public static double[] Doubles(int length, int seed)
{ {
if (seed == 0) if (seed == 0)
{ {
@ -129,7 +129,7 @@ namespace MathNet.Numerics.Random
/// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks> /// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks>
public static IEnumerable<double> SampleSequence(int seed) public static IEnumerable<double> DoubleSequence(int seed)
{ {
if (seed == 0) if (seed == 0)
{ {

11
src/Numerics/Random/MersenneTwister.cs

@ -67,7 +67,12 @@
*/ */
using System.Collections.Generic; using System.Collections.Generic;
#if PORTABLE
using System;
#else
using System.Threading; using System.Threading;
#endif
namespace MathNet.Numerics.Random namespace MathNet.Numerics.Random
{ {
@ -316,7 +321,7 @@ namespace MathNet.Numerics.Random
/// <returns> /// <returns>
/// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
/// </returns> /// </returns>
protected override double DoSample() protected override sealed double DoSample()
{ {
return genrand_int32()*Reciprocal; return genrand_int32()*Reciprocal;
} }
@ -335,7 +340,7 @@ namespace MathNet.Numerics.Random
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads.</remarks> /// <remarks>Supports being called in parallel from multiple threads.</remarks>
public static double[] Samples(int length, int seed) public static double[] Doubles(int length, int seed)
{ {
uint[] t = new uint[624]; uint[] t = new uint[624];
int k; int k;
@ -389,7 +394,7 @@ namespace MathNet.Numerics.Random
/// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks> /// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks>
public static IEnumerable<double> SampleSequence(int seed) public static IEnumerable<double> DoubleSequence(int seed)
{ {
uint[] t = new uint[624]; uint[] t = new uint[624];
int k; int k;

6
src/Numerics/Random/Mrg32k3a.cs

@ -110,7 +110,7 @@ namespace MathNet.Numerics.Random
/// <returns> /// <returns>
/// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
/// </returns> /// </returns>
protected override double DoSample() protected override sealed double DoSample()
{ {
double xn = A12*_xn2 - A13*_xn3; double xn = A12*_xn2 - A13*_xn3;
double k = (long)(xn/Modulus1); double k = (long)(xn/Modulus1);
@ -145,7 +145,7 @@ namespace MathNet.Numerics.Random
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads.</remarks> /// <remarks>Supports being called in parallel from multiple threads.</remarks>
public static double[] Samples(int length, int seed) public static double[] Doubles(int length, int seed)
{ {
double x1 = 1; double x1 = 1;
double x2 = 1; double x2 = 1;
@ -188,7 +188,7 @@ namespace MathNet.Numerics.Random
/// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks> /// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks>
public static IEnumerable<double> SampleSequence(int seed) public static IEnumerable<double> DoubleSequence(int seed)
{ {
double x1 = 1; double x1 = 1;
double x2 = 1; double x2 = 1;

12
src/Numerics/Random/Palf.cs

@ -137,7 +137,7 @@ namespace MathNet.Numerics.Random
LongLag = ((longLag/_threads) + 1)*_threads; LongLag = ((longLag/_threads) + 1)*_threads;
} }
_x = Generate.Map(MersenneTwister.Samples(LongLag, seed), uniform => (uint)(uniform*uint.MaxValue)); _x = Generate.Map(MersenneTwister.Doubles(LongLag, seed), uniform => (uint)(uniform*uint.MaxValue));
_k = LongLag; _k = LongLag;
} }
@ -212,7 +212,7 @@ namespace MathNet.Numerics.Random
/// <returns> /// <returns>
/// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
/// </returns> /// </returns>
protected override double DoSample() protected override sealed double DoSample()
{ {
if (_k >= LongLag) if (_k >= LongLag)
{ {
@ -227,7 +227,7 @@ namespace MathNet.Numerics.Random
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads.</remarks> /// <remarks>Supports being called in parallel from multiple threads.</remarks>
public static double[] Samples(int length, int seed) public static double[] Doubles(int length, int seed)
{ {
if (seed == 0) if (seed == 0)
{ {
@ -244,7 +244,7 @@ namespace MathNet.Numerics.Random
longLag = ((longLag/threads) + 1)*threads; longLag = ((longLag/threads) + 1)*threads;
} }
var x = Generate.Map(MersenneTwister.Samples(longLag, seed), uniform => (uint)(uniform*uint.MaxValue)); var x = Generate.Map(MersenneTwister.Doubles(longLag, seed), uniform => (uint)(uniform*uint.MaxValue));
var k = longLag; var k = longLag;
var data = new double[length]; var data = new double[length];
@ -277,7 +277,7 @@ namespace MathNet.Numerics.Random
/// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks> /// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks>
public static IEnumerable<double> SampleSequence(int seed) public static IEnumerable<double> DoubleSequence(int seed)
{ {
if (seed == 0) if (seed == 0)
{ {
@ -294,7 +294,7 @@ namespace MathNet.Numerics.Random
longLag = ((longLag/threads) + 1)*threads; longLag = ((longLag/threads) + 1)*threads;
} }
var x = Generate.Map(MersenneTwister.Samples(longLag, seed), uniform => (uint)(uniform*uint.MaxValue)); var x = Generate.Map(MersenneTwister.Doubles(longLag, seed), uniform => (uint)(uniform*uint.MaxValue));
var k = longLag; var k = longLag;
while (true) while (true)

116
src/Numerics/Random/RandomExtensions.cs

@ -29,27 +29,111 @@
// </copyright> // </copyright>
using System; using System;
using System.Collections.Generic;
namespace MathNet.Numerics.Random namespace MathNet.Numerics.Random
{ {
/// <summary> /// <summary>
/// This class implements extension methods for the System.Random class. The extension methods generate /// 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. /// pseudo-random distributed numbers for types other than double and int32.
/// </summary> /// </summary>
public static class RandomExtensions public static class RandomExtensions
{ {
/// <summary>
/// Fills an array with uniform random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary>
/// <param name="rnd">The random number generator.</param>
/// <param name="values">The array to fill with random values.</param>
/// <remarks>
/// This extension is thread-safe if and only if called on an random number
/// generator provided by Math.NET Nummerics or derived from the RandomSource class.
/// </remarks>
public static void NextDoubles(this System.Random rnd, double[] values)
{
var rs = rnd as RandomSource;
if (rs != null)
{
rs.NextDoubles(values);
return;
}
for (var i = 0; i < values.Length; i++)
{
values[i] = rnd.NextDouble();
}
}
/// <summary>
/// Returns an array of uniform random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary>
/// <param name="rnd">The random number generator.</param>
/// <param name="count">The size of the array to fill.</param>
/// <remarks>
/// This extension is thread-safe if and only if called on an random number
/// generator provided by Math.NET Nummerics or derived from the RandomSource class.
/// </remarks>
public static double[] NextDoubles(this System.Random rnd, int count)
{
var values = new double[count];
NextDoubles(rnd, values);
return values;
}
/// <summary>
/// Returns an infinite sequence of uniform random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary>
/// <remarks>
/// This extension is thread-safe if and only if called on an random number
/// generator provided by Math.NET Nummerics or derived from the RandomSource class.
/// </remarks>
public static IEnumerable<double> NextDoubleSequence(this System.Random rnd)
{
var rs = rnd as RandomSource;
if (rs != null)
{
return rs.NextDoubleSequence();
}
return NextDoubleSequenceEnumerable(rnd);
}
static IEnumerable<double> NextDoubleSequenceEnumerable(System.Random rnd)
{
while (true)
{
yield return rnd.NextDouble();
}
}
/// <summary>
/// Returns an array of uniform random bytes.
/// </summary>
/// <param name="rnd">The random number generator.</param>
/// <param name="count">The size of the array to fill.</param>
/// <remarks>
/// This extension is thread-safe if and only if called on an random number
/// generator provided by Math.NET Nummerics or derived from the RandomSource class.
/// </remarks>
public static byte[] NextBytes(this System.Random rnd, int count)
{
var values = new byte[count];
rnd.NextBytes(values);
return values;
}
/// <summary> /// <summary>
/// Returns a nonnegative random number less than <see cref="Int64.MaxValue"/>. /// Returns a nonnegative random number less than <see cref="Int64.MaxValue"/>.
/// </summary> /// </summary>
/// <param name="rnd"> /// <param name="rnd">The random number generator.</param>
/// The random object to extend.
/// </param>
/// <returns> /// <returns>
/// A 64-bit signed integer greater than or equal to 0, and less than <see cref="Int64.MaxValue"/>; that is, /// A 64-bit signed integer greater than or equal to 0, and less than <see cref="Int64.MaxValue"/>; that is,
/// the range of return values includes 0 but not <see cref="Int64.MaxValue"/>. /// the range of return values includes 0 but not <see cref="Int64.MaxValue"/>.
/// </returns> /// </returns>
/// <seealso cref="NextFullRangeInt64"/> /// <seealso cref="NextFullRangeInt64"/>
/// <remarks>
/// This extension is thread-safe if and only if called on an random number
/// generator provided by Math.NET Nummerics or derived from the RandomSource class.
/// </remarks>
public static long NextInt64(this System.Random rnd) public static long NextInt64(this System.Random rnd)
{ {
var buffer = new byte[sizeof (long)]; var buffer = new byte[sizeof (long)];
@ -68,14 +152,16 @@ namespace MathNet.Numerics.Random
/// <summary> /// <summary>
/// Returns a random number of the full Int32 range. /// Returns a random number of the full Int32 range.
/// </summary> /// </summary>
/// <param name="rnd"> /// <param name="rnd">The random number generator.</param>
/// The random object to extend.
/// </param>
/// <returns> /// <returns>
/// A 32-bit signed integer of the full range, including 0, negative numbers, /// A 32-bit signed integer of the full range, including 0, negative numbers,
/// <see cref="Int32.MaxValue"/> and <see cref="Int32.MinValue"/>. /// <see cref="Int32.MaxValue"/> and <see cref="Int32.MinValue"/>.
/// </returns> /// </returns>
/// <seealso cref="System.Random.Next()"/> /// <seealso cref="System.Random.Next()"/>
/// <remarks>
/// This extension is thread-safe if and only if called on an random number
/// generator provided by Math.NET Nummerics or derived from the RandomSource class.
/// </remarks>
public static int NextFullRangeInt32(this System.Random rnd) public static int NextFullRangeInt32(this System.Random rnd)
{ {
var buffer = new byte[sizeof (int)]; var buffer = new byte[sizeof (int)];
@ -86,14 +172,16 @@ namespace MathNet.Numerics.Random
/// <summary> /// <summary>
/// Returns a random number of the full Int64 range. /// Returns a random number of the full Int64 range.
/// </summary> /// </summary>
/// <param name="rnd"> /// <param name="rnd">The random number generator.</param>
/// The random object to extend.
/// </param>
/// <returns> /// <returns>
/// A 64-bit signed integer of the full range, including 0, negative numbers, /// A 64-bit signed integer of the full range, including 0, negative numbers,
/// <see cref="Int64.MaxValue"/> and <see cref="Int64.MinValue"/>. /// <see cref="Int64.MaxValue"/> and <see cref="Int64.MinValue"/>.
/// </returns> /// </returns>
/// <seealso cref="NextInt64"/> /// <seealso cref="NextInt64"/>
/// <remarks>
/// This extension is thread-safe if and only if called on an random number
/// generator provided by Math.NET Nummerics or derived from the RandomSource class.
/// </remarks>
public static long NextFullRangeInt64(this System.Random rnd) public static long NextFullRangeInt64(this System.Random rnd)
{ {
var buffer = new byte[sizeof (long)]; var buffer = new byte[sizeof (long)];
@ -104,13 +192,15 @@ namespace MathNet.Numerics.Random
/// <summary> /// <summary>
/// Returns a nonnegative decimal floating point random number less than 1.0. /// Returns a nonnegative decimal floating point random number less than 1.0.
/// </summary> /// </summary>
/// <param name="rnd"> /// <param name="rnd">The random number generator.</param>
/// The random object to extend.
/// </param>
/// <returns> /// <returns>
/// A decimal floating point number greater than or equal to 0.0, and less than 1.0; that is, /// 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. /// the range of return values includes 0.0 but not 1.0.
/// </returns> /// </returns>
/// <remarks>
/// This extension is thread-safe if and only if called on an random number
/// generator provided by Math.NET Nummerics or derived from the RandomSource class.
/// </remarks>
public static decimal NextDecimal(this System.Random rnd) public static decimal NextDecimal(this System.Random rnd)
{ {
decimal candidate; decimal candidate;

27
src/Numerics/Random/RandomSource.cs

@ -66,36 +66,28 @@ namespace MathNet.Numerics.Random
} }
/// <summary> /// <summary>
/// Returns an array of uniform random numbers greater than or equal to 0.0 and less than 1.0. /// Fills an array with uniform random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <param name="n">The size of the array.</param> /// <param name="values">The array to fill with random values.</param>
/// <exception cref="ArgumentException">if n is not greater than 0.</exception> public void NextDoubles(double[] values)
public double[] NextDoubles(int n)
{ {
if (n < 1)
{
throw new ArgumentException(Resources.ArgumentMustBePositive);
}
var ret = new double[n];
if (_threadSafe) if (_threadSafe)
{ {
lock (_lock) lock (_lock)
{ {
for (var i = 0; i < ret.Length; i++) for (var i = 0; i < values.Length; i++)
{ {
ret[i] = DoSample(); values[i] = DoSample();
} }
} }
} }
else else
{ {
for (var i = 0; i < ret.Length; i++) for (var i = 0; i < values.Length; i++)
{ {
ret[i] = DoSample(); values[i] = DoSample();
} }
} }
return ret;
} }
/// <summary> /// <summary>
@ -108,9 +100,10 @@ namespace MathNet.Numerics.Random
yield return NextDouble(); yield return NextDouble();
} }
var buffer = new double[64];
while (true) while (true)
{ {
var buffer = NextDoubles(64); NextDoubles(buffer);
for (int i = 0; i < buffer.Length; i++) for (int i = 0; i < buffer.Length; i++)
{ {
yield return buffer[i]; yield return buffer[i];
@ -222,7 +215,7 @@ namespace MathNet.Numerics.Random
/// Returns a random number between 0.0 and 1.0. /// Returns a random number between 0.0 and 1.0.
/// </summary> /// </summary>
/// <returns>A double-precision floating point number greater than or equal to 0.0, and less than 1.0.</returns> /// <returns>A double-precision floating point number greater than or equal to 0.0, and less than 1.0.</returns>
protected override double Sample() protected override sealed double Sample()
{ {
if (_threadSafe) if (_threadSafe)
{ {

59
src/Numerics/Random/SystemRandomSource.cs

@ -29,9 +29,15 @@
// </copyright> // </copyright>
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using MathNet.Numerics.Threading; using MathNet.Numerics.Threading;
#if PORTABLE
using System;
#else
using System.Runtime;
using System.Threading;
#endif
namespace MathNet.Numerics.Random namespace MathNet.Numerics.Random
{ {
/// <summary> /// <summary>
@ -111,31 +117,42 @@ namespace MathNet.Numerics.Random
/// <returns> /// <returns>
/// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
/// </returns> /// </returns>
protected override double DoSample() protected override sealed double DoSample()
{ {
return _random.NextDouble(); return _random.NextDouble();
} }
/// <summary> /// <summary>
/// Returns an array of uniform random numbers greater than or equal to 0.0 and less than 1.0. /// Fill an array with uniform random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Parallelized on large length, but also supports being called in parallel from multiple threads</remarks> /// <remarks>Parallelized on large length, but also supports being called in parallel from multiple threads</remarks>
public static double[] Samples(int length) public static void Doubles(double[] values)
{ {
if (length < 2048) if (values.Length < 2048)
{ {
return Default.NextDoubles(length); Default.NextDoubles(values);
return;
} }
var data = new double[length]; CommonParallel.For(0, values.Length, values.Length >= 65536 ? 8192 : values.Length >= 16384 ? 2048 : 1024, (a, b) =>
CommonParallel.For(0, length, length >= 65536 ? 8192 : length >= 16384 ? 2048 : 1024, (a, b) =>
{ {
var rnd = new System.Random(RandomSeed.Robust()); var rnd = new System.Random(RandomSeed.Robust());
for (int i = a; i < b; i++) for (int i = a; i < b; i++)
{ {
data[i] = rnd.NextDouble(); values[i] = rnd.NextDouble();
} }
}); });
}
/// <summary>
/// Returns an array of uniform random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary>
/// <remarks>Parallelized on large length, but also supports being called in parallel from multiple threads</remarks>
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public static double[] Doubles(int length)
{
var data = new double[length];
Doubles(data);
return data; return data;
} }
@ -143,7 +160,7 @@ namespace MathNet.Numerics.Random
/// Returns an infinite sequence of uniform random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an infinite sequence of uniform random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks> /// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks>
public static IEnumerable<double> SampleSequence() public static IEnumerable<double> DoubleSequence()
{ {
var rnd1 = Default; var rnd1 = Default;
for (int i = 0; i < 128; i++) for (int i = 0; i < 128; i++)
@ -159,18 +176,28 @@ namespace MathNet.Numerics.Random
} }
/// <summary> /// <summary>
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. /// Fills an array with random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads.</remarks> /// <remarks>Supports being called in parallel from multiple threads.</remarks>
public static double[] Samples(int length, int seed) public static void Doubles(double[] values, int seed)
{ {
var rnd = new System.Random(seed); var rnd = new System.Random(seed);
var data = new double[length]; for (int i = 0; i < values.Length; i++)
for (int i = 0; i < data.Length; i++)
{ {
data[i] = rnd.NextDouble(); values[i] = rnd.NextDouble();
} }
}
/// <summary>
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary>
/// <remarks>Supports being called in parallel from multiple threads.</remarks>
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public static double[] Doubles(int length, int seed)
{
var data = new double[length];
Doubles(data, seed);
return data; return data;
} }
@ -178,7 +205,7 @@ namespace MathNet.Numerics.Random
/// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks> /// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks>
public static IEnumerable<double> SampleSequence(int seed) public static IEnumerable<double> DoubleSequence(int seed)
{ {
var rnd = new System.Random(seed); var rnd = new System.Random(seed);

6
src/Numerics/Random/WH1982.cs

@ -105,7 +105,7 @@ namespace MathNet.Numerics.Random
/// <returns> /// <returns>
/// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
/// </returns> /// </returns>
protected override double DoSample() protected override sealed double DoSample()
{ {
_xn = (171*_xn)%Modx; _xn = (171*_xn)%Modx;
_yn = (172*_yn)%Mody; _yn = (172*_yn)%Mody;
@ -120,7 +120,7 @@ namespace MathNet.Numerics.Random
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads.</remarks> /// <remarks>Supports being called in parallel from multiple threads.</remarks>
public static double[] Samples(int length, int seed) public static double[] Doubles(int length, int seed)
{ {
if (seed == 0) if (seed == 0)
{ {
@ -147,7 +147,7 @@ namespace MathNet.Numerics.Random
/// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks> /// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks>
public static IEnumerable<double> SampleSequence(int seed) public static IEnumerable<double> DoubleSequence(int seed)
{ {
if (seed == 0) if (seed == 0)
{ {

6
src/Numerics/Random/WH2006.cs

@ -107,7 +107,7 @@ namespace MathNet.Numerics.Random
/// <returns> /// <returns>
/// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
/// </returns> /// </returns>
protected override double DoSample() protected override sealed double DoSample()
{ {
_xn = 11600*_xn%Modx; _xn = 11600*_xn%Modx;
_yn = 47003*_yn%Mody; _yn = 47003*_yn%Mody;
@ -123,7 +123,7 @@ namespace MathNet.Numerics.Random
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads.</remarks> /// <remarks>Supports being called in parallel from multiple threads.</remarks>
public static double[] Samples(int length, int seed) public static double[] Doubles(int length, int seed)
{ {
if (seed == 0) if (seed == 0)
{ {
@ -152,7 +152,7 @@ namespace MathNet.Numerics.Random
/// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0. /// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks> /// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks>
public static IEnumerable<double> SampleSequence(int seed) public static IEnumerable<double> DoubleSequence(int seed)
{ {
if (seed == 0) if (seed == 0)
{ {

6
src/Numerics/Random/Xorshift.cs

@ -253,7 +253,7 @@ namespace MathNet.Numerics.Random
/// <returns> /// <returns>
/// A double-precision floating point number greater than or equal to 0.0, and less than 1.0. /// A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
/// </returns> /// </returns>
protected override double DoSample() protected override sealed double DoSample()
{ {
var t = (_a*_x) + _c; var t = (_a*_x) + _c;
_x = _y; _x = _y;
@ -268,7 +268,7 @@ namespace MathNet.Numerics.Random
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads.</remarks> /// <remarks>Supports being called in parallel from multiple threads.</remarks>
[CLSCompliant(false)] [CLSCompliant(false)]
public static double[] Samples(int length, int seed, ulong a = ASeed, ulong c = CSeed, ulong x1 = YSeed, ulong x2 = ZSeed) public static double[] Doubles(int length, int seed, ulong a = ASeed, ulong c = CSeed, ulong x1 = YSeed, ulong x2 = ZSeed)
{ {
if (a <= c) if (a <= c)
{ {
@ -299,7 +299,7 @@ namespace MathNet.Numerics.Random
/// </summary> /// </summary>
/// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks> /// <remarks>Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.</remarks>
[CLSCompliant(false)] [CLSCompliant(false)]
public static IEnumerable<double> SampleSequence(int seed, ulong a = ASeed, ulong c = CSeed, ulong x1 = YSeed, ulong x2 = ZSeed) public static IEnumerable<double> DoubleSequence(int seed, ulong a = ASeed, ulong c = CSeed, ulong x1 = YSeed, ulong x2 = ZSeed)
{ {
if (a <= c) if (a <= c)
{ {

2
src/UnitTests/Random/Mcg31m1Tests.cs

@ -49,7 +49,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test] [Test]
public void StaticSamplesConsistent() public void StaticSamplesConsistent()
{ {
Assert.That(Mcg31m1.Samples(1000, 1), Is.EqualTo(new Mcg31m1(1).NextDoubles(1000)).Within(1e-12).AsCollection); Assert.That(Mcg31m1.Doubles(1000, 1), Is.EqualTo(new Mcg31m1(1).NextDoubles(1000)).Within(1e-12).AsCollection);
} }
} }
} }

2
src/UnitTests/Random/Mcg59Tests.cs

@ -49,7 +49,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test] [Test]
public void StaticSamplesConsistent() public void StaticSamplesConsistent()
{ {
Assert.That(Mcg59.Samples(1000, 1), Is.EqualTo(new Mcg59(1).NextDoubles(1000)).Within(1e-12).AsCollection); Assert.That(Mcg59.Doubles(1000, 1), Is.EqualTo(new Mcg59(1).NextDoubles(1000)).Within(1e-12).AsCollection);
} }
} }
} }

2
src/UnitTests/Random/MersenneTwisterTests.cs

@ -62,7 +62,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test] [Test]
public void StaticSamplesConsistent() public void StaticSamplesConsistent()
{ {
Assert.That(MersenneTwister.Samples(1000, 1), Is.EqualTo(new MersenneTwister(1).NextDoubles(1000)).Within(1e-12).AsCollection); Assert.That(MersenneTwister.Doubles(1000, 1), Is.EqualTo(new MersenneTwister(1).NextDoubles(1000)).Within(1e-12).AsCollection);
} }
} }
} }

2
src/UnitTests/Random/Mrg32k3aTests.cs

@ -49,7 +49,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test] [Test]
public void StaticSamplesConsistent() public void StaticSamplesConsistent()
{ {
Assert.That(Mrg32k3a.Samples(1000, 1), Is.EqualTo(new Mrg32k3a(1).NextDoubles(1000)).Within(1e-12).AsCollection); Assert.That(Mrg32k3a.Doubles(1000, 1), Is.EqualTo(new Mrg32k3a(1).NextDoubles(1000)).Within(1e-12).AsCollection);
} }
} }
} }

2
src/UnitTests/Random/PalfTests.cs

@ -68,7 +68,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test] [Test]
public void StaticSamplesConsistent() public void StaticSamplesConsistent()
{ {
Assert.That(Palf.Samples(1000, 1), Is.EqualTo(new Palf(1).NextDoubles(1000)).Within(1e-12).AsCollection); Assert.That(Palf.Doubles(1000, 1), Is.EqualTo(new Palf(1).NextDoubles(1000)).Within(1e-12).AsCollection);
} }
} }
} }

2
src/UnitTests/Random/SystemRandomSourceTests.cs

@ -46,7 +46,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test] [Test]
public void StaticSamplesConsistent() public void StaticSamplesConsistent()
{ {
Assert.That(SystemRandomSource.Samples(1000, 1), Is.EqualTo(new SystemRandomSource(1).NextDoubles(1000)).Within(1e-12).AsCollection); Assert.That(SystemRandomSource.Doubles(1000, 1), Is.EqualTo(new SystemRandomSource(1).NextDoubles(1000)).Within(1e-12).AsCollection);
} }
} }
} }

2
src/UnitTests/Random/WH1982Tests.cs

@ -49,7 +49,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test] [Test]
public void StaticSamplesConsistent() public void StaticSamplesConsistent()
{ {
Assert.That(WH1982.Samples(1000, 1), Is.EqualTo(new WH1982(1).NextDoubles(1000)).Within(1e-12).AsCollection); Assert.That(WH1982.Doubles(1000, 1), Is.EqualTo(new WH1982(1).NextDoubles(1000)).Within(1e-12).AsCollection);
} }
} }
} }

2
src/UnitTests/Random/WH2006Tests.cs

@ -49,7 +49,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test] [Test]
public void StaticSamplesConsistent() public void StaticSamplesConsistent()
{ {
Assert.That(WH2006.Samples(1000, 1), Is.EqualTo(new WH2006(1).NextDoubles(1000)).Within(1e-12).AsCollection); Assert.That(WH2006.Doubles(1000, 1), Is.EqualTo(new WH2006(1).NextDoubles(1000)).Within(1e-12).AsCollection);
} }
} }
} }

2
src/UnitTests/Random/XorshiftTests.cs

@ -49,7 +49,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test] [Test]
public void StaticSamplesConsistent() public void StaticSamplesConsistent()
{ {
Assert.That(Xorshift.Samples(1000, 1), Is.EqualTo(new Xorshift(1).NextDoubles(1000)).Within(1e-12).AsCollection); Assert.That(Xorshift.Doubles(1000, 1), Is.EqualTo(new Xorshift(1).NextDoubles(1000)).Within(1e-12).AsCollection);
} }
} }
} }

Loading…
Cancel
Save