コード例 #1
0
 /// <summary>
 /// Overwrites the entire list using a random number generator
 /// which would be used to generate random numbers in the interval
 /// [<paramref name="min"/>; <paramref name="max"/>).
 /// </summary>
 /// <remarks>
 /// The filling is made by assign operation, which means, no new elements
 /// will be added to the collection using <c>Add()</c> method.
 /// </remarks>
 /// <typeparam name="T">The type of elements in the list.</typeparam>
 /// <param name="list">The list reference.</param>
 /// <param name="randomGenerator">The random generator to generate random numbers for the list.</param>
 /// <param name="min">The minimum inclusive value to generate.</param>
 /// <param name="max">The maximum exclusive value to generate.</param>
 public static void FillByAssign <T>(this IList <T> list, IRandomBounded <T> randomGenerator, T min, T max)
 {
     for (int i = 0; i < list.Count; i++)
     {
         list[i] = randomGenerator.Next(min, max);
     }
 }
コード例 #2
0
        /// <summary>
        /// Initializes the <c>RandomLongIntRejection&lt;<typeparamref name="B"/>&gt;</c> instance
        /// with an integer digit generator.
        /// </summary>
        /// <param name="intGenerator">
        /// A uniform distribution integer generator which will be used
        /// to produce <c>LongInt&lt;<typeparamref name="B"/>&gt;</c> digits.
        /// If <c>null</c>, a new <c>RandomStandard</c> instance will be used.
        /// </param>
        /// <see cref="RandomStandard"/>
        public RandomLongIntRejection(IRandomBounded <int> intGenerator = null)
        {
            if (intGenerator == null)
            {
                intGenerator = new RandomStandard();
            }

            this.intGenerator = intGenerator;
        }
コード例 #3
0
        /// <summary>
        /// Performs a quick, linear-complexity random shuffling of the list.
        /// The quality of shuffling is medium.
        /// Makes use of a user-provided integer random number generator.
        /// </summary>
        /// <typeparam name="T">The type of elements in the list.</typeparam>
        /// <param name="list">The calling list object.</param>
        /// <param name="randomGenerator">A user-provided integer random number generator.</param>
        public static void ShuffleQuick <T>(this IList <T> list, IRandomBounded <int> randomGenerator)
        {
            Contract.Requires <ArgumentNullException>(list != null, "list");
            Contract.Requires <ArgumentNullException>(randomGenerator != null, "randomGenerator");

            for (int i = 0; i < list.Count - 1; i++)
            {
                int swapIndex = randomGenerator.Next(i + 1, list.Count);
                list.Swap(i, swapIndex);
            }
        }
コード例 #4
0
        /// <summary>
        /// Performs a Solovay-Strassen stochastic primality test of a long integer number
        /// and returns the probability that the number is composite.
        /// </summary>
        /// <typeparam name="B">A class specifying the digit base of <c>LongInt&lt;<typeparamref name="B"/></c> type.</typeparam>
        /// <param name="num">A number, bigger than 1, to test for primality.</param>
        /// <param name="gen">
        /// A bounded <c>LongInt&lt;<typeparamref name="B"/></c> random generator.
        /// For probability estimations to be correct, this generator should guarantee uniform distribution
        /// for any given interval.
        /// </param>
        /// <param name="rounds">
        /// A positive number of testing rounds. Recommended to be more than <c>log2(<paramref name="num"/>)</c>.
        /// </param>
        /// <returns>
        /// The probability that the <paramref name="num"/> is composite.
        /// Equals to <c>2^(-<paramref name="rounds"/>)</c>, which is
        /// worse than for <see cref="IsPrime_MillerRabin&lt;B&gt;"/>.
        /// </returns>
        public static double IsPrime_SolovayStrassen <B>(this LongInt <B> num, IRandomBounded <LongInt <B> > gen, long rounds)
            where B : IBase, new()
        {
            Contract.Requires <ArgumentNullException>(num != null, "num");
            Contract.Requires <ArgumentNullException>(gen != null, "gen");
            Contract.Requires <ArgumentOutOfRangeException>(num > 1, "The tested number should be bigger than 2.");
            Contract.Requires <ArgumentOutOfRangeException>(rounds > 0, "The number of rounds should be positive.");

            if (num.IsEven)
            {
                if (num == 2)
                {
                    return(0);
                }
                else
                {
                    return(1);
                }
            }
            else if (num == 3)
            {
                return(0);
            }

            LongInt <B> half = (num - 1) / 2;

            for (long i = 0; i < rounds; i++)
            {
                LongInt <B> rnd = gen.Next(2, num);

                int jacobiSymbol = WhiteMath <LongInt <B>, CalcLongInt <B> > .JacobiSymbol(rnd, num);

                // Символ Якоби равняется нулю, значит, числа не взаимно простые
                // значит, наше число составное.

                if (jacobiSymbol == 0)
                {
                    return(1);
                }

                // Иначе еще вот что посмотрим.

                LongInt <B> powered = LongInt <B> .Helper.PowerIntegerModular(rnd, half, num);

                if (jacobiSymbol == 1 && powered != 1 ||
                    jacobiSymbol == -1 && powered != num - 1)
                {
                    return(1);
                }
            }

            return(Math.Pow(2, -rounds));
        }
