コード例 #1
0
        private static void SeekStateInternal(ref uint state0, ref uint state1, ulong offset, bool reverse)
        {
            if (offset >= _MaximumPeriod)
            {
                offset %= _MaximumPeriod;
            }

            if (offset == 0)
            {
                return;
            }

            {
                MyUInt256 aexpn = new MyUInt256(reverse ? _Multiplier0Inverse : _Multiplier0);
                aexpn.ExpMod(offset, new MyUInt256(_Modulus));

                state0 = unchecked ((uint)((aexpn.ToUInt64() * state0) % _Modulus));
            }

            {
                MyUInt256 aexpn = new MyUInt256(reverse ? _Multiplier1Inverse : _Multiplier1);
                aexpn.ExpMod(offset, new MyUInt256(_Modulus1));

                state1 = unchecked ((uint)((aexpn.ToUInt64() * state1) % _Modulus1));
            }
        }
コード例 #2
0
ファイル: PrngLcgBase.cs プロジェクト: MasterScott/prangster
        /// <summary>
        /// Computes the state at the specified position in the pseudorandom stream relative to a given initial state.
        /// </summary>
        /// <param name="state">The state at position zero in the stream.</param>
        /// <param name="offset">The number of states to skip.</param>
        /// <param name="multiplier">The linear congruential generator's multiplier constant, or its multiplicative inverse modulo <paramref name="divisor"/> to go backwards.</param>
        /// <param name="increment">The linear congruential generator's increment constant,
        /// or its additive inverse modulo <paramref name="divisor"/> multiplied by the multiplicative inverse to go backwards.</param>
        /// <param name="divisor">The linear congruential generator's modulus constant.</param>
        /// <returns>The state at position <paramref name="offset"/> in the stream.</returns>
        protected static ulong SeekState(ulong state, ulong offset, ulong multiplier, ulong increment, ulong divisor)
        {
            // NewState = (Multiplier**Offset * OldState) + Increment * (Multiplier**Offset - 1) / (Multiplier - 1)
            // caller can substitute Multiplier**-1 and -Increment * Multiplier**-1 to go backwards

            if (offset == 0)
            {
                return(state);
            }

            if (multiplier == 0)
            {
                return(increment);
            }
            else if (multiplier == 1)
            {
                MyUInt256 product = new MyUInt256(increment);
                product.Multiply(offset);
                if (divisor != 0)
                {
                    product.Modulo(divisor);
                }
                return(product.ToUInt64());
            }

            MyUInt256 compdivisor = new MyUInt256(divisor);

            if (divisor == 0)
            {
                compdivisor.Set(0, 1);
            }
            compdivisor.Multiply(multiplier - 1);

            MyUInt256 aexpn = new MyUInt256(multiplier);

            aexpn.ExpMod(offset, compdivisor);  // = Multiplier**Offset

            MyUInt256 fraction = new MyUInt256(aexpn);

            fraction.Subtract(1);
            fraction.Divide(multiplier - 1); // should always divide evenly; that's why divisor has to include (Multiplier - 1) factor though
            fraction.Multiply(increment);    // = Increment * (Multiplier**Offset - 1) / (Multiplier - 1)

            MyUInt256 newstate = new MyUInt256(state);

            newstate.Multiply(aexpn); // = Multiplier**Offset * OldState
            newstate.Add(fraction);   // = (Multiplier**Offset * OldState) + Increment * (Multiplier**Offset - 1) / (Multiplier - 1)

            if (divisor != 0)
            {
                newstate.Modulo(divisor);  // now that we've divided by (Multiplier - 1), we can go back to using 'divisor' instead of 'compdivisor'
            }
            return(newstate.ToUInt64());
        } //PrngLcgBase.SeekState
コード例 #3
0
ファイル: PrngLcgBase.cs プロジェクト: MasterScott/prangster
        protected static ulong GetMultiplicativeInverse(ulong multiplier, ulong divisor)
        {
            ulong mi;

            if (multiplier >= divisor && divisor != 0)
            {
                return(0);
            }

            if (unchecked ((long)multiplier) < 0 || unchecked ((long)divisor) <= 0)
            {
                mi = ModularMath.MultiplicativeInverse(unchecked ((long)multiplier), unchecked ((long)divisor));
            }
            else
            {
                MyUInt256 mibig = ModularMath.MultiplicativeInverse(new MyUInt256(multiplier), (divisor == 0 ? new MyUInt256(0, 1) : new MyUInt256(divisor)));
                mi = (mibig == null ? 0 : mibig.ToUInt64());
            }

            return(mi);
        } //PrngLcgBase.GetMultiplicativeInverse
