Browse Source

Random: all RNGs must provide static Sample(values) function to fill existing array

provider
Christoph Ruegg 13 years ago
parent
commit
0aef2d4694
  1. 2
      src/FSharp/Random.fs
  2. 32
      src/Numerics/Random/CryptoRandomSource.cs
  3. 26
      src/Numerics/Random/Mcg31m1.cs
  4. 24
      src/Numerics/Random/Mcg59.cs
  5. 26
      src/Numerics/Random/Mrg32k3a.cs
  6. 26
      src/Numerics/Random/Palf.cs
  7. 2
      src/Numerics/Random/SystemRandomSource.cs
  8. 26
      src/Numerics/Random/WH1982.cs
  9. 26
      src/Numerics/Random/WH2006.cs
  10. 27
      src/Numerics/Random/Xorshift.cs

2
src/FSharp/Random.fs

@ -55,7 +55,7 @@ module Random =
/// Creates a default .Net cryptographic system pRNG
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 cryptoDoubles (length:int) = CryptoRandomSource.Doubles(length)
let inline cryptoDoubleSeq () = CryptoRandomSource.DoubleSequence()
#endif

32
src/Numerics/Random/CryptoRandomSource.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -28,11 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System.Collections.Generic;
#if !PORTABLE
using System;
using System.Collections.Generic;
using System.Runtime;
using System.Security.Cryptography;
namespace MathNet.Numerics.Random
@ -48,7 +48,7 @@ namespace MathNet.Numerics.Random
/// <summary>
/// Construct a new random number generator with a random seed.
/// </summary>
/// <remarks>Uses <see cref="System.Security.Cryptography.RNGCryptoServiceProvider"/> and uses the value of
/// <remarks>Uses <see cref="System.Security.Cryptography.RNGCryptoServiceProvider"/> and uses the value of
/// <see cref="Control.ThreadSafeRandomNumberGenerators"/> to set whether the instance is thread safe.</remarks>
public CryptoRandomSource()
{
@ -107,24 +107,36 @@ namespace MathNet.Numerics.Random
}
/// <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>
public static double[] Doubles(int length)
/// <remarks>Supports being called in parallel from multiple threads.</remarks>
public static void Doubles(double[] values)
{
var rnd = new RNGCryptoServiceProvider();
var bytes = new byte[length*4];
var bytes = new byte[values.Length*4];
rnd.GetBytes(bytes);
var data = new double[length];
for (int i = 0; i < data.Length; i++)
for (int i = 0; i < values.Length; i++)
{
data[i] = BitConverter.ToUInt32(bytes, i*4)*Reciprocal;
values[i] = BitConverter.ToUInt32(bytes, i*4)*Reciprocal;
}
}
/// <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)
{
var data = new double[length];
Doubles(data);
return data;
}
/// <summary>
/// Returns an infinite sequence 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>
public static IEnumerable<double> DoubleSequence()
{
var rnd = new RNGCryptoServiceProvider();

26
src/Numerics/Random/Mcg31m1.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -30,6 +30,10 @@
using System.Collections.Generic;
#if !PORTABLE
using System.Runtime;
#endif
namespace MathNet.Numerics.Random
{
/// <summary>
@ -103,10 +107,10 @@ namespace MathNet.Numerics.Random
}
/// <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>
/// <remarks>Supports being called in parallel from multiple threads.</remarks>
public static double[] Doubles(int length, int seed)
public static void Doubles(double[] values, int seed)
{
if (seed == 0)
{
@ -114,12 +118,22 @@ namespace MathNet.Numerics.Random
}
ulong xn = (uint)seed%Modulus;
var data = new double[length];
for (int i = 0; i < data.Length; i++)
for (int i = 0; i < values.Length; i++)
{
data[i] = xn*Reciprocal;
values[i] = xn*Reciprocal;
xn = (xn*Multiplier)%Modulus;
}
}
/// <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;
}

24
src/Numerics/Random/Mcg59.cs

@ -30,6 +30,10 @@
using System.Collections.Generic;
#if !PORTABLE
using System.Runtime;
#endif
namespace MathNet.Numerics.Random
{
/// <summary>
@ -105,10 +109,10 @@ namespace MathNet.Numerics.Random
}
/// <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>
/// <remarks>Supports being called in parallel from multiple threads.</remarks>
public static double[] Doubles(int length, int seed)
public static void Doubles(double[] values, int seed)
{
if (seed == 0)
{
@ -116,12 +120,22 @@ namespace MathNet.Numerics.Random
}
ulong xn = (uint)seed%Modulus;
var data = new double[length];
for (int i = 0; i < data.Length; i++)
for (int i = 0; i < values.Length; i++)
{
data[i] = xn*Reciprocal;
values[i] = xn*Reciprocal;
xn = (xn*Multiplier)%Modulus;
}
}
/// <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;
}

26
src/Numerics/Random/Mrg32k3a.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -30,6 +30,10 @@
using System.Collections.Generic;
#if !PORTABLE
using System.Runtime;
#endif
namespace MathNet.Numerics.Random
{
/// <summary>
@ -142,10 +146,10 @@ namespace MathNet.Numerics.Random
}
/// <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>
/// <remarks>Supports being called in parallel from multiple threads.</remarks>
public static double[] Doubles(int length, int seed)
public static void Doubles(double[] values, int seed)
{
double x1 = 1;
double x2 = 1;
@ -154,8 +158,7 @@ namespace MathNet.Numerics.Random
double y2 = 1;
double y3 = 1;
var data = new double[length];
for (int i = 0; i < data.Length; i++)
for (int i = 0; i < values.Length; i++)
{
double xn = A12*x2 - A13*x3;
double k = (long)(xn/Modulus1);
@ -179,8 +182,19 @@ namespace MathNet.Numerics.Random
y2 = y1;
y1 = yn;
data[i] = xn <= yn ? (xn - yn + Modulus1)*Reciprocal : (xn - yn)*Reciprocal;
values[i] = xn <= yn ? (xn - yn + Modulus1)*Reciprocal : (xn - yn)*Reciprocal;
}
}
/// <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;
}

