Skip to content
This repository has been archived by the owner on Nov 19, 2020. It is now read-only.

Commit

Permalink
GH-628: Inject other Random.Generators (like Mersenne Twister)
Browse files Browse the repository at this point in the history
  • Loading branch information
cesarsouza committed Jun 7, 2017
1 parent 9736812 commit 20a631a
Show file tree
Hide file tree
Showing 44 changed files with 3,397 additions and 1,762 deletions.
2 changes: 1 addition & 1 deletion Sources/Accord.Math/Accord.Math.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net462|AnyCPU' ">
<DefineConstants>TRACE;NET462</DefineConstants>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'mono|AnyCPU'">
<DefineConstants>TRACE;MONO</DefineConstants>
Expand Down
28 changes: 16 additions & 12 deletions Sources/Accord.Math/Random/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ public static class Generator
private static readonly object sourceRandomLock = new Object();

private static int? sourceSeed;
private static long sourceLastUpdateTicks;
private static int sourceLastUpdateTicks;
private static readonly object sourceSeedLock = new Object();


[ThreadStatic]
private static long threadLastUpdateTicks;
private static int threadLastUpdateTicks;

[ThreadStatic]
private static bool threadOverriden;
Expand Down Expand Up @@ -111,12 +111,6 @@ private static int GetRandomSeed()
}
}

///// <summary>
///// Gets an object that can be used to synchronize access to the generator.
///// </summary>
/////
//public static readonly object SyncObject = new Object();

/// <summary>
/// Gets the timestamp for when the global random generator
/// was last changed (i.e. after setting <see cref="Seed"/>).
Expand Down Expand Up @@ -154,8 +148,9 @@ public static int? ThreadSeed
if (value.HasValue)
{
Generator.threadOverriden = true;
Generator.threadLastUpdateTicks = DateTime.Now.Ticks;
Generator.threadLastUpdateTicks = Environment.TickCount;
Generator.threadRandom = (value.HasValue) ? new Random(threadSeed.Value) : new Random();
Thread.Sleep(100);
}
else
{
Expand Down Expand Up @@ -183,8 +178,7 @@ public static Random Random
{
Generator.threadSeed = GetRandomSeed();
Generator.threadLastUpdateTicks = Generator.sourceLastUpdateTicks;
Generator.threadRandom = (Generator.threadSeed.HasValue) ?
new Random(threadSeed.Value) : new Random();
Generator.threadRandom = (Generator.threadSeed.HasValue) ? new Random(threadSeed.Value) : new Random();
}

return threadRandom;
Expand All @@ -200,6 +194,14 @@ public static Random Random
/// seeds.
/// </summary>
///
/// <remarks>
/// Adjusting the global generator seed causes the calling thread to sleep for 100ms
/// so new threads spawned in a short time span after the call can be properly initialized
/// with the new random seeds. In order to better control the random behavior of different
/// algorithms, please consider specifying random generators directly using appropriate
/// interfaces for these algorithms in case they are available.
/// </remarks>
///
public static int? Seed
{
get { return Generator.sourceSeed; }
Expand All @@ -211,7 +213,7 @@ public static int? Seed

lock (sourceRandomLock)
{
Generator.sourceLastUpdateTicks = DateTime.Now.Ticks;
Generator.sourceLastUpdateTicks = Environment.TickCount;

if (value.HasValue)
{
Expand All @@ -232,6 +234,8 @@ public static int? Seed
int s = unchecked((int)(13 * Thread.CurrentThread.ManagedThreadId ^ Generator.sourceLastUpdateTicks));
Generator.sourceRandom = new Random(s);
}

Thread.Sleep(100); // Make sure the tick count has incremented before returning
}
}
}
Expand Down
226 changes: 128 additions & 98 deletions Sources/Accord.Statistics/Distributions/DistributionBase.cs
Original file line number Diff line number Diff line change
@@ -1,98 +1,128 @@
// Accord Statistics Library
// The Accord.NET Framework
// http://accord-framework.net
//
// Copyright © César Souza, 2009-2017
// cesarsouza at gmail.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//

namespace Accord.Statistics.Distributions
{
using System;

/// <summary>
/// Base class for statistical distribution implementations.
/// </summary>
///
[Serializable]
public abstract class DistributionBase : IFormattable
{

/// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
/// </summary>
///
/// <returns>
/// A <see cref="System.String"/> that represents this instance.
/// </returns>
///
public override string ToString()
{
return ToString(null, null);
}

/// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
/// </summary>
///
/// <returns>
/// A <see cref="System.String"/> that represents this instance.
/// </returns>
///
public string ToString(IFormatProvider formatProvider)
{
return ToString(null, formatProvider);
}

/// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
/// </summary>
///
/// <returns>
/// A <see cref="System.String"/> that represents this instance.
/// </returns>
///
public string ToString(string format)
{
return ToString(format, null);
}

/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
///
/// <param name="format">The format.</param>
/// <param name="formatProvider">The format provider.</param>
///
/// <returns>
/// A <see cref="System.String" /> that represents this instance.
/// </returns>
///
public abstract string ToString(string format, IFormatProvider formatProvider);

/// <summary>
/// Creates a new object that is a copy of the current instance.
/// </summary>
///
/// <returns>
/// A new object that is a copy of this instance.
/// </returns>
///
public abstract object Clone();

}
}
// Accord Statistics Library
// The Accord.NET Framework
// http://accord-framework.net
//
// Copyright © César Souza, 2009-2017
// cesarsouza at gmail.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//

