diff --git a/src/FSharp/Random.fs b/src/FSharp/Random.fs
index f6253d2d..24ee548e 100644
--- a/src/FSharp/Random.fs
+++ b/src/FSharp/Random.fs
@@ -37,78 +37,67 @@ module Random =
let shared = SystemRandomSource.Default :> System.Random
/// Default sampling, efficient but without custom seed (uses robust seeds internally)
- let samples length = SystemRandomSource.Samples(length)
- let sampleSeq () = SystemRandomSource.SampleSequence()
+ let inline doubles (length:int) = SystemRandomSource.Doubles(length)
+ 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 system () = new SystemRandomSource() :> System.Random
- let systemSeed (seed:int) = new SystemRandomSource(seed) :> System.Random
- let systemSamples (seed:int) length = SystemRandomSource.Samples(length, seed)
- let systemSampleSeq (seed:int) = SystemRandomSource.SampleSequence(seed)
+ let inline doublesSeed (seed:int) (length:int) = SystemRandomSource.Doubles(length, seed)
+ let inline doubleSeqSeed (seed:int) = SystemRandomSource.DoubleSequence(seed)
+ let inline doubleFillSeed (seed:int) (values:double[]) = SystemRandomSource.Doubles(values, 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
#else
/// Creates a default .Net cryptographic system pRNG
- let crypto () = new CryptoRandomSource() :> System.Random
- let cryptoWith (threadSafe:bool) = new CryptoRandomSource(threadSafe) :> System.Random
- let cryptoSamples length = CryptoRandomSource.Samples(length)
- let cryptoSampleSeq () = CryptoRandomSource.SampleSequence()
+ let inline crypto () = new CryptoRandomSource() :> System.Random
+ let inline cryptoWith (threadSafe:bool) = new CryptoRandomSource(threadSafe) :> System.Random
+ let inline cryptoDoubles length = CryptoRandomSource.Doubles(length)
+ let inline cryptoDoubleSeq () = CryptoRandomSource.DoubleSequence()
#endif
- /// Creates a Mersenne Twister 19937 pRNG with a custom seed based on uinque GUIDs
- let mersenneTwister () = new MersenneTwister() :> System.Random
- let mersenneTwisterSeed (seed:int) = new MersenneTwister(seed) :> System.Random
- let mersenneTwisterWith seed threadSafe = new MersenneTwister(seed, threadSafe) :> System.Random
- let mersenneTwisterSamples (seed:int) length = MersenneTwister.Samples(length, seed)
- let mersenneTwisterSampleSeq (seed:int) = MersenneTwister.SampleSequence(seed)
+ /// Creates a Mersenne Twister 19937 pRNG with a robust seed
+ let mersenneTwisterShared = MersenneTwister.Default :> System.Random
+ let inline mersenneTwister () = MersenneTwister() :> System.Random
+ let inline mersenneTwisterSeed (seed:int) = MersenneTwister(seed) :> System.Random
+ let inline mersenneTwisterWith (seed:int) threadSafe = MersenneTwister(seed, threadSafe) :> System.Random
- /// Creates a multiply-with-carry Xorshift (Xn = a * Xn−3 + c mod 2^32) pRNG with a custom seed based on uinque GUIDs
- let xorshift () = new Xorshift() :> System.Random
- let xorshiftSeed (seed:int) = new Xorshift(seed) :> System.Random
- let xorshiftWith seed threadSafe = new Xorshift(seed, threadSafe) :> System.Random
- let xorshiftCustom seed threadSafe a c x1 x2 = new 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 multiply-with-carry Xorshift (Xn = a * Xn−3 + c mod 2^32) pRNG with a robust seed
+ let inline xorshift () = Xorshift() :> System.Random
+ let inline xorshiftSeed (seed:int) = Xorshift(seed) :> System.Random
+ let inline xorshiftWith (seed:int) threadSafe = Xorshift(seed, threadSafe) :> System.Random
+ let inline xorshiftCustom (seed:int) threadSafe a c x1 x2 = Xorshift(seed, threadSafe, a, c, x1, x2) :> System.Random
- /// Creates a Wichmann-Hill’s 1982 combined multiplicative congruential pRNG with a custom seed based on uinque GUIDs
- let wh1982 () = new WH1982() :> System.Random
- let wh1982Seed (seed:int) = new WH1982(seed) :> System.Random
- let wh1982With seed threadSafe = new 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 1982 combined multiplicative congruential pRNG with a robust seed
+ let inline wh1982 () = WH1982() :> System.Random
+ let inline wh1982Seed (seed:int) = WH1982(seed) :> System.Random
+ let inline wh1982With (seed:int) threadSafe = WH1982(seed, threadSafe) :> System.Random
- /// Creates a Wichmann-Hill’s 2006 combined multiplicative congruential pRNG with a custom seed based on uinque GUIDs
- let wh2006 () = new WH2006() :> System.Random
- let wh2006Seed (seed:int) = new WH2006(seed) :> System.Random
- let wh2006With seed threadSafe = new WH2006(seed, threadSafe) :> System.Random
- let wh2006Samples (seed:int) length = WH2006.Samples(length, seed)
- let wh2006SampleSeq (seed:int) = WH2006.SampleSequence(seed)
+ /// Creates a Wichmann-Hill’s 2006 combined multiplicative congruential pRNG with a robust seed
+ let inline wh2006 () = WH2006() :> System.Random
+ let inline wh2006Seed (seed:int) = WH2006(seed) :> System.Random
+ let inline wh2006With (seed:int) threadSafe = WH2006(seed, threadSafe) :> System.Random
- /// Creates a Parallel Additive Lagged Fibonacci pRNG with a custom seed based on uinque GUIDs
- let palf () = new Palf() :> System.Random
- let palfSeed (seed:int) = new Palf(seed) :> System.Random
- let palfWith seed threadSafe = new Palf(seed, threadSafe, 418, 1279) :> System.Random
- let palfCustom seed threadSafe shortLag longLag = new 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 Parallel Additive Lagged Fibonacci pRNG with a robust seed
+ let inline palf () = Palf() :> System.Random
+ let inline palfSeed (seed:int) = Palf(seed) :> System.Random
+ let inline palfWith (seed:int) threadSafe = Palf(seed, threadSafe, 418, 1279) :> System.Random
+ let inline palfCustom (seed:int) threadSafe shortLag longLag = Palf(seed, threadSafe, shortLag, longLag) :> System.Random
- /// 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
- let mcg59 () = new Mcg59() :> System.Random
- let mcg59Seed (seed:int) = new Mcg59(seed) :> System.Random
- let mcg59With seed threadSafe = new 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^59 and a multiplier of 13^13 pRNG with a robust seed
+ let inline mcg59 () = Mcg59() :> System.Random
+ let inline mcg59Seed (seed:int) = Mcg59(seed) :> System.Random
+ let inline mcg59With (seed:int) threadSafe = Mcg59(seed, threadSafe) :> System.Random
- /// 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
- let mcg31m1 () = new Mcg31m1() :> System.Random
- let mcg31m1Seed (seed:int) = new Mcg31m1(seed) :> System.Random
- let mcg31m1With seed threadSafe = new Mcg31m1(seed, threadSafe) :> System.Random
- let mcg31m1Samples (seed:int) length = Mcg31m1.Samples(length, seed)
- let mcg31m1SampleSeq (seed:int) = Mcg31m1.SampleSequence(seed)
+ /// Creates a Multiplicative congruential generator using a modulus of 2^31-1 and a multiplier of 1132489760 pRNG with a robust seed
+ let inline mcg31m1 () = Mcg31m1() :> System.Random
+ let inline mcg31m1Seed (seed:int) = Mcg31m1(seed) :> System.Random
+ let inline mcg31m1With (seed:int) threadSafe = Mcg31m1(seed, threadSafe) :> System.Random
- /// Creates a 32-bit combined multiple recursive generator with 2 components of order 3 pRNG with a custom seed based on uinque GUIDs
- let mrg32k3a () = new Mrg32k3a() :> System.Random
- let mrg32k3aSeed (seed:int) = new Mrg32k3a(seed) :> System.Random
- let mrg32k3aWith seed threadSafe = new Mrg32k3a(seed, threadSafe) :> System.Random
- let mrg32k3aSamples (seed:int) length = Mrg32k3a.Samples(length, seed)
- let mrg32k3aSampleSeq (seed:int) = Mrg32k3a.SampleSequence(seed)
+ /// Creates a 32-bit combined multiple recursive generator with 2 components of order 3 pRNG with a robust seed
+ let inline mrg32k3a () = Mrg32k3a() :> System.Random
+ let inline mrg32k3aSeed (seed:int) = Mrg32k3a(seed) :> System.Random
+ let inline mrg32k3aWith (seed:int) threadSafe = Mrg32k3a(seed, threadSafe) :> System.Random
diff --git a/src/Numerics/Random/CryptoRandomSource.cs b/src/Numerics/Random/CryptoRandomSource.cs
index 8bc864b9..86389ee8 100644
--- a/src/Numerics/Random/CryptoRandomSource.cs
+++ b/src/Numerics/Random/CryptoRandomSource.cs
@@ -92,7 +92,7 @@ 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 DoSample()
+ protected override sealed double DoSample()
{
var bytes = new byte[4];
_crypto.GetBytes(bytes);
@@ -109,7 +109,7 @@ namespace MathNet.Numerics.Random
///
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
///
- public static double[] Samples(int length)
+ public static double[] Doubles(int length)
{
var rnd = new RNGCryptoServiceProvider();
var bytes = new byte[length*4];
@@ -125,7 +125,7 @@ namespace MathNet.Numerics.Random
///
/// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0.
///
- public static IEnumerable SampleSequence()
+ public static IEnumerable DoubleSequence()
{
var rnd = new RNGCryptoServiceProvider();
var buffer = new byte[1024*4];
diff --git a/src/Numerics/Random/Mcg31m1.cs b/src/Numerics/Random/Mcg31m1.cs
index d169672d..b363a74e 100644
--- a/src/Numerics/Random/Mcg31m1.cs
+++ b/src/Numerics/Random/Mcg31m1.cs
@@ -95,7 +95,7 @@ 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 DoSample()
+ protected override sealed double DoSample()
{
double ret = _xn*Reciprocal;
_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.
///
/// Supports being called in parallel from multiple threads.
- public static double[] Samples(int length, int seed)
+ public static double[] Doubles(int length, int seed)
{
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.
///
/// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.
- public static IEnumerable SampleSequence(int seed)
+ public static IEnumerable DoubleSequence(int seed)
{
if (seed == 0)
{
diff --git a/src/Numerics/Random/Mcg59.cs b/src/Numerics/Random/Mcg59.cs
index 5449be1b..f78eff5f 100644
--- a/src/Numerics/Random/Mcg59.cs
+++ b/src/Numerics/Random/Mcg59.cs
@@ -37,9 +37,9 @@ namespace MathNet.Numerics.Random
///
public class Mcg59 : RandomSource
{
- const double Reciprocal = 1.0/Modulus;
const ulong Modulus = 576460752303423488;
const ulong Multiplier = 302875106592253;
+ const double Reciprocal = 1.0/Modulus;
ulong _xn;
///
@@ -97,7 +97,7 @@ 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 DoSample()
+ protected override sealed double DoSample()
{
double ret = _xn*Reciprocal;
_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.
///
/// Supports being called in parallel from multiple threads.
- public static double[] Samples(int length, int seed)
+ public static double[] Doubles(int length, int seed)
{
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.
///
/// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.
- public static IEnumerable SampleSequence(int seed)
+ public static IEnumerable DoubleSequence(int seed)
{
if (seed == 0)
{
diff --git a/src/Numerics/Random/MersenneTwister.cs b/src/Numerics/Random/MersenneTwister.cs
index 19457160..a26477b2 100644
--- a/src/Numerics/Random/MersenneTwister.cs
+++ b/src/Numerics/Random/MersenneTwister.cs
@@ -67,7 +67,12 @@
*/
using System.Collections.Generic;
+
+#if PORTABLE
+using System;
+#else
using System.Threading;
+#endif
namespace MathNet.Numerics.Random
{
@@ -316,7 +321,7 @@ 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 DoSample()
+ protected override sealed double DoSample()
{
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.
///
/// Supports being called in parallel from multiple threads.
- public static double[] Samples(int length, int seed)
+ public static double[] Doubles(int length, int seed)
{
uint[] t = new uint[624];
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.
///
/// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.
- public static IEnumerable SampleSequence(int seed)
+ public static IEnumerable DoubleSequence(int seed)
{
uint[] t = new uint[624];
int k;
diff --git a/src/Numerics/Random/Mrg32k3a.cs b/src/Numerics/Random/Mrg32k3a.cs
index 8c682335..fa80cf77 100644
--- a/src/Numerics/Random/Mrg32k3a.cs
+++ b/src/Numerics/Random/Mrg32k3a.cs
@@ -110,7 +110,7 @@ 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 DoSample()
+ protected override sealed double DoSample()
{
double xn = A12*_xn2 - A13*_xn3;
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.
///
/// Supports being called in parallel from multiple threads.
- public static double[] Samples(int length, int seed)
+ public static double[] Doubles(int length, int seed)
{
double x1 = 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.
///
/// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.
- public static IEnumerable SampleSequence(int seed)
+ public static IEnumerable DoubleSequence(int seed)
{
double x1 = 1;
double x2 = 1;
diff --git a/src/Numerics/Random/Palf.cs b/src/Numerics/Random/Palf.cs
index 40bed9c2..635d98f1 100644
--- a/src/Numerics/Random/Palf.cs
+++ b/src/Numerics/Random/Palf.cs
@@ -137,7 +137,7 @@ namespace MathNet.Numerics.Random
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;
}
@@ -212,7 +212,7 @@ 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 DoSample()
+ protected override sealed double DoSample()
{
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.
///
/// Supports being called in parallel from multiple threads.
- public static double[] Samples(int length, int seed)
+ public static double[] Doubles(int length, int seed)
{
if (seed == 0)
{
@@ -244,7 +244,7 @@ namespace MathNet.Numerics.Random
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 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.
///
/// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.
- public static IEnumerable SampleSequence(int seed)
+ public static IEnumerable DoubleSequence(int seed)
{
if (seed == 0)
{
@@ -294,7 +294,7 @@ namespace MathNet.Numerics.Random
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;
while (true)
diff --git a/src/Numerics/Random/RandomExtensions.cs b/src/Numerics/Random/RandomExtensions.cs
index 7d75253e..45398c01 100644
--- a/src/Numerics/Random/RandomExtensions.cs
+++ b/src/Numerics/Random/RandomExtensions.cs
@@ -29,27 +29,111 @@
//
using System;
+using System.Collections.Generic;
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 RandomExtensions
{
+ ///
+ /// Fills an array with uniform random numbers greater than or equal to 0.0 and less than 1.0.
+ ///
+ /// The random number generator.
+ /// The array to fill with random values.
+ ///
+ /// 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.
+ ///
+ 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();
+ }
+ }
+
+ ///
+ /// Returns an array of uniform random numbers greater than or equal to 0.0 and less than 1.0.
+ ///
+ /// The random number generator.
+ /// The size of the array to fill.
+ ///
+ /// 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.
+ ///
+ public static double[] NextDoubles(this System.Random rnd, int count)
+ {
+ var values = new double[count];
+ NextDoubles(rnd, values);
+ return values;
+ }
+
+ ///
+ /// Returns an infinite sequence of uniform random numbers greater than or equal to 0.0 and less than 1.0.
+ ///
+ ///
+ /// 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.
+ ///
+ public static IEnumerable NextDoubleSequence(this System.Random rnd)
+ {
+ var rs = rnd as RandomSource;
+ if (rs != null)
+ {
+ return rs.NextDoubleSequence();
+ }
+
+ return NextDoubleSequenceEnumerable(rnd);
+ }
+
+ static IEnumerable NextDoubleSequenceEnumerable(System.Random rnd)
+ {
+ while (true)
+ {
+ yield return rnd.NextDouble();
+ }
+ }
+
+ ///
+ /// Returns an array of uniform random bytes.
+ ///
+ /// The random number generator.
+ /// The size of the array to fill.
+ ///
+ /// 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.
+ ///
+ public static byte[] NextBytes(this System.Random rnd, int count)
+ {
+ var values = new byte[count];
+ rnd.NextBytes(values);
+ return values;
+ }
+
///
/// Returns a nonnegative random number less than .
///
- ///
- /// The random object to extend.
- ///
+ /// The random number generator.
///
/// A 64-bit signed integer greater than or equal to 0, and less than ; that is,
/// the range of return values includes 0 but not .
///
///
+ ///
+ /// 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.
+ ///
public static long NextInt64(this System.Random rnd)
{
var buffer = new byte[sizeof (long)];
@@ -68,14 +152,16 @@ namespace MathNet.Numerics.Random
///
/// Returns a random number of the full Int32 range.
///
- ///
- /// The random object to extend.
- ///
+ /// The random number generator.
///
/// A 32-bit signed integer of the full range, including 0, negative numbers,
/// and .
///
///
+ ///
+ /// 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.
+ ///
public static int NextFullRangeInt32(this System.Random rnd)
{
var buffer = new byte[sizeof (int)];
@@ -86,14 +172,16 @@ namespace MathNet.Numerics.Random
///
/// Returns a random number of the full Int64 range.
///
- ///
- /// The random object to extend.
- ///
+ /// The random number generator.
///
/// A 64-bit signed integer of the full range, including 0, negative numbers,
/// and .
///
///
+ ///
+ /// 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.
+ ///
public static long NextFullRangeInt64(this System.Random rnd)
{
var buffer = new byte[sizeof (long)];
@@ -104,13 +192,15 @@ namespace MathNet.Numerics.Random
///
/// Returns a nonnegative decimal floating point random number less than 1.0.
///
- ///
- /// The random object to extend.
- ///
+ /// The random number generator.
///
/// 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.
///
+ ///
+ /// 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.
+ ///
public static decimal NextDecimal(this System.Random rnd)
{
decimal candidate;
diff --git a/src/Numerics/Random/RandomSource.cs b/src/Numerics/Random/RandomSource.cs
index 24830e8d..3f614ac1 100644
--- a/src/Numerics/Random/RandomSource.cs
+++ b/src/Numerics/Random/RandomSource.cs
@@ -66,36 +66,28 @@ namespace MathNet.Numerics.Random
}
///
- /// 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.
///
- /// The size of the array.
- /// if n is not greater than 0.
- public double[] NextDoubles(int n)
+ /// The array to fill with random values.
+ public void NextDoubles(double[] values)
{
- if (n < 1)
- {
- throw new ArgumentException(Resources.ArgumentMustBePositive);
- }
-
- var ret = new double[n];
if (_threadSafe)
{
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
{
- for (var i = 0; i < ret.Length; i++)
+ for (var i = 0; i < values.Length; i++)
{
- ret[i] = DoSample();
+ values[i] = DoSample();
}
}
- return ret;
}
///
@@ -108,9 +100,10 @@ namespace MathNet.Numerics.Random
yield return NextDouble();
}
+ var buffer = new double[64];
while (true)
{
- var buffer = NextDoubles(64);
+ NextDoubles(buffer);
for (int i = 0; i < buffer.Length; i++)
{
yield return buffer[i];
@@ -222,7 +215,7 @@ namespace MathNet.Numerics.Random
/// 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.
- protected override double Sample()
+ protected override sealed double Sample()
{
if (_threadSafe)
{
diff --git a/src/Numerics/Random/SystemRandomSource.cs b/src/Numerics/Random/SystemRandomSource.cs
index 4f80f336..fb9c9804 100644
--- a/src/Numerics/Random/SystemRandomSource.cs
+++ b/src/Numerics/Random/SystemRandomSource.cs
@@ -29,9 +29,15 @@
//
using System.Collections.Generic;
-using System.Threading;
using MathNet.Numerics.Threading;
+#if PORTABLE
+using System;
+#else
+using System.Runtime;
+using System.Threading;
+#endif
+
namespace MathNet.Numerics.Random
{
///
@@ -111,31 +117,42 @@ 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 DoSample()
+ protected override sealed double DoSample()
{
return _random.NextDouble();
}
///
- /// 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.
///
/// Parallelized on large length, but also supports being called in parallel from multiple threads
- 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, length, length >= 65536 ? 8192 : length >= 16384 ? 2048 : 1024, (a, b) =>
+ CommonParallel.For(0, values.Length, values.Length >= 65536 ? 8192 : values.Length >= 16384 ? 2048 : 1024, (a, b) =>
{
var rnd = new System.Random(RandomSeed.Robust());
for (int i = a; i < b; i++)
{
- data[i] = rnd.NextDouble();
+ values[i] = rnd.NextDouble();
}
});
+ }
+
+ ///
+ /// Returns an array of uniform random numbers greater than or equal to 0.0 and less than 1.0.
+ ///
+ /// Parallelized on large length, but also supports being called in parallel from multiple threads
+ [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;
}
@@ -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.
///
/// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.
- public static IEnumerable SampleSequence()
+ public static IEnumerable DoubleSequence()
{
var rnd1 = Default;
for (int i = 0; i < 128; i++)
@@ -159,18 +176,28 @@ namespace MathNet.Numerics.Random
}
///
- /// 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.
///
/// Supports being called in parallel from multiple threads.
- public static double[] Samples(int length, int seed)
+ public static void Doubles(double[] values, int seed)
{
var rnd = new System.Random(seed);
- var data = new double[length];
- for (int i = 0; i < data.Length; i++)
+ for (int i = 0; i < values.Length; i++)
{
- data[i] = rnd.NextDouble();
+ values[i] = rnd.NextDouble();
}
+ }
+
+ ///
+ /// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
+ ///
+ /// Supports being called in parallel from multiple threads.
+ [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;
}
@@ -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.
///
/// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.
- public static IEnumerable SampleSequence(int seed)
+ public static IEnumerable DoubleSequence(int seed)
{
var rnd = new System.Random(seed);
diff --git a/src/Numerics/Random/WH1982.cs b/src/Numerics/Random/WH1982.cs
index abcc74fe..d35bc3b8 100644
--- a/src/Numerics/Random/WH1982.cs
+++ b/src/Numerics/Random/WH1982.cs
@@ -105,7 +105,7 @@ 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 DoSample()
+ protected override sealed double DoSample()
{
_xn = (171*_xn)%Modx;
_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.
///
/// Supports being called in parallel from multiple threads.
- public static double[] Samples(int length, int seed)
+ public static double[] Doubles(int length, int seed)
{
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.
///
/// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.
- public static IEnumerable SampleSequence(int seed)
+ public static IEnumerable DoubleSequence(int seed)
{
if (seed == 0)
{
diff --git a/src/Numerics/Random/WH2006.cs b/src/Numerics/Random/WH2006.cs
index 376e63c5..6cd0ad70 100644
--- a/src/Numerics/Random/WH2006.cs
+++ b/src/Numerics/Random/WH2006.cs
@@ -107,7 +107,7 @@ 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 DoSample()
+ protected override sealed double DoSample()
{
_xn = 11600*_xn%Modx;
_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.
///
/// Supports being called in parallel from multiple threads.
- public static double[] Samples(int length, int seed)
+ public static double[] Doubles(int length, int seed)
{
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.
///
/// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.
- public static IEnumerable SampleSequence(int seed)
+ public static IEnumerable DoubleSequence(int seed)
{
if (seed == 0)
{
diff --git a/src/Numerics/Random/Xorshift.cs b/src/Numerics/Random/Xorshift.cs
index cf02bff1..46133ca0 100644
--- a/src/Numerics/Random/Xorshift.cs
+++ b/src/Numerics/Random/Xorshift.cs
@@ -253,7 +253,7 @@ 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 DoSample()
+ protected override sealed double DoSample()
{
var t = (_a*_x) + _c;
_x = _y;
@@ -268,7 +268,7 @@ namespace MathNet.Numerics.Random
///
/// Supports being called in parallel from multiple threads.
[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)
{
@@ -299,7 +299,7 @@ namespace MathNet.Numerics.Random
///
/// Supports being called in parallel from multiple threads, but the result must be enumerated from a single thread each.
[CLSCompliant(false)]
- public static IEnumerable SampleSequence(int seed, ulong a = ASeed, ulong c = CSeed, ulong x1 = YSeed, ulong x2 = ZSeed)
+ public static IEnumerable DoubleSequence(int seed, ulong a = ASeed, ulong c = CSeed, ulong x1 = YSeed, ulong x2 = ZSeed)
{
if (a <= c)
{
diff --git a/src/UnitTests/Random/Mcg31m1Tests.cs b/src/UnitTests/Random/Mcg31m1Tests.cs
index 9302d041..27782bdb 100644
--- a/src/UnitTests/Random/Mcg31m1Tests.cs
+++ b/src/UnitTests/Random/Mcg31m1Tests.cs
@@ -49,7 +49,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test]
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);
}
}
}
diff --git a/src/UnitTests/Random/Mcg59Tests.cs b/src/UnitTests/Random/Mcg59Tests.cs
index 703958c4..dc433270 100644
--- a/src/UnitTests/Random/Mcg59Tests.cs
+++ b/src/UnitTests/Random/Mcg59Tests.cs
@@ -49,7 +49,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test]
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);
}
}
}
diff --git a/src/UnitTests/Random/MersenneTwisterTests.cs b/src/UnitTests/Random/MersenneTwisterTests.cs
index 4847df84..1a41bd07 100644
--- a/src/UnitTests/Random/MersenneTwisterTests.cs
+++ b/src/UnitTests/Random/MersenneTwisterTests.cs
@@ -62,7 +62,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test]
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);
}
}
}
diff --git a/src/UnitTests/Random/Mrg32k3aTests.cs b/src/UnitTests/Random/Mrg32k3aTests.cs
index 0ec26f19..5e6580b4 100644
--- a/src/UnitTests/Random/Mrg32k3aTests.cs
+++ b/src/UnitTests/Random/Mrg32k3aTests.cs
@@ -49,7 +49,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test]
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);
}
}
}
diff --git a/src/UnitTests/Random/PalfTests.cs b/src/UnitTests/Random/PalfTests.cs
index 2f8b9b0b..bf0147d1 100644
--- a/src/UnitTests/Random/PalfTests.cs
+++ b/src/UnitTests/Random/PalfTests.cs
@@ -68,7 +68,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test]
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);
}
}
}
diff --git a/src/UnitTests/Random/SystemRandomSourceTests.cs b/src/UnitTests/Random/SystemRandomSourceTests.cs
index f0ca3ee5..009560bb 100644
--- a/src/UnitTests/Random/SystemRandomSourceTests.cs
+++ b/src/UnitTests/Random/SystemRandomSourceTests.cs
@@ -46,7 +46,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test]
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);
}
}
}
diff --git a/src/UnitTests/Random/WH1982Tests.cs b/src/UnitTests/Random/WH1982Tests.cs
index d65537e1..a68321c4 100644
--- a/src/UnitTests/Random/WH1982Tests.cs
+++ b/src/UnitTests/Random/WH1982Tests.cs
@@ -49,7 +49,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test]
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);
}
}
}
diff --git a/src/UnitTests/Random/WH2006Tests.cs b/src/UnitTests/Random/WH2006Tests.cs
index 6c91d20a..6e40f506 100644
--- a/src/UnitTests/Random/WH2006Tests.cs
+++ b/src/UnitTests/Random/WH2006Tests.cs
@@ -49,7 +49,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test]
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);
}
}
}
diff --git a/src/UnitTests/Random/XorshiftTests.cs b/src/UnitTests/Random/XorshiftTests.cs
index ed220177..c4a9ae95 100644
--- a/src/UnitTests/Random/XorshiftTests.cs
+++ b/src/UnitTests/Random/XorshiftTests.cs
@@ -49,7 +49,7 @@ namespace MathNet.Numerics.UnitTests.Random
[Test]
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);
}
}
}