상속: IRandomNumberBatchGenerator
예제 #1
0
        /// <summary>
        /// Initializes generator with a set of random numbers.
        /// </summary>
        /// <param name="randomGeneratorFactory">Factory used to create random number batch generators.</param>
        /// <param name="segmentIndexBits">Number of significant bits in segment index, i.e. value of 3 means 8 segments of random numbers - 0..7.</param>
        /// <param name="segmentBits">Number of significant bits in random number index within segment, i.e. value of 10 means 1024 random numbers per segment.</param>
        public void Initialize(
            Func <ulong, IRandomNumberBatchGenerator> randomGeneratorFactory,
            int segmentIndexBits,
            int segmentBits)
        {
            // **************************************************
            // validate value of the segementIndexBits parameter
            int effectiveSegementIndexBits = segmentIndexBits;

            // number of segements must be between 1 and 15
            if ((segmentIndexBits < 1) || (segmentIndexBits > 4))
            {
                // 8 segements is default in case the value supplied by caller is incorrect
                effectiveSegementIndexBits = 3;
            }

            // **************************************************
            // validate value of the segementBits parameter
            int effectiveSegementBits = segmentBits;

            // number of randoms within segement must be between 256 and 64K
            if ((segmentBits < 7) || (segmentBits > 15))
            {
                // 1024 randoms is default in case the value supplied by caller is incorrect
                effectiveSegementBits = 9;
            }

            this.bitsToStoreRandomIndexWithinSegment = effectiveSegementBits;

            // store count of segments and count of randoms within the segment
            this.segmentCount = 1 << effectiveSegementIndexBits;
            this.segmentSize  = 1 << effectiveSegementBits;

            // store masks
            this.segmentIndexMask             = (this.segmentCount - 1) << this.bitsToStoreRandomIndexWithinSegment;
            this.randomIndexWithinSegmentMask = this.segmentSize - 1;
            this.randomArrayIndexMask         = this.segmentIndexMask | this.randomIndexWithinSegmentMask;

            int randomNumberCount = this.segmentCount * this.segmentSize;

            // create segmentCount random generators
            this.randomGemerators = new IRandomNumberBatchGenerator[this.segmentCount];

            // create random generator to seed the other ones
            XorshiftRandomBatchGenerator seedingRnd = new XorshiftRandomBatchGenerator((ulong)Environment.TickCount);

            ulong[] seeds = new ulong[this.segmentCount];

            seedingRnd.NextBatch(seeds, 0, this.segmentCount);

            for (int i = 0; i < this.segmentCount; i++)
            {
                // default random batch generator in case factory is null or returns null generator
                Func <ulong, IRandomNumberBatchGenerator> defaultGenerator = (ulong seed) => new XorshiftRandomBatchGenerator(seed);

                IRandomNumberBatchGenerator segmentGenerator = (randomGeneratorFactory == null)
                    ? defaultGenerator(seeds[i])
                    : randomGeneratorFactory(seeds[i]) ?? defaultGenerator(seeds[i]);

                this.randomGemerators[i] = segmentGenerator;
            }

            // allocate storage for random numbers
            this.randomNumbers = new ulong[randomNumberCount];

            // generate entire set of random numbers using seeding random
            seedingRnd.NextBatch(this.randomNumbers, 0, randomNumberCount);
        }
        /// <summary>
        /// Initializes generator with a set of random numbers.
        /// </summary>
        /// <param name="randomGeneratorFactory">Factory used to create random number batch generators.</param>
        /// <param name="segmentIndexBits">Number of significant bits in segment index, i.e. value of 3 means 8 segments of random numbers - 0..7.</param>
        /// <param name="segmentBits">Number of significant bits in random number index within segment, i.e. value of 10 means 1024 random numbers per segment.</param>
        public void Initialize(
            Func<ulong, IRandomNumberBatchGenerator> randomGeneratorFactory,
            int segmentIndexBits,
            int segmentBits)
        {
            // **************************************************
            // validate value of the segementIndexBits parameter
            int effectiveSegementIndexBits = segmentIndexBits;

            // number of segements must be between 1 and 15
            if ((segmentIndexBits < 1) || (segmentIndexBits > 4))
            {
                // 8 segements is default in case the value supplied by caller is incorrect
                effectiveSegementIndexBits = 3;
            }

            // **************************************************
            // validate value of the segementBits parameter
            int effectiveSegementBits = segmentBits;

            // number of randoms within segement must be between 256 and 64K
            if ((segmentBits < 7) || (segmentBits > 15))
            {
                // 1024 randoms is default in case the value supplied by caller is incorrect
                effectiveSegementBits = 9;
            }

            this.bitsToStoreRandomIndexWithinSegment = effectiveSegementBits;

            // store count of segments and count of randoms within the segment
            this.segmentCount = 1 << effectiveSegementIndexBits;
            this.segmentSize = 1 << effectiveSegementBits;

            // store masks
            this.segmentIndexMask = (this.segmentCount - 1) << this.bitsToStoreRandomIndexWithinSegment;
            this.randomIndexWithinSegmentMask = this.segmentSize - 1;
            this.randomArrayIndexMask = this.segmentIndexMask | this.randomIndexWithinSegmentMask;

            int randomNumberCount = this.segmentCount * this.segmentSize;

            // create segmentCount random generators
            this.randomGemerators = new IRandomNumberBatchGenerator[this.segmentCount];

            // create random generator to seed the other ones
            XorshiftRandomBatchGenerator seedingRnd = new XorshiftRandomBatchGenerator((ulong)Environment.TickCount);
            ulong[] seeds = new ulong[this.segmentCount];

            seedingRnd.NextBatch(seeds, 0, this.segmentCount);

            for (int i = 0; i < this.segmentCount; i++)
            {
                // default random batch generator in case factory is null or returns null generator
                Func<ulong, IRandomNumberBatchGenerator> defaultGenerator = (ulong seed) => new XorshiftRandomBatchGenerator(seed);

                IRandomNumberBatchGenerator segmentGenerator = (randomGeneratorFactory == null)
                    ? defaultGenerator(seeds[i])
                    : randomGeneratorFactory(seeds[i]) ?? defaultGenerator(seeds[i]);

                this.randomGemerators[i] = segmentGenerator;
            }

            // allocate storage for random numbers
            this.randomNumbers = new ulong[randomNumberCount];

            // generate entire set of random numbers using seeding random
            seedingRnd.NextBatch(this.randomNumbers, 0, randomNumberCount);
        }