Beispiel #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Palf"/> class.
        /// </summary>
        /// <param name="seed">The seed value.</param>
        /// <param name="threadSafe">if set to <c>true</c>, the class is thread safe.</param>
        /// <param name="shortLag">The ShortLag value</param>
        /// <param name="longLag">TheLongLag value</param>
        public Palf(int seed, bool threadSafe, int shortLag, int longLag) : base(threadSafe)
        {
            if (shortLag < 1)
            {
                throw new ArgumentException(Resources.ArgumentMustBePositive, "shortLag");
            }

            if (longLag <= shortLag)
            {
                throw new ArgumentException(Resources.ArgumentUpperBoundMustBeLargerThanLowerBound, "longLag");
            }

            if (seed == 0)
            {
                seed = 1;
            }

            _threads = Control.MaxDegreeOfParallelism;
            ShortLag = shortLag;

            // Align LongLag to number of worker threads.
            if (longLag % _threads == 0)
            {
                LongLag = longLag;
            }
            else
            {
                LongLag = ((longLag / _threads) + 1) * _threads;
            }

            _x = Generate.Map(MersenneTwister.Doubles(LongLag, seed), uniform => (uint)(uniform * uint.MaxValue));
            _k = LongLag;
        }
Beispiel #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Palf"/> class.
        /// </summary>
        /// <param name="seed">The seed value.</param>
        /// <param name="threadSafe">if set to <c>true</c>, the class is thread safe.</param>
        /// <param name="shortLag">The ShortLag value</param>
        /// <param name="longLag">TheLongLag value</param>
        public Palf(int seed, bool threadSafe, int shortLag, int longLag) : base(threadSafe)
        {
            if (shortLag < 1)
            {
                throw new ArgumentException("Value must be positive.", nameof(shortLag));
            }

            if (longLag <= shortLag)
            {
                throw new ArgumentException("The upper bound must be strictly larger than the lower bound.", nameof(longLag));
            }

            if (seed == 0)
            {
                seed = 1;
            }

            _threads = Control.MaxDegreeOfParallelism;
            ShortLag = shortLag;

            // Align LongLag to number of worker threads.
            if (longLag % _threads == 0)
            {
                LongLag = longLag;
            }
            else
            {
                LongLag = ((longLag / _threads) + 1) * _threads;
            }

            _x = Generate.Map(MersenneTwister.Doubles(LongLag, seed), uniform => (uint)(uniform * uint.MaxValue));
            _k = LongLag;
        }
Beispiel #3
0
        /// <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, but the result must be enumerated from a single thread each.</remarks>
        public static IEnumerable <double> DoubleSequence(int seed)
        {
            if (seed == 0)
            {
                seed = 1;
            }

            int       threads  = Control.MaxDegreeOfParallelism;
            const int shortLag = DefaultShortLag;
            var       longLag  = DefaultLongLag;

            // Align LongLag to number of worker threads.
            if (longLag % threads != 0)
            {
                longLag = ((longLag / threads) + 1) * threads;
            }

            var x = Generate.Map(MersenneTwister.Doubles(longLag, seed), uniform => (uint)(uniform * uint.MaxValue));
            var k = longLag;

            while (true)
            {
                if (k >= longLag)
                {
                    for (int index = 0; index < threads; index++)
                    {
                        // Two loops to avoid costly modulo operations
                        for (var j = index; j < shortLag; j = j + threads)
                        {
                            x[j] += x[j + (longLag - shortLag)];
                        }

                        for (var j = shortLag + index; j < longLag; j = j + threads)
                        {
                            x[j] += x[j - shortLag - index];
                        }
                    }

                    k = 0;
                }

                yield return(x[k++] * Reciprocal);
            }
        }
Beispiel #4
0
        /// <summary>
        /// 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 void Doubles(double[] values, int seed)
        {
            if (seed == 0)
            {
                seed = 1;
            }

            int       threads  = Control.MaxDegreeOfParallelism;
            const int shortLag = DefaultShortLag;
            var       longLag  = DefaultLongLag;

            // Align LongLag to number of worker threads.
            if (longLag % threads != 0)
            {
                longLag = ((longLag / threads) + 1) * threads;
            }

            var x = Generate.Map(MersenneTwister.Doubles(longLag, seed), uniform => (uint)(uniform * uint.MaxValue));
            var k = longLag;

            for (int i = 0; i < values.Length; i++)
            {
                if (k >= longLag)
                {
                    for (int index = 0; index < threads; index++)
                    {
                        // Two loops to avoid costly modulo operations
                        for (var j = index; j < shortLag; j = j + threads)
                        {
                            x[j] += x[j + (longLag - shortLag)];
                        }

                        for (var j = shortLag + index; j < longLag; j = j + threads)
                        {
                            x[j] += x[j - shortLag - index];
                        }
                    }

                    k = 0;
                }

                values[i] = (int)(x[k++] >> 1) * IntToDoubleMultiplier;
            }
        }