/// <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) { int num = segmentIndexBits; if (segmentIndexBits < 1 || segmentIndexBits > 4) { num = 3; } int num2 = segmentBits; if (segmentBits < 7 || segmentBits > 15) { num2 = 9; } bitsToStoreRandomIndexWithinSegment = num2; segmentCount = 1 << num; segmentSize = 1 << num2; segmentIndexMask = segmentCount - 1 << bitsToStoreRandomIndexWithinSegment; randomIndexWithinSegmentMask = segmentSize - 1; randomArrayIndexMask = (segmentIndexMask | randomIndexWithinSegmentMask); int num3 = segmentCount * segmentSize; randomGemerators = new IRandomNumberBatchGenerator[segmentCount]; XorshiftRandomBatchGenerator xorshiftRandomBatchGenerator = new XorshiftRandomBatchGenerator((ulong)Environment.TickCount); ulong[] array = new ulong[segmentCount]; xorshiftRandomBatchGenerator.NextBatch(array, 0, segmentCount); for (int i = 0; i < segmentCount; i++) { Func <ulong, IRandomNumberBatchGenerator> func = (ulong seed) => new XorshiftRandomBatchGenerator(seed); IRandomNumberBatchGenerator randomNumberBatchGenerator = (randomGeneratorFactory == null) ? func(array[i]) : (randomGeneratorFactory(array[i]) ?? func(array[i])); randomGemerators[i] = randomNumberBatchGenerator; } randomNumbers = new ulong[num3]; xorshiftRandomBatchGenerator.NextBatch(randomNumbers, 0, num3); }
/// <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 segments must be between 1 and 15 if ((segmentIndexBits < 1) || (segmentIndexBits > 4)) { // 8 segments 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 segment 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); }