Example #1
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);
        }
Example #2
0
        /// <summary>
        /// Returns the runs test series count for a sequence of observations.
        /// The sample median for that sequence must first be calculated.
        /// </summary>
        /// <typeparam name="T">The type of observations' values.</typeparam>
        /// <typeparam name="C">The calculator for the <typeparamref name="T"/> type.</typeparam>
        /// <param name="values">The list of observations.</param>
        /// <param name="sampleMedian">The sample median of the observations' sequence.</param>
        /// <returns>The amount of series for the runs test.</returns>
        public static int RunsTest_SeriesCount <T, C>(this IEnumerable <T> values, T sampleMedian) where C : ICalc <T>, new()
        {
            int count = values.Count();

            if (count == 0)
            {
                throw new ArgumentException("Cannot return the series count for an empty sequence.");
            }
            else if (count == 1)
            {
                return(0);
            }

            int signChanges = 0;

            IEnumerator <T> enumerator = values.GetEnumerator();
            ICalc <T>       calc       = Numeric <T, C> .Calculator;

            enumerator.MoveNext();

            // Find the first value not equal to the median.
            // -
            while (calc.eqv(enumerator.Current, sampleMedian))
            {
                if (enumerator.MoveNext() == false)
                {
                    return(0);
                }
            }

            bool isPlus = calc.mor(enumerator.Current, sampleMedian);

            while (enumerator.MoveNext())
            {
                if (!isPlus && calc.mor(enumerator.Current, sampleMedian))
                {
                    signChanges++;
                    isPlus = true;
                }
                else if (isPlus && calc.mor(sampleMedian, enumerator.Current))
                {
                    signChanges++;
                    isPlus = false;
                }
            }

            return(signChanges + 1);
        }
Example #3
0
        // -----------------------------------
        // ----- constructors ----------------
        // -----------------------------------

        /// <summary>
        /// Creates a new instance of an interval.
        /// </summary>
        /// <param name="left">The leftmost interval bound.</param>
        /// <param name="leftInclusive">The flag determining whether the leftmost bound is included into the interval.</param>
        /// <param name="right">The rightmost interval bound.</param>
        /// <param name="rightInclusive">The flag determining whether the rightmost bound is included into the interval.</param>
        public BoundedInterval(T left, T right, bool leftInclusive = false, bool rightInclusive = false) : this()
        {
            if (!calc.mor(right, left))
            {
                if (calc.mor(left, right))
                {
                    throw new ArgumentException("The lower interval bound exceeds the upper interval bound.");
                }
                else if (leftInclusive != rightInclusive)
                {
                    throw new ArgumentException("The interval contains at most one point, but the bounds' inclusiveness is inconsistent. Please check.");
                }
            }

            LeftBound       = left;
            IsLeftInclusive = leftInclusive;

            RightBound       = right;
            IsRightInclusive = rightInclusive;
        }
Example #4
0
        // --------------------------------------------
        // --------- РАВЕНСТВО ФУНКЦИЙ ----------------
        // --------------------------------------------

        /// <summary>
        /// Checks whether the current function is equal to another at least within the
        /// finite set of points.
        /// </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.</param>
        /// <param name="another">The function object to test equality with.</param>
        /// <param name="epsilon">The upper epsilon bound of 'equality' criteria. If |f(x) - g(x)| &lt; eps, two functions are considered equal.</param>
        /// <param name="points">The points list to test equality on.</param>
        /// <returns>True if the functions are epsilon-equal within the points list passed, false otherwise.</returns>
        public static bool PointwiseEquals <T, C>(this IFunction <T, T> obj, IFunction <T, T> another, T epsilon, IList <T> points) where C : ICalc <T>, new()
        {
            Func <T, T> abs  = WhiteMath <T, C> .Abs;
            ICalc <T>   calc = Numeric <T, C> .Calculator;

            for (int i = 0; i < points.Count; i++)
            {
                if (!calc.mor(epsilon, abs(calc.dif(obj.Value(points[i]), another.Value(points[i])))))
                {
                    return(false);
                }
            }

            return(true);
        }
Example #5
0
 /// <summary>
 /// Tests whether a number is negative according to the calling calculator object.
 /// </summary>
 public static bool isNegative <T>(this ICalc <T> calculator, T num)
 {
     return(calculator.mor(calculator.zero, num));
 }
Example #6
0
 /// <summary>
 /// Tests whether a number is positive according to the calling calculator object.
 /// </summary>
 public static bool isPositive <T>(this ICalc <T> calculator, T num)
 {
     return(calculator.mor(num, calculator.zero));
 }
Example #7
0
        /// <summary>
        /// Searches for the function maximum/minimum. using the ternary search method.
        ///
        /// Conditions:
        /// 1a. If one searches for the maximum, f(x) should be STRICTLY increasing before the maximum and STRICTLY decreasing after the maximum.
        /// 1b. If one searches for the minimum, f(x) should be STRICTLY decreasing before the minimum and STRICTLY increasing after the minimum.
        /// 1*. Only one maximum/minimum should exist on the interval.
        /// </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.</param>
        /// <param name="interval">The interval on which the maximum lies.</param>
        /// <param name="absolutePrecision">The desired precision of the argument value.</param>
        /// <param name="what">What to search for, maximum or minimum. Should be of 'SearchFor' enum type.</param>
        /// <returns>The 'x0' value such that f(x0) ~= max f(x) on the interval.</returns>
        public static T MaximumSearchTernaryMethod <T, C>(this IFunction <T, T> obj, BoundedInterval <T, C> interval, T absolutePrecision, SearchFor what) where C : ICalc <T>, new()
        {
            Numeric <T, C> left  = interval.LeftBound;
            Numeric <T, C> right = interval.RightBound;

            Numeric <T, C> leftThird;
            Numeric <T, C> rightThird;

            Numeric <T, C> two   = (Numeric <T, C>) 2;
            Numeric <T, C> three = (Numeric <T, C>) 3;

            Numeric <T, C> funcValLT, funcValRT;

            ICalc <T>         calc = Numeric <T, C> .Calculator;
            Func <T, T, bool> test = (what == SearchFor.Maximum ? (Func <T, T, bool>) delegate(T a, T b) { return(calc.mor(b, a)); } : calc.mor);

            while (true)
            {
                if (right - left < absolutePrecision)
                {
                    return((left + right) / two);
                }

                leftThird  = (left * two + right) / three;
                rightThird = (left + two * right) / three;

                funcValLT = obj.Value(leftThird);
                funcValRT = obj.Value(rightThird);

                if (test(funcValLT, funcValRT))
                {
                    left = leftThird;
                }
                else
                {
                    right = rightThird;
                }
            }
        }
Example #8
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)))));
        }