コード例 #4
0
ファイル: PrngLcgBase.cs プロジェクト: MasterScott/prangster
        public override void SeekBack(ulong offset)
        {
            if (offset == 0)
            {
                return;
            }

            ulong multiplier = this.Multiplier;
            ulong increment  = this.Increment;
            ulong divisor    = this.Modulus;

            ulong mi = GetMultiplicativeInverse(multiplier, divisor);

            if (mi == 0)
            {
                // guessing that modulus is a multiple of period, in which case seeking ahead (modulus - offset) states will reverse by 'offset' states
                SeekAhead(unchecked (divisor - offset));
                return;
            }

            if (increment >= divisor && divisor != 0)
            {
                increment %= divisor;
            }

            if (increment != 0)
            {
                MyUInt256 incrinverse = new MyUInt256(unchecked (divisor - increment));  // negate increment (modulo divisor) to get additive inverse
                incrinverse.Multiply(mi);

                if (divisor != 0)
                {
                    incrinverse.Modulo(divisor);
                }

                increment = incrinverse.ToUInt64();
            }

            this._LcgState = SeekState(this._LcgState, offset, mi, increment, divisor);
        } //PrngLcgBase.SeekBack
コード例 #5
0
ファイル: PrngLcgBase.cs プロジェクト: MasterScott/prangster
        /// <summary>
        /// Performs discard, modulus, and/or take-from-top transformations on a raw value to produce output according to the PRNG's parameters.
        /// </summary>
        /// <param name="raw">The raw bits to transform.</param>
        /// <param name="limit">The lowest positive integer greater than the maximum desired value.</param>
        /// <returns>A value suitable for output.</returns>
        protected virtual ulong ValueFromRaw(ulong raw, ulong limit)
        {
            if (this.DiscardDivisor != 0)
            {
                raw /= this.DiscardDivisor;

                if (this.OutputDivisor != 0)
                {
                    raw %= this.OutputDivisor;
                }

                return(raw);
            }
            else
            {
                // TO-DO TODO: should we incorporate OutputDivisor somehow?
                MyUInt256 product = new MyUInt256(raw);
                product.Multiply(limit);
                product.Divide(this.Modulus);

                return(product.ToUInt64());
            }
        }
コード例 #6
0
ファイル: PrngLehmerBase.cs プロジェクト: JarLob/Prangster
        /// <summary>
        /// Computes the state at the specified position in the pseudorandom stream relative to a given initial state.
        /// </summary>
        /// <param name="state">The state at position zero in the stream.</param>
        /// <param name="offset">The number of states to skip.</param>
        /// <param name="multiplier">The linear congruential generator's multiplier constant, or its multiplicative inverse modulo <paramref name="divisor"/> to go backwards.</param>
        /// <param name="divisor">The linear congruential generator's modulus constant.</param>
        /// <returns>The state at position <paramref name="offset"/> in the stream.</returns>
        protected static ulong SeekState(ulong state, ulong offset, ulong multiplier, ulong divisor)
        {
            // NewState = (Multiplier**Offset * OldState)
            // caller can substitute Multiplier**-1 to go backwards

            if (offset == 0)
            {
                return(state);
            }

            MyUInt256 fullmodulus = (divisor == 0 ? new MyUInt256(0, 1) : new MyUInt256(divisor));

            MyUInt256 aexpn = new MyUInt256(multiplier);

            aexpn.ExpMod(offset, fullmodulus);
            aexpn.Multiply(state);

            if (divisor != 0)
            {
                aexpn.Modulo(fullmodulus);
            }

            return(aexpn.ToUInt64());
        } //PrngLehmerBase.SeekState
コード例 #7
0
ファイル: PrngMssql.cs プロジェクト: CylanceSPEAR/Prangster
        private static void SeekStateInternal(ref uint state0, ref uint state1, ulong offset, bool reverse)
        {
            if (offset >= _MaximumPeriod)
                offset %= _MaximumPeriod;

            if (offset == 0)
                return;

            {
                MyUInt256 aexpn = new MyUInt256(reverse ? _Multiplier0Inverse : _Multiplier0);
                aexpn.ExpMod(offset, new MyUInt256(_Modulus));

                state0 = unchecked((uint)((aexpn.ToUInt64() * state0) % _Modulus));
            }

            {
                MyUInt256 aexpn = new MyUInt256(reverse ? _Multiplier1Inverse : _Multiplier1);
                aexpn.ExpMod(offset, new MyUInt256(_Modulus1));

                state1 = unchecked((uint)((aexpn.ToUInt64() * state1) % _Modulus1));
            }
        }
コード例 #8
0
        /// <summary>
        /// Computes the state at the specified position in the pseudorandom stream relative to a given initial state.
        /// </summary>
        /// <param name="state">The state at position zero in the stream.</param>
        /// <param name="offset">The number of states to skip.</param>
        /// <param name="multiplier">The linear congruential generator's multiplier constant, or its multiplicative inverse modulo <paramref name="divisor"/> to go backwards.</param>
        /// <param name="divisor">The linear congruential generator's modulus constant.</param>
        /// <returns>The state at position <paramref name="offset"/> in the stream.</returns>
        protected static ulong SeekState(ulong state, ulong offset, ulong multiplier, ulong divisor)
        {
            // NewState = (Multiplier**Offset * OldState)
            // caller can substitute Multiplier**-1 to go backwards

            if (offset == 0)
                return state;

            MyUInt256 fullmodulus = (divisor == 0 ? new MyUInt256(0, 1) : new MyUInt256(divisor));

            MyUInt256 aexpn = new MyUInt256(multiplier);
            aexpn.ExpMod(offset, fullmodulus);
            aexpn.Multiply(state);

            if (divisor != 0)
                aexpn.Modulo(fullmodulus);

            return aexpn.ToUInt64();
        }
