Example #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));
            }
        }
Example #2
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="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
Example #3
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());
        } //PrngLehmerBase.SeekState
Example #4
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));
            }
        }
Example #5
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();
        }
Example #6
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="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();
        }