Browse Source

Random: reintroduce SystemRandomSource, RandomSource abstract again

optimization-3
Christoph Ruegg 13 years ago
parent
commit
b0fcc0cc50
  1. 4
      src/FSharp/Random.fs
  2. 1
      src/Numerics/Numerics.csproj
  3. 75
      src/Numerics/Random/RandomSource.cs
  4. 115
      src/Numerics/Random/SystemRandomSource.cs
  5. 2
      src/UnitTests/Random/RandomTests.cs
  6. 52
      src/UnitTests/Random/SystemRandomSourceTests.cs
  7. 1
      src/UnitTests/UnitTests.csproj

4
src/FSharp/Random.fs

@ -37,8 +37,8 @@ module Random =
let shared = MersenneTwister.Default :> System.Random
/// Creates a default .Net system pRNG with a custom seed based on uinque GUIDs
let system () = new System.Random(RandomSeed.Guid())
let systemSeed seed = new System.Random(seed)
let system () = new SystemRandomSource() :> System.Random
let systemSeed (seed:int) = new SystemRandomSource(seed) :> System.Random
#if PORTABLE
#else

1
src/Numerics/Numerics.csproj

@ -182,6 +182,7 @@
<Compile Include="LinearAlgebra\Vector.BCL.cs" />
<Compile Include="LinearAlgebra\Vector.Operators.cs" />
<Compile Include="NonConvergenceException.cs" />
<Compile Include="Random\SystemRandomSource.cs" />
<Compile Include="Random\RandomSeed.cs" />
<Compile Include="RootFinding\Broyden.cs" />
<Compile Include="RootFinding\NewtonRaphson.cs" />

75
src/Numerics/Random/RandomSource.cs

@ -29,7 +29,6 @@
// </copyright>
using System;
using System.Collections.Generic;
using MathNet.Numerics.Properties;
namespace MathNet.Numerics.Random
@ -39,7 +38,7 @@ namespace MathNet.Numerics.Random
/// and the Math.Net Numerics random number generators to provide thread safety.
/// When used directly it use the System.Random as random number source.
/// </summary>
public class RandomSource : System.Random
public abstract class RandomSource : System.Random
{
readonly bool _threadSafe;
readonly object _lock = new object();
@ -49,7 +48,7 @@ namespace MathNet.Numerics.Random
/// the value of <see cref="Control.ThreadSafeRandomNumberGenerators"/> to set whether
/// the instance is thread safe or not.
/// </summary>
public RandomSource() : base(RandomSeed.Guid())
protected RandomSource() : base(RandomSeed.Guid())
{
_threadSafe = Control.ThreadSafeRandomNumberGenerators;
}
@ -60,30 +59,7 @@ namespace MathNet.Numerics.Random
/// <param name="threadSafe">if set to <c>true</c> , the class is thread safe.</param>
/// <remarks>Thread safe instances are two and half times slower than non-thread
/// safe classes.</remarks>
public RandomSource(bool threadSafe) : base(RandomSeed.Guid())
{
_threadSafe = threadSafe;
}
/// <summary>
/// Initializes a new instance of the <see cref="RandomSource"/> class using
/// the value of <see cref="Control.ThreadSafeRandomNumberGenerators"/> to set whether
/// the instance is thread safe or not.
/// </summary>
/// <param name="systemRandomSeed">The seed value.</param>
public RandomSource(int systemRandomSeed) : base(systemRandomSeed)
{
_threadSafe = Control.ThreadSafeRandomNumberGenerators;
}
/// <summary>
/// Initializes a new instance of the <see cref="RandomSource"/> class.
/// </summary>
/// <param name="systemRandomSeed">The seed value.</param>
/// <param name="threadSafe">if set to <c>true</c> , the class is thread safe.</param>
/// <remarks>Thread safe instances are two and half times slower than non-thread
/// safe classes.</remarks>
public RandomSource(int systemRandomSeed, bool threadSafe) : base(systemRandomSeed)
protected RandomSource(bool threadSafe) : base(RandomSeed.Guid())
{
_threadSafe = threadSafe;
}
@ -241,55 +217,12 @@ namespace MathNet.Numerics.Random
return DoSample();
}
/// <summary>
/// Thread safe version of <seealso cref="DoSample"/> which returns a random number between 0.0 and 1.0.
/// </summary>
/// <returns>A double-precision floating point number greater than or equal to 0.0, and less than 1.0</returns>
double ThreadSafeSample()
{
lock (_lock)
{
return DoSample();
}
}
/// <summary>
/// Returns a random number between 0.0 and 1.0.
/// </summary>
/// <returns>
/// A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
/// </returns>
protected virtual double DoSample()
{
return base.Sample();
}
/// <summary>
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary>
public static double[] Samples(int length, int systemRandomSeed)
{
var rnd = new System.Random(systemRandomSeed);
var data = new double[length];
for (int i = 0; i < data.Length; i++)
{
data[i] = rnd.NextDouble();
}
return data;
}
/// <summary>
/// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary>
public static IEnumerable<double> SampleSequence(int systemRandomSeed)
{
var rnd = new System.Random(systemRandomSeed);
while (true)
{
yield return rnd.NextDouble();
}
}
protected abstract double DoSample();
}
}

