Resolve "Add possibility to get integers" #17
@ -36,13 +36,12 @@ public sealed class MultiChannelRng<TNum> : IRandom<TNum>, IDisposable where TNu
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Creates a multi-threaded random number generator.
|
||||
/// Creates a multithreaded random number generator.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This constructor uses the user's current local time
|
||||
/// to derive necessary parameters for the generator.
|
||||
/// Thus, the results are depending on the time, where
|
||||
/// the generator was created.
|
||||
/// to derive the necessary parameters for the generator.
|
||||
/// Thus, the results depend on the time when the generator was created.
|
||||
/// </remarks>
|
||||
public MultiChannelRng()
|
||||
{
|
||||
@ -58,7 +57,7 @@ public sealed class MultiChannelRng<TNum> : IRandom<TNum>, IDisposable where TNu
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a multi-threaded random number generator.
|
||||
/// Creates a multithreaded random number generator.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A multi-threaded random number generator created by this constructor is
|
||||
|
@ -12,18 +12,15 @@ namespace FastRng;
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Please note, that Math.NET's (https://www.mathdotnet.com/) random number generator is in some situations faster.
|
||||
/// Unlike Math.NET, MultiThreadedRng is multi-threaded. Consumers can use a token to cancel e.g. timeout an operation.<br/><br/>
|
||||
/// Unlike Math.NET, MultiThreadedRng is multithreaded. Consumers can use a token to cancel an operation.<br/><br/>
|
||||
///
|
||||
/// MultiThreadedRng using a shape fitter (a rejection sampler) to enforce arbitrary shapes of probabilities for
|
||||
/// desired distributions. By using the shape fitter, it is even easy to define discontinuous, arbitrary functions
|
||||
/// desired distributions. By using the shape fitter, it is even easier to define discontinuous, arbitrary functions
|
||||
/// as shapes. Any consumer can define and use own distributions.<br/><br/>
|
||||
///
|
||||
/// This class uses the George Marsaglia's MWC algorithm. The algorithm's implementation based loosely on John D.
|
||||
/// This class uses the George Marsaglia's MWC algorithm. The algorithm's implementation is based loosely on John D.
|
||||
/// Cook's (johndcook.com) implementation (https://www.codeproject.com/Articles/25172/Simple-Random-Number-Generation).
|
||||
/// Thanks John for the inspiration.<br/><br/>
|
||||
///
|
||||
/// Please notice: When using the debug environment, MultiThreadedRng might uses a smaller buffer size. Please ensure,
|
||||
/// that the production environment uses a release build, though.
|
||||
/// Thanks, John, for the inspiration.<br/><br/>
|
||||
/// </remarks>
|
||||
public sealed class MultiThreadedRng<TNum> : IRandom<TNum>, IDisposable where TNum : IFloatingPointIeee754<TNum>, IAdditionOperators<TNum, TNum, TNum>
|
||||
{
|
||||
@ -33,10 +30,10 @@ public sealed class MultiThreadedRng<TNum> : IRandom<TNum>, IDisposable where TN
|
||||
private const int BUFFER_SIZE = 1_000_000;
|
||||
#endif
|
||||
|
||||
// The queue size means, how many buffer we store in a queue at the same time:
|
||||
// The queue size means, how many buffers we store in a queue at the same time:
|
||||
private const int QUEUE_SIZE_FLOAT = 2;
|
||||
|
||||
// The queue size means, how many buffer we store in a queue at the same time:
|
||||
// The queue size means, how many buffers we store in a queue at the same time:
|
||||
private const int QUEUE_SIZE_INT = QUEUE_SIZE_FLOAT * 2;
|
||||
|
||||
private static readonly TNum CONST_FLOAT_CONVERSION = TNum.CreateChecked(2.328306435454494e-10f);
|
||||
@ -65,7 +62,7 @@ public sealed class MultiThreadedRng<TNum> : IRandom<TNum>, IDisposable where TN
|
||||
private uint mW;
|
||||
private uint mZ;
|
||||
|
||||
// This is the current buffer for the consumer side i.e. the public interfaces:
|
||||
// This is the current buffer for the consumer side, i.e., the public interfaces:
|
||||
private TNum[] currentBuffer = [];
|
||||
|
||||
// The current pointer to the next current buffer's address to read from:
|
||||
@ -77,10 +74,8 @@ public sealed class MultiThreadedRng<TNum> : IRandom<TNum>, IDisposable where TN
|
||||
/// Creates a multi-threaded random number generator.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This constructor uses the user's current local time
|
||||
/// to derive necessary parameters for the generator.
|
||||
/// Thus, the results are depending on the time, where
|
||||
/// the generator was created.
|
||||
/// This constructor uses the user's current local time to derive the necessary parameters for the generator.
|
||||
/// Thus, the results depend on the time when the generator was created.
|
||||
/// </remarks>
|
||||
public MultiThreadedRng()
|
||||
{
|
||||
@ -171,7 +166,7 @@ public sealed class MultiThreadedRng<TNum> : IRandom<TNum>, IDisposable where TN
|
||||
{
|
||||
try
|
||||
{
|
||||
// Ensure, that we do not produce more buffers, as configured:
|
||||
// Ensure that we do not produce more buffers, as configured:
|
||||
if (this.queueIntegers.Count < QUEUE_SIZE_INT)
|
||||
{
|
||||
this.queueIntegers.Enqueue(nextBuffer);
|
||||
@ -224,7 +219,7 @@ public sealed class MultiThreadedRng<TNum> : IRandom<TNum>, IDisposable where TN
|
||||
{
|
||||
try
|
||||
{
|
||||
// Ensure, that the queue contains only the configured number of buffers:
|
||||
// Ensure that the queue contains only the configured number of buffers:
|
||||
if (this.queueFloats.Count < QUEUE_SIZE_FLOAT)
|
||||
{
|
||||
this.queueFloats.Enqueue(nextBuffer);
|
||||
@ -273,7 +268,7 @@ public sealed class MultiThreadedRng<TNum> : IRandom<TNum>, IDisposable where TN
|
||||
// can get the next buffer:
|
||||
lock (LOCKER)
|
||||
{
|
||||
// We are might not the first thread, which has to get the next buffer.
|
||||
// We might not the first thread, which has to get the next buffer.
|
||||
// When some other thread has already got the next buffer, the pointer
|
||||
// was already reset to zero. In this case, we start over again:
|
||||
if(this.currentBufferPointer < BUFFER_SIZE)
|
||||
@ -295,7 +290,7 @@ public sealed class MultiThreadedRng<TNum> : IRandom<TNum>, IDisposable where TN
|
||||
// Made a local copy of the current pointer:
|
||||
var myPointer = this.currentBufferPointer;
|
||||
|
||||
// Issue #8: This might happens when the current thread was interrupted by another thread, and
|
||||
// Issue #8: This might happen when another thread interrupted the current thread, and
|
||||
// the other thread has already updated the pointer. In this case, we start over again.
|
||||
if (myPointer >= BUFFER_SIZE)
|
||||
goto Start;
|
||||
|
Loading…
Reference in New Issue
Block a user