namespace Accord.Statistics.Distributions
{
using Accord.Math.Random;
using System;
using System.Threading;

/// <summary>
/// Base class for statistical distribution implementations.
/// </summary>
///
[Serializable]
public abstract class DistributionBase : IFormattable
{
/*
public DistributionBase()
{
RandomSource = () => Accord.Math.Random.Generator.Random;
}
/// <summary>
/// Gets or sets a factory method to create random number generators used
/// within the distribution.
/// </summary>
///
/// <remarks>
/// <para>
/// As a recommendation, any provided factory method should create a new generator
/// on each call instead of reusing the same one. The reason is that not all
/// generators can be used across multiple threads, and some distributions will
/// call this method from different threads expecting different objects. Ignore
/// this remark only if your generators are thread safe or thread local.</para>
///
/// <para>
/// By default, this method will return instances of the framework's main random generator.
/// The property that gives access to the framework's main random generator
/// (<see cref="Accord.Math.Random.Generator.Random"/>) provides a different generator for
/// each thread (as it uses ThreadLocal).</para>
/// </remarks>
///
public Func<Random> RandomSource { get; set; }
*/

/// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
/// </summary>
///
/// <returns>
/// A <see cref="System.String"/> that represents this instance.
/// </returns>
///
public override string ToString()
{
return ToString(null, null);
}

/// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
/// </summary>
///
/// <returns>
/// A <see cref="System.String"/> that represents this instance.
/// </returns>
///
public string ToString(IFormatProvider formatProvider)
{
return ToString(null, formatProvider);
}

/// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
/// </summary>
///
/// <returns>
/// A <see cref="System.String"/> that represents this instance.
/// </returns>
///
public string ToString(string format)
{
return ToString(format, null);
}

/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
///
/// <param name="format">The format.</param>
/// <param name="formatProvider">The format provider.</param>
///
/// <returns>
/// A <see cref="System.String" /> that represents this instance.
/// </returns>
///
public abstract string ToString(string format, IFormatProvider formatProvider);

/// <summary>
/// Creates a new object that is a copy of the current instance.
/// </summary>
///
/// <returns>
/// A new object that is a copy of this instance.
/// </returns>
///
public abstract object Clone();

}
}
46 changes: 46 additions & 0 deletions Sources/Accord.Statistics/Distributions/ISampleableDistribution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
namespace Accord.Statistics.Distributions
{
using Accord.Math.Random;
using System;

/// <summary>
/// Common interface for sampleable distributions (i.e. distributions that
Expand All @@ -44,5 +45,50 @@ public interface ISampleableDistribution<TObservations> : IDistribution<TObserva
/// <returns>A random observation drawn from this distribution.</returns>
///
TObservations Generate(TObservations result);

/// <summary>
/// Generates a random observation from the current distribution.
/// </summary>
///
/// <param name="result">The location where to store the sample.</param>
/// <param name="source">The random number generator to use as a source of randomness.
/// Default is to use <see cref="Accord.Math.Random.Generator.Random"/>.</param>
///
/// <returns>A random observation drawn from this distribution.</returns>
///
TObservations Generate(TObservations result, Random source);

/// <summary>
/// Generates a random vector of observations from the current distribution.
/// </summary>
///
/// <param name="samples">The number of samples to generate.</param>
/// <param name="source">The random number generator to use as a source of randomness.
/// Default is to use <see cref="Accord.Math.Random.Generator.Random"/>.</param>
///
/// <returns>A random vector of observations drawn from this distribution.</returns>
///
TObservations[] Generate(int samples, Random source);

/// <summary>
/// Generates a random vector of observations from the current distribution.
/// </summary>
///
/// <param name="samples">The number of samples to generate.</param>
/// <param name="result">The location where to store the samples.</param>
/// <param name="source">The random number generator to use as a source of randomness.
/// Default is to use <see cref="Accord.Math.Random.Generator.Random"/>.</param>
///
/// <returns>A random vector of observations drawn from this distribution.</returns>
///
TObservations[] Generate(int samples, TObservations[] result, Random source);

/// <summary>
/// Generates a random observation from the current distribution.
/// </summary>
///
/// <returns>A random observations drawn from this distribution.</returns>
///
TObservations Generate(Random source);
}
}
Loading

0 comments on commit 20a631a

Please sign in to comment.