115
src/Numerics/Random/SystemRandomSource.cs

@ -0,0 +1,115 @@
// <copyright file="SystemCrypto.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System.Collections.Generic;
namespace MathNet.Numerics.Random
{
/// <summary>
/// A random number generator based on the <see cref="System.Random"/> class in the .NET library.
/// </summary>
public class SystemRandomSource : RandomSource
{
readonly System.Random _random;
/// <summary>
/// Construct a new random number generator with a random seed.
/// </summary>
public SystemRandomSource() : this(RandomSeed.Guid())
{
}
/// <summary>
/// Construct a new random number generator with random seed.
/// </summary>
/// <param name="threadSafe">if set to <c>true</c> , the class is thread safe.</param>
public SystemRandomSource(bool threadSafe) : this(RandomSeed.Guid(), threadSafe)
{
}
/// <summary>
/// Construct a new random number generator with random seed.
/// </summary>
/// <param name="seed">The seed value.</param>
public SystemRandomSource(int seed)
{
_random = new System.Random(seed);
}
/// <summary>
/// Construct a new random number generator with random seed.
/// </summary>
/// <param name="seed">The seed value.</param>
/// <param name="threadSafe">if set to <c>true</c> , the class is thread safe.</param>
public SystemRandomSource(int seed, bool threadSafe) : base(threadSafe)
{
_random = new System.Random(seed);
}
/// <summary>
/// Returns a random number between 0.0 and 1.0.
/// </summary>
/// <returns>
/// A double-precision floating point number greater than or equal to 0.0, and less than 1.0.
/// </returns>
protected override double DoSample()
{
return _random.NextDouble();
}
/// <summary>
/// Returns an array of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary>
public static double[] Samples(int length, int seed)
{
var rnd = new System.Random(seed);
var data = new double[length];
for (int i = 0; i < data.Length; i++)
{
data[i] = rnd.NextDouble();
}
return data;
}
/// <summary>
/// Returns an infinite sequence of random numbers greater than or equal to 0.0 and less than 1.0.
/// </summary>
public static IEnumerable<double> SampleSequence(int seed)
{
var rnd = new System.Random(seed);
while (true)
{
yield return rnd.NextDouble();
}
}
}
}

2
src/UnitTests/Random/RandomTests.cs

@ -89,10 +89,12 @@ namespace MathNet.Numerics.UnitTests.Random
[Test]
public void Reproducible()
{
#if !PORTABLE
if (_randomType == typeof (CryptoRandomSource))
{
Assert.Ignore("CryptoRandomSource does not support seeds and is not reproducible by design.");
}
#endif
Assert.That(
((RandomSource)Activator.CreateInstance(_randomType, new object[] { 5, false })).NextDoubles(1000),

52
src/UnitTests/Random/SystemRandomSourceTests.cs

@ -0,0 +1,52 @@
// <copyright file="Mcg59Tests.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using MathNet.Numerics.Random;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.Random
{
/// <summary>
/// Tests for System.Random.
/// </summary>
[TestFixture, Category("Random")]
public class SystemRandomSourceTests : RandomTests
{
public SystemRandomSourceTests() : base(typeof(SystemRandomSource))
{
}
[Test]
public void StaticSamplesConsistent()
{
Assert.That(SystemRandomSource.Samples(1000, 1), Is.EqualTo(new SystemRandomSource(1).NextDoubles(1000)).Within(1e-12).AsCollection);
}
}
}

1
src/UnitTests/UnitTests.csproj

@ -358,6 +358,7 @@
<Compile Include="EuclidTests\GcdRelatedTest.cs" />
<Compile Include="EuclidTests\GcdRelatedTestBigInteger.cs" />
<Compile Include="EuclidTests\IntegerTheoryTest.cs" />
<Compile Include="Random\SystemRandomSourceTests.cs" />
<Compile Include="RootFindingTests\BisectionTest.cs" />
<Compile Include="PermutationTest.cs" />
<Compile Include="PrecisionTest.cs" />

Loading…
Cancel
Save