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