/* * 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<<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); }
/// <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)); }