コード例 #5
0
        /// <summary>
        /// Forms a random string of the desired length containing characters from a <c>char</c> list.
        /// There are no guarantees for each character to appear in the string.
        /// </summary>
        /// <param name="gen">An integer generator which will be used to randomly traverse the character list.</param>
        /// <param name="characters">A list of characters. Duplicates will increase the chance of appearing in the result string.</param>
        /// <param name="length">A non-negative desired length of the string.</param>
        /// <returns>A random string of the desired length containing characters from a <c>char</c> list.</returns>
        public static string NextString(this IRandomBounded<int> gen, IList<char> characters, int length)
        {
            Contract.Requires<ArgumentNullException>(gen != null, "gen");
            Contract.Requires<ArgumentNullException>(characters != null, "characters");
            Contract.Requires<ArgumentOutOfRangeException>(length >= 0, "The length of the string should be a non-negative value.");

            StringBuilder builder = new StringBuilder(length);

            for (int i = 0; i < length; i++)
                builder.Append(characters[gen.Next(0, characters.Count)]);

            return builder.ToString();
        }
コード例 #6
0
        /// <summary>
        /// Performs a Miller-Rabin stochastic primality test of a long integer number
        /// and returns the probability that the number is composite.
        /// </summary>
        /// <typeparam name="B">A class specifying the digit base of <c>LongInt&lt;<typeparamref name="B"/></c> type.</typeparam>
        /// <param name="num">The number to test for primality. Should be more than 1.</param>
        /// <param name="gen">
        /// A bounded <c>LongInt&lt;<typeparamref name="B"/></c> random generator.
        /// For probability estimations to be correct, this generator should guarantee uniform distribution
        /// for any given interval.
        /// </param>
        /// <param name="rounds">
        /// A positive number of testing rounds. Recommended to be more than <c>log2(<paramref name="num"/>)</c>.
        /// </param>
        /// <returns>The probability that the <paramref name="num"/> is composite.</returns>
        public static double IsPrime_MillerRabin <B>(this LongInt <B> num, IRandomBounded <LongInt <B> > gen, long rounds)
            where B : IBase, new()
        {
            Contract.Requires <ArgumentNullException>(num != null, "num");
            Contract.Requires <ArgumentNullException>(gen != null, "gen");
            Contract.Requires <ArgumentOutOfRangeException>(num > 1, "The number to test should be bigger than 1.");
            Contract.Requires <ArgumentOutOfRangeException>(rounds > 0, "The number of rounds should be positive.");

            if (num.IsEven)
            {
                if (num == 2)
                {
                    return(0);
                }
                else
                {
                    return(1);
                }
            }
            else if (num == 3)
            {
                return(0);
            }

            // Представим число num - 1 в виде
            //
            //      num - 1 = 2^s * t

            LongInt <B> t;
            long        s;

            ___millerRabinFactorize(num - 1, out t, out s);

            // ------------------------
            // А теперь - куча раундов.
            // ------------------------

            for (int i = 0; i < rounds; i++)
            {
                LongInt <B> x = gen.Next(2, num - 1);

                if (!___millerRabinIsPrimeWitness(x, num, t, s))
                {
                    return(1);
                }
            }

            return(Math.Pow(4, -rounds));
        }
