コード例 #1
0
        /*
         *   if n < 1,373,653, it is enough to test a = 2 and 3;
         * if n < 9,080,191, it is enough to test a = 31 and 73;
         * if n < 4,759,123,141, it is enough to test a = 2, 7, and 61;
         * if n < 2,152,302,898,747, it is enough to test a = 2, 3, 5, 7, and 11;
         * if n < 3,474,749,660,383, it is enough to test a = 2, 3, 5, 7, 11, and 13;
         * if n < 341,550,071,728,321, it is enough to test a = 2, 3, 5, 7, 11, 13, and 17.
         *
         */

        /// <summary>
        /// Performs a Miller's deterministic prime test on a number.
        /// Goes over all numbers under the <c>floor(ln^2(<paramref name="num"/>))</c> boundary.
        /// </summary>
        /// <typeparam name="B">
        /// A class specifying the digit base of <c>LongInt&lt;<typeparamref name="B"/></c> type.
        /// The base should be an integer power of two.
        /// </typeparam>
        /// <remarks>This test relies upon Riemann's Generalized Hypothesis, which still remains unproven. Use with caution.</remarks>
        /// <param name="num">A number, bigger than 1, to test for primality.</param>
        /// <returns>True if the number is prime according to the test, false otherwise.</returns>
        public static bool IsPrime_Miller <B>(this LongInt <B> num)
            where B : IBase, new()
        {
            Contract.Requires <ArgumentException>(LongInt <B> .BASE_is_power_of_two, "The digit base of the number should be a strict power of two.");
            Contract.Requires <ArgumentNullException>(num != null, "num");
            Contract.Requires <ArgumentOutOfRangeException>(num > 1, "The tested number should be bigger than 1.");

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

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

            LongInt <B> t;
            long        s;

            LongInt <B> numDecremented = num - 1;

            ___millerRabinFactorize(numDecremented, out t, out s);

            LongInt <B> upperBound = WhiteMath <LongInt <B>, CalcLongInt <B> > .Min(num.LengthInBinaryPlaces *num.LengthInBinaryPlaces, numDecremented);

            for (LongInt <B> i = 2; i <= upperBound; i++)
            {
                if (!___millerRabinIsPrimeWitness(i, num, t, s))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #2
0
        /// <summary>
        /// Warning! Works correctly only for the MONOTONOUS (on the interval specified) function!
        /// Returns the bounded approximation of monotonous function's Riman integral.
        /// </summary>
        /// <typeparam name="T">The type of function argument/value.</typeparam>
        /// <typeparam name="C">The calculator for the argument type.</typeparam>
        /// <param name="obj">The calling function object.</param>
        /// <param name="interval">The interval to approximate the integral on.</param>
        /// <param name="pointCount">The overall point count used to approximate the integral value. The more this value is, the more precise is the calculation.</param>
        /// <returns>The interval in which the integral's value lies.</returns>
        public static BoundedInterval <T, C> IntegralRectangleBoundedApproximation <T, C>(this IFunction <T, T> obj, BoundedInterval <T, C> interval, int pointCount) where C : ICalc <T>, new()
        {
            ICalc <T> calc = Numeric <T, C> .Calculator;

            // Если интервал нулевой длины, то ваще забей.

            if (interval.IsZeroLength)
            {
                return(new BoundedInterval <T, C>(calc.zero, calc.zero, true, true));
            }

            // Если нет, то ваще не забей.

            Point <T>[] table = obj.GetFunctionTable <T, C>(interval, pointCount + 1);

            Numeric <T, C> step = calc.dif(table[2].X, table[0].X);

            Numeric <T, C> sumOne = calc.zero;
            Numeric <T, C> sumTwo = calc.zero;

            for (int i = 0; i < pointCount; i++)
            {
                if (i < pointCount - 1)
                {
                    sumOne += table[i].Y;
                }
                if (i > 0)
                {
                    sumTwo += table[i].Y;
                }
            }

            Numeric <T, C> res1 = sumOne * step;
            Numeric <T, C> res2 = sumTwo * step;

            return(new BoundedInterval <T, C>(WhiteMath <T, C> .Min(res1, res2), WhiteMath <T, C> .Max(res1, res2), true, true));
        }