Ejemplo n.º 1
0
        public static void baseConvert(IList <int> from, IList <int> to, int fromBase, int newBase)
        {
            // проверяем, не кратное ли основание

            int?power;

            if (WhiteMath <int, CalcInt> .IsNaturalIntegerPowerOf(fromBase, newBase, out power) ||
                WhiteMath <int, CalcInt> .IsNaturalIntegerPowerOf(newBase, fromBase, out power))
            {
                convertPowered(from, to, fromBase, newBase, power.Value);
            }

            // в противном случае - не избежать последовательного деления.

            else
            {
                int         k      = 0;
                IList <int> divide = from;

                while (divide.CountSignificant() > 1 || divide[0] > 0)
                {
                    int remainder;
                    divide = LongIntegerMethods.DivideByInteger(fromBase, divide, newBase, out remainder);

                    to[k++] = remainder;
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Gets the amount of polynom sequence's sign variations either
        /// at positive or negative infinity using polynom's degree and the sign of its higher coefficient.
        ///
        /// Works fast.
        /// </summary>
        /// <typeparam name="T">The type of polynom coefficients.</typeparam>
        /// <typeparam name="C">The calculator for the coefficients' type.</typeparam>
        /// <param name="list">The sequence of polynoms to be evaluated for sign variations.</param>
        /// <param name="negativeInfinity">If this flag is set to FALSE, the evalution is at positive infinity. Otherwise, at negative infinity.</param>
        /// <returns>The number of polynom's sign variations.</returns>
        public static int InfinitySignVariations <T, C>(this IList <Polynom <T, C> > list, bool negativeInfinity) where C : ICalc <T>, new()
        {
            int signPrev = 0;
            int signNew  = 0;
            int k        = 0;

            for (int i = 0; i < list.Count; i++)
            {
                if (list[i].Degree == 0)
                {
                    signNew = WhiteMath <T, C> .Sign(list[i][0]);
                }
                else
                {
                    signNew = WhiteMath <T, C> .Sign(list[i][list[i].Degree]) *
                              (negativeInfinity ? ((list[i].Degree % 2 == 0 ? 1 : -1)) : 1);
                }

                if (signNew == 0)
                {
                    continue;
                }
                else if (signNew != signPrev && signPrev != 0)
                {
                    k++;
                }

                signPrev = signNew;
            }

            return(k);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Cancels the polynom with integer coefficients by the greatest common divisor of
        /// its coefficients.
        ///
        /// The resulting polynom contains all the same roots, but its value range is less than
        /// of the current.
        ///
        /// If either some of the coefficients isn't integer or GCD = 1, the current polynom will be returned.
        /// <returns>The polynom with cancelled coefficients containing all the same roots.</returns>
        /// </summary>
        public Polynom <T, C> IntegerCoefficientsCancel()
        {
            ArgumentException ex = new ArgumentException("Only polynoms with integer coefficients can be cancelled.");

            if (coefficients[0].FractionalPart != Numeric <T, C> .Zero)
            {
                throw ex;
            }

            Numeric <T, C> gcd = coefficients[0];

            for (int i = 1; i < coefficients.Length; i++)
            {
                if (coefficients[i].FractionalPart != Numeric <T, C> .Zero)
                {
                    throw ex;
                }
                else
                {
                    gcd = WhiteMath <T, C> .GreatestCommonDivisor(gcd, coefficients[i]);
                }
            }

            Numeric <T, C>[] newCoefs = new Numeric <T, C> [coefficients.Length];

            for (int i = 0; i < coefficients.Length; i++)
            {
                newCoefs[i] = this.coefficients[i] / gcd;
            }

            return(new Polynom <T, C>(newCoefs));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Filters the surges in a sequence whose absolute values deviate from the specified positive value by a
        /// positive factor specified.
        /// </summary>
        /// <typeparam name="T">The type of elements in the incoming sequence.</typeparam>
        /// <typeparam name="C">The calculator for the sequence elements type.</typeparam>
        /// <param name="sequence">A calling sequence object.</param>
        /// <param name="centerValue">A nonnegative value. Sequence elements that deviate from this value by more than <paramref name="allowedDeviationFactor"/> will be filtered out.</param>
        /// <param name="allowedDeviationFactor">The allowed factor of absolute deviation.</param>
        /// <param name="deviationType">
        /// If deviation type is Downwards, values which are smaller than <paramref name="centerValue"/>
        /// by a factor of <paramref name="allowedDeviationFactor"/> will be filtered.
        /// If deviation type is Upwards, values which are bigger than <paramref name="centerValue"/>
        /// by a factor of <paramref name="allowedDeviationFactor"/> will be filtered.
        /// If deviation type is EitherSide, all values that differ from the <paramref name="centerValue"/>
        /// by a factor of <paramref name="allowedDeviationFactor"/> will be filtered.
        /// </param>
        /// <param name="filteredValues">A reference to a collection to store the filtered values. May be null.</param>
        /// <returns>The list containing all incoming values except for the filtered ones.</returns>
        public static List <T> filterSurgesByAbsoluteFactorDeviationFromValue <T, C>(this IEnumerable <T> sequence, T centerValue, double allowedDeviationFactor, DeviationType deviationType = DeviationType.EitherSide, ICollection <T> filteredValues = null) where C : ICalc <T>, new()
        {
            ICalc <T> calc = Numeric <T, C> .Calculator;

            (centerValue > Numeric <T, C> .Zero).Assert(new ArgumentException("The center value specified should be positive."));
            (allowedDeviationFactor > 0).Assert(new ArgumentException("The allowed deviation factor should be positive."));

            List <T> result = new List <T>();

            foreach (Numeric <T, C> current in sequence)
            {
                Numeric <T, C> absCurrent = WhiteMath <T, C> .Abs(current);

                Numeric <T, C> multipliedValue   = (Numeric <T, C>)allowedDeviationFactor * centerValue;
                Numeric <T, C> multipliedCurrent = (Numeric <T, C>)allowedDeviationFactor * absCurrent;

                if (deviationType == DeviationType.EitherSide && (absCurrent > multipliedValue || multipliedCurrent < centerValue) ||
                    deviationType == DeviationType.Upwards && absCurrent > multipliedValue ||
                    deviationType == DeviationType.Downwards && multipliedCurrent < centerValue)
                {
                    // Filter the surge.

                    if (filteredValues != null)
                    {
                        filteredValues.Add(current);
                    }
                }
                else
                {
                    result.Add(current);
                }
            }

            return(result);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Returns the maximum error for the Simpson integral approximation method
        /// depending on the interval on which the calculation is performed,
        /// the maximum absolute value of the function's fourth derivative and the point count (should be even).
        /// </summary>
        /// <typeparam name="T">The type of function argument/value.</typeparam>
        /// <typeparam name="C">The calculator for the function argument.</typeparam>
        /// <param name="obj">The calling function object. Is not actually used.</param>
        /// <param name="interval">The interval on which the calculation is performed. No matter if bounds are exclusive, they are considered INCLUSIVE.</param>
        /// <param name="pointCount">The point count on the interval.</param>
        /// <param name="maxFourthDerivative">The maximum absolute value of the function's fourth derivative.</param>
        /// <returns>The maximum error of the simpson method.</returns>
        public static T IntegralSimpsonMethodError <T, C>(this IFunction <T, T> obj, BoundedInterval <T, C> interval, int pointCount, T maxFourthDerivative) where C : ICalc <T>, new()
        {
            Numeric <T, C> big     = (Numeric <T, C>) 2880;
            Numeric <T, C> hFourth = WhiteMath <T, C> .PowerInteger((interval.RightBound - interval.LeftBound) / (Numeric <T, C>)(pointCount / 2), 4);

            return((interval.RightBound - interval.LeftBound) * hFourth * maxFourthDerivative / big);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Calculates the sample unbiased variation for a sequence of observations.
        /// </summary>
        /// <typeparam name="T">The type of observations' values.</typeparam>
        /// <typeparam name="C">A calculator for the <typeparamref name="T"/> type.</typeparam>
        /// <param name="values">The sequence of observations.</param>
        /// <param name="sampleAverage">The sample average for the observations sequence.</param>
        /// <returns>The sample unbiased variation for the sequence of observations.</returns>
        public static T SampleUnbiasedVariance <T, C>(this IEnumerable <T> values, T sampleAverage) where C : ICalc <T>, new()
        {
            Contract.Requires <ArgumentNullException>(values != null, "values");
            Contract.Ensures(Contract.Result <T>() >= Numeric <T, C> ._0, "The variance should not be negative.");

            int count = values.Count();

            if (count == 0)
            {
                throw new ArgumentException("Cannot calculate the sample variance for an empty sequence.");
            }
            else if (count == 1)
            {
                return(Numeric <T, C> .Zero);
            }

            Numeric <T, C> sum  = Numeric <T, C> .Zero;
            ICalc <T>      calc = Numeric <T, C> .Calculator;

            foreach (T value in values)
            {
                sum += WhiteMath <T, C> .PowerInteger(calc.dif(value, sampleAverage), 2);
            }

            return(sum / (Numeric <T, C>)(values.Count() - 1));
        }
Ejemplo n.º 7
0
        public static Func <T, T> SigmoidFunction <T, C>(T exponentDelta, int taylorMemberCount = 100) where C : ICalc <T>, new()
        {
            return(delegate(T x)
            {
                ICalc <T> calc = Numeric <T, C> .Calculator;
                T temp = WhiteMath <T, C> .Exponent(calc.mul(exponentDelta, x), taylorMemberCount);

                return Numeric <T, C> ._1 / (Numeric <T, C> ._1 + temp);
            });
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Calculates a public exponent on the basis of
        /// a pair of primes which form the RSA secret key and
        /// the number chosen as public exponent.
        /// </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="secretKey">A pair of primes which form the RSA secret key.</param>
        /// <returns>The secret exponent of the RSA algorithm.</returns>
        public static LongInt <B> GetSecretExponent <B>(Point <LongInt <B> > secretKey, LongInt <B> publicExponent)
            where B : IBase, new()
        {
            Contract.Requires <ArgumentNullException>(publicExponent != null, "publicExponent");
            Contract.Requires <ArgumentNullException>(secretKey.X != null, "secretKey.X");
            Contract.Requires <ArgumentNullException>(secretKey.Y != null, "secretKey.Y");

            LongInt <B> totient = LongInt <B> .Helper.MultiplyFFTComplex(secretKey.X - 1, secretKey.Y - 1);

            return
                (WhiteMath <LongInt <B>, CalcLongInt <B> > .MultiplicativeInverse(publicExponent, totient));
        }
Ejemplo n.º 9
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));
        }
Ejemplo n.º 10
0
            /// <summary>
            /// Returns the first half of the [rootDegree]th roots of unity series in the BigInteger field.
            /// Used in the recursive FFT algorithm in LongInt.Helper class.
            ///
            /// Root degree should be an exact power of two.
            /// </summary>
            /// <param name="rootDegree"></param>
            /// <returns></returns>
            public static BigInteger[] rootsOfUnityHalfGalois(int rootDegree, bool inverted)
            {
                Contract.Requires <ArgumentOutOfRangeException>(rootDegree > 0, "The degree of the root should be a positive power of two.");
                Contract.Ensures(
                    Contract.ForAll(
                        Contract.Result <BigInteger[]>(),
                        (x => WhiteMath <BigInteger, CalcBigInteger> .PowerIntegerModular(x, (ulong)rootDegree, NTT_MODULUS) == 1)));

                BigInteger[] result = new BigInteger[rootDegree / 2];

                // The first root of unity is obviously one.
                // -
                result[0] = 1;

                // Now we will learn what k it is in rootDegree == 2^k
                // -
                int rootDegreeCopy     = rootDegree;
                int rootDegreeExponent = 0;

                while (rootDegreeCopy > 1)
                {
                    rootDegreeCopy /= 2;
                    ++rootDegreeExponent;
                }

                // Now we obtain the principal 2^rootDegreeExponent-th root of unity.
                // -
                BigInteger principalRoot = WhiteMath <BigInteger, CalcBigInteger> .PowerIntegerModular(
                    NTT_MAX_ROOT_OF_UNITY_2_30,
                    WhiteMath <ulong, CalcULong> .PowerInteger(2, NTT_MAX_ROOT_OF_UNITY_DEGREE_EXPONENT - rootDegreeExponent),
                    NTT_MODULUS);

                // Calculate the desired roots of unity.
                // -
                for (int i = 1; i < rootDegree / 2; i++)
                {
                    // All the desired roots of unity are obtained as powers of the principal root.
                    // -
                    result[i] = result[i - 1] * principalRoot % NTT_MODULUS;
                }

                // If performing the inverse NTT, we should invert the roots.
                // -
                if (inverted)
                {
                    for (int i = 0; i < rootDegree / 2; ++i)
                    {
                        result[i] = WhiteMath <BigInteger, CalcBigInteger> .MultiplicativeInverse(result[i], NTT_MODULUS);
                    }
                }

                return(result);
            }
Ejemplo n.º 11
0
        /// <summary>
        /// TODO: write description
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="C"></typeparam>
        /// <param name="obj"></param>
        /// <param name="interval"></param>
        /// <param name="maxError"></param>
        /// <param name="maxFourthDerivative"></param>
        /// <returns></returns>
        public static T IntegralSimpsonNeededPointCount <T, C>(this IFunction <T, T> obj, BoundedInterval <T, C> interval, T maxError, T maxFourthDerivative) where C : ICalc <T>, new()
        {
            // N^4 степени.
            Numeric <T, C> nFourth = (Numeric <T, C>)maxFourthDerivative * WhiteMath <T, C> .PowerInteger(interval.RightBound - interval.LeftBound, 5) / (maxError * (Numeric <T, C>) 2880);

            // TODO: почему 100 членов в ряде тейлора?
            // надо вычислять точность.

            Numeric <T, C> power = (Numeric <T, C>) 0.25;
            Numeric <T, C> n     = WhiteMath <T, C> .SquareRootHeron(WhiteMath <T, C> .SquareRootHeron(nFourth, maxError), maxError);

            return(Numeric <T, C> ._2 * WhiteMath <T, C> .Ceiling(n));
        }
Ejemplo n.º 12
0
            /// <summary>
            /// Returns the first half of the [rootDegree]th roots of unity series in the BigInteger field.
            /// Used in the recursive FFT algorithm in LongInt.Helper class.
            ///
            /// Root degree should be an exact power of two.
            /// </summary>
            /// <param name="rootDegree"></param>
            /// <returns></returns>
            internal static BigInteger[] rootsOfUnityHalfGalois(
                NTTFiniteFieldInfo finiteFieldInfo,
                int rootDegree,
                bool inverted)
            {
                Contract.Requires <ArgumentOutOfRangeException>(rootDegree > 0, "The degree of the root should be a positive power of two.");
                Contract.Ensures(
                    Contract.ForAll(
                        Contract.Result <BigInteger[]>(),
                        (x => WhiteMath <BigInteger, CalcBigInteger> .PowerIntegerModular(x, (ulong)rootDegree, finiteFieldInfo.primeModulus) == 1)));

                BigInteger[] result = new BigInteger[rootDegree / 2];

                // The first root of unity is obviously one,
                // but we start with -1 if we need the inverse roots.
                // -
                if (!inverted)
                {
                    result[0] = 1;
                }
                else
                {
                    result[0] = finiteFieldInfo.primeModulus - 1;
                }

                // Calculate the desired roots of unity.
                // -
                for (int i = 1; i < rootDegree / 2; ++i)
                {
                    // All the desired roots of unity are obtained as powers of the principal root.
                    // -
                    result[i] = result[i - 1] * finiteFieldInfo.rootOfUnity % finiteFieldInfo.primeModulus;
                }

                // If performing the inverse NTT, we should reverse the array along
                // with a magic shift by 1 to get the inverted roots in the necessary order.
                //
                if (inverted)
                {
                    result[0] = 1;

                    for (int i = 1; i < rootDegree / 4; ++i)
                    {
                        result.Swap(i, rootDegree / 2 - i);
                    }
                }

                return(result);
            }
Ejemplo n.º 13
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);
        }
Ejemplo n.º 14
0
            /// <summary>
            /// BACK FFT
            /// </summary>
            /// <param name="coefficients"></param>
            /// <returns></returns>
            internal static BigInteger[] Recursive_NTT_Inverse(IList <BigInteger> coefficients)
            {
                int n = coefficients.Count;

                BigInteger[] rootsHalf = rootsOfUnityHalfGalois(n, true);
                BigInteger[] result    = Recursive_NTT_Skeleton(coefficients, rootsHalf, 1, 0);

                // We should multiply the result by the multiplicative inverse of length.
                // -
                BigInteger lengthMultiplicativeInverse =
                    WhiteMath <BigInteger, CalcBigInteger> .MultiplicativeInverse(n, NTT_MODULUS);

                for (int i = 0; i < result.Length; i++)
                {
                    result[i] = (result[i] * lengthMultiplicativeInverse) % NTT_MODULUS;
                }

                return(result);
            }
Ejemplo n.º 15
0
            /// <summary>
            /// BACK FFT
            /// </summary>
            /// <param name="coefficients"></param>
            /// <returns></returns>
            internal static BigInteger[] Recursive_NTT_Inverse(
                IList <BigInteger> coefficients,
                NTTFiniteFieldInfo finiteFieldInfo)
            {
                int n = coefficients.Count;

                BigInteger[] rootsHalf = rootsOfUnityHalfGalois(finiteFieldInfo, n, true);
                BigInteger[] result    = Recursive_NTT_Skeleton(coefficients, rootsHalf, finiteFieldInfo, 1, 0);

                // We should multiply the result by the multiplicative inverse of length
                // in contrast to the forward-NTT.
                // -
                BigInteger lengthMultiplicativeInverse =
                    WhiteMath <BigInteger, CalcBigInteger> .MultiplicativeInverse(n, finiteFieldInfo.primeModulus);

                for (int i = 0; i < result.Length; i++)
                {
                    result[i] = (result[i] * lengthMultiplicativeInverse) % finiteFieldInfo.primeModulus;
                }

                return(result);
            }
Ejemplo n.º 16
0
        /// <summary>
        /// Adds relative (factor) surges from a symmetric distribution random generator to each value of a numeric sequence
        /// and returns the nosiy sequence in the form of a list.
        /// </summary>
        /// <typeparam name="T">The type of elements in the numeric sequence.</typeparam>
        /// <typeparam name="C">The calculator for the <typeparamref name="T"/> type.</typeparam>
        /// <param name="sequence">The calling numeric sequence object.</param>
        /// <param name="symmetricDistributionGenerator">A random generator providing values of some symmetric distribution.</param>
        /// <param name="deviationType">Which deviations (positive, negative or both) should be added to the sequence.</param>
        /// <returns></returns>
        public static List <T> addRelativeSurgesFromSymmetricDistribution <T, C>(this IEnumerable <T> sequence, IRandomUnbounded <T> symmetricDistributionGenerator, DeviationType deviationType) where C : ICalc <T>, new()
        {
            List <T> result = new List <T>(sequence.Count());

            foreach (Numeric <T, C> value in sequence)
            {
                if (deviationType == DeviationType.EitherSide)
                {
                    result.Add(value + value * symmetricDistributionGenerator.Next());
                }
                else if (deviationType == DeviationType.Downwards)
                {
                    result.Add(value - WhiteMath <T, C> .Abs(value * symmetricDistributionGenerator.Next()));
                }
                else
                {
                    result.Add(value + WhiteMath <T, C> .Abs(value * symmetricDistributionGenerator.Next()));
                }
            }

            return(result);
        }
Ejemplo n.º 17
0
        // --------------------------------------------
        // --------- ЗНАК ФУНКЦИИ ---------------------
        // --------------------------------------------

        /// <summary>
        /// Returns the number of sign variations in the function list for some certain
        /// point.
        /// </summary>
        /// <typeparam name="T">The type of polynom coefficients.</typeparam>
        /// <typeparam name="C">The type of polynom coefficients' calculator.</typeparam>
        /// <param name="list">The list of the polynoms to be analyzed.</param>
        /// <returns>The number of sign variations within the list. Zero values do not count.</returns>
        public static int SignVariations <T, C>(this IList <IFunction <T, T> > list, Numeric <T, C> point) where C : ICalc <T>, new()
        {
            int signPrev = 0;
            int signNew  = 0;
            int k        = 0;

            for (int i = 0; i < list.Count; i++)
            {
                signNew = WhiteMath <T, C> .Sign(list[i].Value(point));

                if (signPrev == 0)
                {
                    if (signNew != 0)
                    {
                        k++;
                    }
                    else
                    {
                        continue;
                    }
                }
                else if (signPrev < 0 || signPrev > 0)
                {
                    if (signNew != 0)
                    {
                        k++;
                    }
                    else
                    {
                        continue;
                    }
                }

                signPrev = signNew;
            }

            return(k);
        }
Ejemplo n.º 18
0
            /// <summary>
            /// For debug purposes. Performs the NTT in a straightforward (quadratic) manner.
            /// </summary>
            internal static BigInteger[] __DB_Quadratic_NTT(IList <BigInteger> coefficients, bool back = false)
            {
                BigInteger[] rootsOfUnity = __DB__rootsOfUnityGalois(coefficients.Count, back);
                BigInteger[] result       = new BigInteger[coefficients.Count];

                for (int i = 0; i < rootsOfUnity.Length; ++i)
                {
                    BigInteger currentRoot = rootsOfUnity[i];

                    BigInteger hornerResult = 0;

                    for (int j = coefficients.Count - 1; j >= 0; --j)
                    {
                        hornerResult = (hornerResult * currentRoot + coefficients[j]) % NTT_MODULUS;
                    }

                    result[i] =
                        hornerResult *
                        (back ? WhiteMath <BigInteger, CalcBigInteger> .MultiplicativeInverse(coefficients.Count, NTT_MODULUS) : 1) % NTT_MODULUS;
                }

                return(result);
            }
Ejemplo n.º 19
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));
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Filters the surges in a sequence whose absolute values deviate from the specified positive value by a
        /// nonnegative value specified.
        /// </summary>
        /// <typeparam name="T">The type of elements in the incoming sequence.</typeparam>
        /// <typeparam name="C">The calculator for the sequence elements type.</typeparam>
        /// <param name="sequence">A calling sequence object.</param>
        /// <param name="centerValue">Some value. Sequence elements that deviate from this value by more than <paramref name="allowedEpsilon"/> will be filtered out.</param>
        /// <param name="allowedEpsilon">The allowed nonnegative value of deviation from <paramref name="centerValue"/>.</param>
        /// <param name="deviationType">
        /// If deviation type is Downwards, values which are smaller than <paramref name="centerValue"/>
        /// by <paramref name="allowedEpsilon"/> will be filtered.
        /// If deviation type is Upwards, values which are bigger than <paramref name="centerValue"/>
        /// by <paramref name="allowedEpsilon"/> will be filtered.
        /// If deviation type is EitherSide, all values that differ from the <paramref name="centerValue"/>
        /// by <paramref name="allowedEpsilon"/> will be filtered.
        /// </param>
        /// <param name="filteredValues">A reference to a collection to store the filtered values. May be null.</param>
        /// <returns>The list containing all incoming values except for the filtered ones.</returns>
        public static List <T> filterSurgesByEpsilonDeviationFromValue <T, C>(this IEnumerable <T> sequence, T centerValue, T allowedEpsilon, DeviationType deviationType = DeviationType.EitherSide, ICollection <T> filteredValues = null) where C : ICalc <T>, new()
        {
            ICalc <T> calc = Numeric <T, C> .Calculator;

            (allowedEpsilon >= Numeric <T, C> .Zero).Assert(new ArgumentException("Allowed deviation epsilon should be a non-negative value."));

            List <T> result = new List <T>();

            foreach (Numeric <T, C> current in sequence)
            {
                if (deviationType == DeviationType.EitherSide && WhiteMath <T, C> .Abs(centerValue - current) < (Numeric <T, C>)allowedEpsilon ||
                    deviationType == DeviationType.Downwards && centerValue - current < allowedEpsilon ||
                    deviationType == DeviationType.Upwards && current - centerValue < allowedEpsilon)
                {
                    result.Add(current);
                }
                else if (filteredValues != null)
                {
                    filteredValues.Add(current);
                }
            }

            return(result);
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Returns the string representation of the polynomial function
        /// as an array of coefficients - or, in the functional form
        /// i.e. 'f(x) = ...'.
        /// </summary>
        /// <param name="type">The type of the string representation.</param>
        /// <returns>The string representation of the current object.</returns>
        public string ToString(PolynomStringRepresentationType type)
        {
            if (type == PolynomStringRepresentationType.Coefficients)
            {
                string coefString = "";

                for (int i = 0; i < coefficients.Length; i++)
                {
                    coefString += "|" + this.coefficients[i].ToString();
                }

                coefString += "|";

                return(coefString);
            }
            else
            {
                string functionString = "f(x) = ";

                Numeric <T, C> one = calc.fromInt(1);

                for (int i = coefficients.Length - 1; i > 0; i--)
                {
                    if (coefficients[i] != Numeric <T, C> .Zero)
                    {
                        functionString += string.Format("{0}{1}x{2}", (coefficients[i] >= calc.zero ? (i < coefficients.Length - 1?" + ":"") : (i < coefficients.Length - 1?" - ":"-")), (coefficients[i] != one ? WhiteMath <T, C> .Abs(coefficients[i]).ToString() : ""), (i == 1 ? "" : "^" + i.ToString()));
                    }
                }

                if (coefficients[0] != Numeric <T, C> .Zero)
                {
                    functionString += string.Format(" {0} {1} ", (coefficients[0] > Numeric <T, C> .Zero ? "+" : "-"), WhiteMath <T, C> .Abs(coefficients[0]));
                }

                return(functionString);
            }
        }
Ejemplo n.º 22
0
        // ------------------- FACTORIZATION ----------------------------

        /// <summary>
        /// Preforms the LUP-factorization of a matrix (let it be A)
        /// in the form of:
        ///
        /// P*A = L*U.
        ///
        /// The P is an identity matrix with a plenty of row inversions.
        /// For the economy of space it is provided as a single-dimensional array of integers:
        ///
        /// (0, 1, 2, 3, ..., n).
        ///
        /// Element indices of this array stand for matrix rows, and elements value
        /// mean the position of '1' in a row.
        ///
        /// Requirements: works for any square and nonsingular matrix (having a non-zero determinant).
        /// If these requirements aren't met, either a MatrixSingularException or a MatrixSizeException
        /// would be thrown.
        /// </summary>
        /// <param name="C">The matrix C containing L + U - E. It is clear that both L and U can be easily extracted from this matrix.</param>
        /// <param name="P">The identity matrix with a plenty of row inversions in the form of array.</param>
        public void LUP_Factorization(out int[] P, out Matrix_SDA <T, C> C)
        {
            if (this.rows != this.columns)
            {
                throw new MatrixSizeException("The matrix is not square an thus cannot be factorized.");
            }

            int n = this.rows;  // размер матрицы

            C = new Matrix_SDA <T, C>(n, n);

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    C.setItemAt(i, j, this.getItemAt(i, j));
                }
            }

            P = new int[n];
            P.FillByAssign(delegate(int i) { return(i); });

            // ----- пошел ----------

            Numeric <T, C> pivot;
            Numeric <T, C> abs;

            int pivotIndex;

            for (int i = 0; i < n; i++)
            {
                pivot      = Numeric <T, C> .Zero;
                pivotIndex = -1;

                for (int row = i; row < n; row++)
                {
                    abs = WhiteMath <T, C> .Abs(this.getItemAt(row, i));

                    if (abs > pivot)
                    {
                        pivot      = abs;
                        pivotIndex = row;
                    }
                }

                if (pivot == Numeric <T, C> .Zero)
                {
                    throw new MatrixSingularityException("The matrix is singular. It cannot be factorized.");
                }

                if (pivotIndex != i)
                {
                    P.Swap(pivotIndex, i);
                    C.swapRows(pivotIndex, i);
                }

                try
                {
                    for (int j = i + 1; j < n; j++)
                    {
                        C.setItemAt(j, i, C.getItemAt(j, i) / C.getItemAt(i, i));

                        if (Numeric <T, C> .isInfinity(C.getItemAt(j, i)) || Numeric <T, C> .isNaN(C.getItemAt(j, i)))
                        {
                            throw new DivideByZeroException();
                        }

                        for (int k = i + 1; k < n; k++)
                        {
                            C.setItemAt(j, k, C.getItemAt(j, k) - C.getItemAt(j, i) * C.getItemAt(i, k));
                        }
                    }
                }
                catch (DivideByZeroException)
                {
                    throw new MatrixSingularityException("The matrix is singular. It cannot be factorized.");
                }
            }

            return;
        }