コード例 #7
0
        /// <summary>
        /// Initializes the <c>RandomLongIntModular&lt;<typeparamref name="B"/>&gt;</c> instance
        /// with an integer digit generator and a delegate used to multiply <c>LongInt&lt;<typeparamref name="B"/>&gt;</c> numbers.
        /// </summary>
        /// <param name="intGenerator">
        /// A uniform distribution integer generator which will be used
        /// to produce <c>LongInt&lt;<typeparamref name="B"/>&gt;</c> digits.
        /// If <c>null</c>, a new <c>RandomStandard</c> instance will be used.
        /// </param>
        /// <see cref="RandomStandard"/>
        /// <param name="multiplication">
        /// A function taking two <c>LongInt&lt;<typeparamref name="B"/>&gt;</c> numbers
        /// and returning their multiplication product.
        /// If <c>null</c>, the simple, O(n^2) multiplication method will be used.
        /// </param>
        /// <see cref="LongInt&lt;B&gt;.Helper.MultiplySimple"/>
        public RandomLongIntModularUnoptimized(IRandomBounded <int> intGenerator = null, Func <LongInt <B>, LongInt <B>, LongInt <B> > multiplication = null)
        {
            if (intGenerator == null)
            {
                intGenerator = new RandomStandard();
            }

            if (multiplication == null)
            {
                multiplication = LongInt <B> .Helper.MultiplySimple;
            }

            this.intGenerator   = intGenerator;
            this.multiplication = multiplication;
        }
コード例 #8
0
        /// <summary>
        /// Creates a pair of two primes which, being multiplied one by another,
        /// produce a public key of desired length for the RSA algorithm.
        /// </summary>
        /// <typeparam name="B">An implementation of <c>IBase</c> interface which specifies the digit base of <c>LongInt&lt;<typeparamref name="B"/>&gt;</c> numbers.</typeparam>
        /// <param name="digits">The desired number of digits in the public key.</param>
        /// <param name="randomGenerator">A random generator for long integer numbers.</param>
        /// <param name="primalityTest"></param>
        /// <returns></returns>
        public static Point <LongInt <B> > GetKey <B>(int digits, IRandomBounded <LongInt <B> > randomGenerator = null, Func <LongInt <B>, bool> primalityTest = null) where B : IBase, new()
        {
            Contract.Requires <ArgumentOutOfRangeException>(digits > 1, "The amount of digits in the key should be more than 1.");

            /*
             * Contract.Ensures(
             *  (Contract.Result<Point<LongInt<B>>>().X * Contract.Result<Point<LongInt<B>>>().Y)
             *  .Length == digits);
             */

            long bits = (long)Math.Ceiling(Math.Log(LongInt <B> .BASE, 2));   // сколько бит занимает BASE

            if (randomGenerator == null)
            {
                randomGenerator = new RandomLongIntModular <B>(new RandomMersenneTwister());
            }

            if (primalityTest == null)
            {
                primalityTest = (x => __isPrimeOptimized(x));
            }

            LongInt <B>
            firstPrime,
                secondPrime;

            int half = digits / 2;

            // На текущий момент длина ключа может оказаться МЕНЬШЕ
            // запланированной. Сделать так, чтобы она всегда была одна.
            // Нижеуказанный генератор тоже снести.

            IRandomBoundedUnbounded <int> tmp = new RandomCryptographic();

            do
            {
                firstPrime = new LongInt <B>(half, tmp, false);
            }while (!primalityTest(firstPrime));

            do
            {
                secondPrime = new LongInt <B>(digits - half, tmp, false);
            }while (!primalityTest(secondPrime));

            return(new Point <LongInt <B> >(firstPrime, secondPrime));
        }