コード例 #9
0
ファイル: PrngLcgBase.cs プロジェクト: CylanceSPEAR/Prangster
        /// <summary>
        /// Performs discard, modulus, and/or take-from-top transformations on a raw value to produce output according to the PRNG's parameters.
        /// </summary>
        /// <param name="raw">The raw bits to transform.</param>
        /// <param name="limit">The lowest positive integer greater than the maximum desired value.</param>
        /// <returns>A value suitable for output.</returns>
        protected virtual ulong ValueFromRaw(ulong raw, ulong limit)
        {
            if (this.DiscardDivisor != 0)
            {
                raw /= this.DiscardDivisor;

                if (this.OutputDivisor != 0)
                    raw %= this.OutputDivisor;

                return raw;
            }
            else
            {
                // TO-DO TODO: should we incorporate OutputDivisor somehow?
                MyUInt256 product = new MyUInt256(raw);
                product.Multiply(limit);
                product.Divide(this.Modulus);

                return (product.ToUInt64());
            }
        }
コード例 #10
0
ファイル: PrngLcgBase.cs プロジェクト: CylanceSPEAR/Prangster
        /// <summary>
        /// Computes the state at the specified position in the pseudorandom stream relative to a given initial state.
        /// </summary>
        /// <param name="state">The state at position zero in the stream.</param>
        /// <param name="offset">The number of states to skip.</param>
        /// <param name="multiplier">The linear congruential generator's multiplier constant, or its multiplicative inverse modulo <paramref name="divisor"/> to go backwards.</param>
        /// <param name="increment">The linear congruential generator's increment constant,
        /// or its additive inverse modulo <paramref name="divisor"/> multiplied by the multiplicative inverse to go backwards.</param>
        /// <param name="divisor">The linear congruential generator's modulus constant.</param>
        /// <returns>The state at position <paramref name="offset"/> in the stream.</returns>
        protected static ulong SeekState(ulong state, ulong offset, ulong multiplier, ulong increment, ulong divisor)
        {
            // NewState = (Multiplier**Offset * OldState) + Increment * (Multiplier**Offset - 1) / (Multiplier - 1)
            // caller can substitute Multiplier**-1 and -Increment * Multiplier**-1 to go backwards

            if (offset == 0)
                return state;

            if (multiplier == 0)
            {
                return increment;
            }
            else if (multiplier == 1)
            {
                MyUInt256 product = new MyUInt256(increment);
                product.Multiply(offset);
                if (divisor != 0)
                    product.Modulo(divisor);
                return product.ToUInt64();
            }

            MyUInt256 compdivisor = new MyUInt256(divisor);
            if (divisor == 0)
                compdivisor.Set(0, 1);
            compdivisor.Multiply(multiplier - 1);

            MyUInt256 aexpn = new MyUInt256(multiplier);
            aexpn.ExpMod(offset, compdivisor);  // = Multiplier**Offset

            MyUInt256 fraction = new MyUInt256(aexpn);
            fraction.Subtract(1);
            fraction.Divide(multiplier - 1);  // should always divide evenly; that's why divisor has to include (Multiplier - 1) factor though
            fraction.Multiply(increment);  // = Increment * (Multiplier**Offset - 1) / (Multiplier - 1)

            MyUInt256 newstate = new MyUInt256(state);
            newstate.Multiply(aexpn);  // = Multiplier**Offset * OldState
            newstate.Add(fraction);  // = (Multiplier**Offset * OldState) + Increment * (Multiplier**Offset - 1) / (Multiplier - 1)

            if (divisor != 0)
                newstate.Modulo(divisor);  // now that we've divided by (Multiplier - 1), we can go back to using 'divisor' instead of 'compdivisor'

            return newstate.ToUInt64();
        }
コード例 #11
0
ファイル: PrngLcgBase.cs プロジェクト: CylanceSPEAR/Prangster
        public override ulong SeekSeedBack(ulong seed, ulong offset)
        {
            if (offset == 0)
                return seed;

            ulong multiplier = this.Multiplier;
            ulong increment = this.Increment;
            ulong divisor = this.Modulus;

            ulong mi = GetMultiplicativeInverse(multiplier, divisor);

            if (mi == 0)
            {
                // guessing that modulus is a multiple of period, in which case seeking ahead (modulus - offset) states will reverse by 'offset' states
                return SeekSeedAhead(seed, unchecked(divisor - offset));
            }

            if (increment >= divisor && divisor != 0)
                increment %= divisor;

            if (increment != 0)
            {
                MyUInt256 incrinverse = new MyUInt256(unchecked(divisor - increment));  // negate increment (modulo divisor) to get additive inverse
                incrinverse.Multiply(mi);

                if (divisor != 0)
                    incrinverse.Modulo(divisor);

                increment = incrinverse.ToUInt64();
            }

            return SeekState(this._LcgState, offset, mi, increment, divisor);
        }