26
src/Numerics/Random/Palf.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -32,6 +32,10 @@ using System;
using System.Collections.Generic;
using MathNet.Numerics.Properties;
#if !PORTABLE
using System.Runtime;
#endif
namespace MathNet.Numerics.Random
{
/// <summary>
@ -224,10 +228,10 @@ namespace MathNet.Numerics.Random
}
/// <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>
/// <remarks>Supports being called in parallel from multiple threads.</remarks>
public static double[] Doubles(int length, int seed)
public static void Doubles(double[] values, int seed)
{
if (seed == 0)
{
@ -247,8 +251,7 @@ namespace MathNet.Numerics.Random
var x = Generate.Map(MersenneTwister.Doubles(longLag, seed), uniform => (uint)(uniform*uint.MaxValue));
var k = longLag;
var data = new double[length];
for (int i = 0; i < data.Length; i++)
for (int i = 0; i < values.Length; i++)
{
if (k >= longLag)
{
@ -268,8 +271,19 @@ namespace MathNet.Numerics.Random
k = 0;
}
data[i] = (int)(x[k++] >> 1)*IntToDoubleMultiplier;
values[i] = (int)(x[k++] >> 1)*IntToDoubleMultiplier;
}
}
/// <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;
}

2
src/Numerics/Random/SystemRandomSource.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation

26
src/Numerics/Random/WH1982.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -30,6 +30,10 @@
using System.Collections.Generic;
#if !PORTABLE
using System.Runtime;
#endif
namespace MathNet.Numerics.Random
{
/// <summary>
@ -117,10 +121,10 @@ namespace MathNet.Numerics.Random
}
/// <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>
/// <remarks>Supports being called in parallel from multiple threads.</remarks>
public static double[] Doubles(int length, int seed)
public static void Doubles(double[] values, int seed)
{
if (seed == 0)
{
@ -130,16 +134,26 @@ namespace MathNet.Numerics.Random
uint yn = 1;
uint zn = 1;
var data = new double[length];
for (int i = 0; i < data.Length; i++)
for (int i = 0; i < values.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;
values[i] = w - (int)w;
}
}
/// <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;
}

26
src/Numerics/Random/WH2006.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -30,6 +30,10 @@
using System.Collections.Generic;
#if !PORTABLE
using System.Runtime;
#endif
namespace MathNet.Numerics.Random
{
/// <summary>
@ -120,10 +124,10 @@ namespace MathNet.Numerics.Random
}
/// <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>
/// <remarks>Supports being called in parallel from multiple threads.</remarks>
public static double[] Doubles(int length, int seed)
public static void Doubles(double[] values, int seed)
{
if (seed == 0)
{
@ -134,8 +138,7 @@ namespace MathNet.Numerics.Random
ulong yn = 1;
ulong zn = 1;
var data = new double[length];
for (int i = 0; i < data.Length; i++)
for (int i = 0; i < values.Length; i++)
{
xn = 11600*xn%Modx;
yn = 47003*yn%Mody;
@ -143,8 +146,19 @@ namespace MathNet.Numerics.Random
wn = 33000*wn%Modw;
double u = xn*ModxRecip + yn*ModyRecip + zn*ModzRecip + wn*ModwRecip;
data[i] = u - (int)u;
values[i] = u - (int)u;
}
}
/// <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;
}

27
src/Numerics/Random/Xorshift.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -32,6 +32,10 @@ using System;
using System.Collections.Generic;
using MathNet.Numerics.Properties;
#if !PORTABLE
using System.Runtime;
#endif
namespace MathNet.Numerics.Random
{
/// <summary>
@ -264,11 +268,11 @@ namespace MathNet.Numerics.Random
}
/// <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>
/// <remarks>Supports being called in parallel from multiple threads.</remarks>
[CLSCompliant(false)]
public static double[] Doubles(int length, int seed, ulong a = ASeed, ulong c = CSeed, ulong x1 = YSeed, ulong x2 = ZSeed)
public static void Doubles(double[] values, int seed, ulong a = ASeed, ulong c = CSeed, ulong x1 = YSeed, ulong x2 = ZSeed)
{
if (a <= c)
{
@ -281,16 +285,27 @@ namespace MathNet.Numerics.Random
}
ulong x = (uint)seed;
var data = new double[length];
for (int i = 0; i < data.Length; i++)
for (int i = 0; i < values.Length; i++)
{
var t = (a*x) + c;
x = x1;
x1 = x2;
c = t >> 32;
x2 = t & 0xffffffff;
data[i] = x2*UlongToDoubleMultiplier;
values[i] = x2*UlongToDoubleMultiplier;
}
}
/// <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>
[CLSCompliant(false)]
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public static double[] Doubles(int length, int seed, ulong a = ASeed, ulong c = CSeed, ulong x1 = YSeed, ulong x2 = ZSeed)
{
var data = new double[length];
Doubles(data, seed, a, c, x1, x2);
return data;
}

Loading…
Cancel
Save