Ejemplo n.º 23
0
        // --------- this is the key to happiness

        private static T _PositiveLagrangeBound(IList <Numeric <T, C> > coefficients, Func <int, Numeric <T, C>, Numeric <T, C> > selector)
        {
            // нули в начале нам совсем не нужны.

            int minus = 1;

            while (coefficients[coefficients.Count - minus] == Numeric <T, C> .Zero)
            {
                minus++;

                if (minus > coefficients.Count)
                {
                    throw new ArgumentException("This polynom contains only zero coefficients. Cannot evaluate the finite roots interval.");
                }
                // todo - return INFINITY.
            }

            // ------- начальный коэффициент - меньше нуля?
            // заменяем функцию g(x) = -f(x) и сохраняем корни и нервы.

            if (selector(coefficients.Count - minus, coefficients[coefficients.Count - minus]) < Numeric <T, C> .Zero)
            {
                object     target = selector.Target;
                MethodInfo method = selector.Method;

                selector = delegate(int i, Numeric <T, C> obj) { return(-(Numeric <T, C>)method.Invoke(target, new object[] { i, obj })); };
            }

            // -----------------

            T nCoef = coefficients[coefficients.Count - minus];

            T cur;

            T one = calc.fromInt(1);
            T max = calc.zero;

            int  index = -1;        // индекс первого отрицательного коэффициента
            bool found = false;     // найдены ли отрицательные коэффициенты!

            for (int i = coefficients.Count - minus; i >= 0; i--)
            {
                cur = selector(i, coefficients[i]);

                if (!found && calc.mor(calc.zero, cur))
                {
                    found = true;
                    index = coefficients.Count - i - minus;
                }

                // -- здесь cur больше не нужна, а нужно только ее
                // абсолютное значение. его и используем.

                cur = WhiteMath <T, C> .Abs(cur);

                if (calc.mor(cur, max))
                {
                    max = cur;
                }
            }

            if (!found)
            {
                return(calc.zero);
            }

            return(calc.sum(one, WhiteMath <T, C> .Power(calc.div(max, WhiteMath <T, C> .Abs(nCoef)), calc.div(one, calc.fromInt(index)))));
        }