コード例 #9
0
        /// <summary>
        /// Performs a Fermat stochastic primality test of a long integer number.
        /// </summary>
        /// <typeparam name="B">A class specifying the digit base of <c>LongInt&lt;<typeparamref name="B"/></c> type.</typeparam>
        /// <param name="num">A number to test for primality. Should be more than 1.</param>
        /// <param name="gen">
        /// A bounded <c>LongInt&lt;<typeparamref name="B"/></c> random generator.
        /// For probability estimations to be correct, this generator should guarantee uniform distribution
        /// for any given interval.
        /// </param>
        /// <param name="rounds">A positive number of testing rounds.</param>
        /// <returns>If this method returns false, the number is guaranteed to be composite. Otherwise the number is probably prime, but it's not always the case.</returns>
        public static bool IsPrime_Fermat <B>(this LongInt <B> num, IRandomBounded <LongInt <B> > gen, long rounds)
            where B : IBase, new()
        {
            Contract.Requires <ArgumentNullException>(num != null, "num");
            Contract.Requires <ArgumentNullException>(gen != null, "gen");
            Contract.Requires <ArgumentOutOfRangeException>(num > 1, "The number to test should be bigger than 1.");
            Contract.Requires <ArgumentOutOfRangeException>(rounds > 0, "The number of rounds should be positive.");

            if (num.IsEven)
            {
                if (num == 2)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            else if (num == 3)
            {
                return(true);
            }

            LongInt <B> numDecremented = num - 1;

            for (long i = 0; i < rounds; i++)
            {
                LongInt <B> test = gen.Next(2, num);

                if (LongInt <B> .Helper.PowerIntegerModular(test, numDecremented, num) != 1)
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #10
0
        // --------------------------------------------
        // --------- ЧИСЛЕННОЕ ИНТЕГРИРОВАНИЕ ---------
        // --------------------------------------------

        /// <summary>
        /// Returns the Monte-Carlo stochastic approximation of the function integral.
        ///
        /// Requirements: calculator for the function argument/value should provide
        /// reasonable implementation of the 'fromDouble()' method.
        /// </summary>
        /// <typeparam name="T">The type of the function's argument/value.</typeparam>
        /// <typeparam name="C">The calculator for the function argument.</typeparam>
        /// <param name="obj">The calling function object.</param>
        /// <param name="generator">The uniform distribution (pseudo)random generator.</param>
        /// <param name="interval">The interval on which the integral will be approximated.</param>
        /// <param name="rectangleHeight">The height of the testing rectangle. Should be more than the function's absolute maximum on the interval tested, otherwise the method would return wrong results. On the other side, the difference between the height and the function's absolute maximum should not be very large as it will reduce the accuracy of the method. The ideal case is equality of the max f(x) on [a; b] and the rectangle height.</param>
        /// <param name="throwsCount">A positive integer value of overall tests.</param>
        /// <returns>The value approximating the function integral on the interval specified.</returns>
        public static T IntegralMonteCarloApproximation <T, C>(this IFunction <T, T> obj, IRandomBounded <T> generator, BoundedInterval <T, C> interval, T rectangleHeight, T throwsCount) where C : ICalc <T>, new()
        {
            ICalc <T> calc = Numeric <T, C> .Calculator;

            T         hits = calc.zero; // overall hits.
            Point <T> randomPoint;      // random point.

            if (!calc.mor(throwsCount, calc.zero))
            {
                throw new ArgumentException("The amount of point throws count should be a positive integer value.");
            }

            for (T i = calc.zero; calc.mor(throwsCount, i); i = calc.increment(i))
            {
                randomPoint = new Point <T>(generator.Next(interval.LeftBound, interval.RightBound), generator.Next(calc.zero, rectangleHeight));

                // Если попали под функцию - увеличиваем количество хитов.

                if (!calc.mor(randomPoint.Y, obj.Value(randomPoint.X)))
                {
                    hits = calc.increment(hits);
                }
            }

            T result = calc.div(calc.mul(calc.mul(interval.Length, rectangleHeight), hits), throwsCount);

            return(result);
        }
コード例 #11
0
        /// <summary>
        /// Adds elements to a collection by using a random number generator
        /// to create random numbers in the interval <c>[<paramref name="min"/>; <paramref name="max"/>)</c>.
        /// </summary>
        /// <remarks>
        /// The filling is made by <c>Add()</c> operation, which means, no existing
        /// elements of the collection will be modified by this method.
        /// </remarks>
        /// <typeparam name="T">The type of elements in the collection.</typeparam>
        /// <param name="collection">The collection reference.</param>
        /// <param name="elementCount">A number specifying how many elements should be added to the collection.</param>
        /// <param name="randomGenerator">A random generator.</param>
        /// <param name="min">The lower inclusive bound of numbers to be generated.</param>
        /// <param name="max">The upper exclusive bound of numbers to be generated.</param>
        public static void FillByAppending <T>(this ICollection <T> collection, int elementCount, IRandomBounded <T> randomGenerator, T min, T max)
        {
            Contract.Requires <ArgumentNullException>(collection != null, "collection");
            Contract.Requires <ArgumentNullException>(randomGenerator != null, "randomGenerator");
            Contract.Requires <ArgumentOutOfRangeException>(elementCount >= 0, "The element count should be a non-negative value.");

            for (int i = 0; i < elementCount; i++)
            {
                collection.Add(randomGenerator.Next(min, max));
            }
        }