Ejemplo n.º 1
0
        public double Integration(FormulaExecutor integrand, double a, double b, double eps)
        {
            //заменим особые предельные точки на точки из окрестности
            if (Double.IsNaN(integrand.Execute(a)) || Double.IsInfinity(integrand.Execute(a)))
            {
                a += 0.0001 * eps * (b - a);
            }
            if (Double.IsNaN(integrand.Execute(b)) || Double.IsInfinity(integrand.Execute(b)))
            {
                b -= 0.0001 * eps * (b - a);
            }
            //последовательно посчитаем производные до 4 порядка на 100 точках
            int n = 1000;

            //первая производная
            double[] deriv = new double[n];
            deriv[0] = (integrand.Execute(a + (b - a) / (n - 1)) - integrand.Execute(a)) / ((b - a) / (n - 1));
            for (int i = 1; i < n; ++i)
            {
                deriv[i] = (integrand.Execute(a + i * (b - a) / (n - 1)) - integrand.Execute(a + (i - 1) * (b - a) / (n - 1))) / ((b - a) / (n - 1));
            }
            //вторая производная
            double[] secDeriv = new double[n];
            secDeriv[0] = (deriv[1] - deriv[0]) / ((b - a) / (n - 1));
            for (int i = 1; i < n; ++i)
            {
                secDeriv[i] = (deriv[i] - deriv[i - 1]) / ((b - a) / (n - 1));
            }
            //третья производная
            double[] thirdDeriv = new double[n];
            thirdDeriv[0] = (secDeriv[1] - secDeriv[0]) / ((b - a) / (n - 1));
            for (int i = 1; i < n; ++i)
            {
                thirdDeriv[i] = (secDeriv[i] - secDeriv[i - 1]) / ((b - a) / (n - 1));
            }
            //четвертая производная
            double[] fourthDeriv = new double[n];
            fourthDeriv[0] = (thirdDeriv[1] - thirdDeriv[0]) / ((b - a) / (n - 1));
            double maxFourthDeriv = Math.Abs(fourthDeriv[0]);

            for (int i = 1; i < n; ++i)
            {
                fourthDeriv[i] = (thirdDeriv[i] - thirdDeriv[i - 1]) / ((b - a) / (n - 1));
                if (Math.Abs(fourthDeriv[i]) > maxFourthDeriv)
                {
                    maxFourthDeriv = Math.Abs(fourthDeriv[i]);
                }
            }
            //определим шаг разбиения h для метода
            double h = (b - a) / Math.Ceiling(Math.Pow(maxFourthDeriv * Math.Pow(b - a, 5) / (2880 * eps), 0.25));
            //найдем значение интеграла
            double sum = 0;

            for (int i = 0; i *h < (b - a); ++i)
            {
                sum += h / 6 * (integrand.Execute(a + i * h) + 4 * integrand.Execute(a + i * h + h / 2) + integrand.Execute(a + (i + 1) * h));
            }
            return(sum);
        }
Ejemplo n.º 2
0
        private (int time, bool hasSpecialCharacter) ParseCalculationPattern(Time time, string calculationPattern)
        {
            var splittedPattern = calculationPattern.Split(':');

            if (splittedPattern.Length != 2)
            {
                throw new FormatException("Calculation format. Expected [S].");
            }

            var timePattern  = splittedPattern.FirstOrDefault();
            int concreteTime = GetTimeFromTimePattern(time, timePattern);

            var formulaPattern = splittedPattern.LastOrDefault();

            IFormulaExecutor formula = new FormulaExecutor();

            (int formulaResult, int formulaValue, string specialCharacter) = formula.Execute(concreteTime, formulaPattern);

            if (specialCharacter == null)
            {
                SubtractTime(time, formulaValue * formulaResult, timePattern);
            }

            return(formulaResult, specialCharacter != null);
        }
Ejemplo n.º 3
0
        public double Integration(FormulaExecutor integrand, double a, double b, double eps)
        {
            //заменим особые предельные точки на точки из окрестности
            if (Double.IsNaN(integrand.Execute(a)) || Double.IsInfinity(integrand.Execute(a)))
            {
                a += 0.0001 * eps * (b - a);
            }
            if (Double.IsNaN(integrand.Execute(b)) || Double.IsInfinity(integrand.Execute(b)))
            {
                b -= 0.0001 * eps * (b - a);
            }
            //посчитаем производную на 100 точках и определим шаг разбиения h для метода
            int n = 100;

            double[] deriv = new double[n];
            deriv[0] = (integrand.Execute(a + (b - a) / (n - 1)) - integrand.Execute(a)) / ((b - a) / (n - 1));
            double maxDeriv = Math.Abs(deriv[0]);

            for (int i = 1; i < n; ++i)
            {
                deriv[i] = (integrand.Execute(a + i * (b - a) / (n - 1)) - integrand.Execute(a + (i - 1) * (b - a) / (n - 1))) / ((b - a) / (n - 1));
                if (Math.Abs(deriv[i]) > maxDeriv)
                {
                    maxDeriv = Math.Abs(deriv[i]);
                }
            }
            double h = (b - a) / Math.Ceiling(0.5 * maxDeriv * (b - a) * (b - a) / eps);
            //найдем значение интеграла
            double sum = 0;

            for (int i = 0; i *h < (b - a); ++i)
            {
                sum += integrand.Execute(a + i * h);
            }
            return(sum * h);
        }
Ejemplo n.º 4
0
        public double Integration(FormulaExecutor integrand, double a, double b, double eps)
        {
            //заменим особые предельные точки на точки из окрестности
            if (Double.IsNaN(integrand.Execute(a)) || Double.IsInfinity(integrand.Execute(a)))
            {
                a += 0.0001 * eps * (b - a);
            }
            if (Double.IsNaN(integrand.Execute(b)) || Double.IsInfinity(integrand.Execute(b)))
            {
                b -= 0.0001 * eps * (b - a);
            }
            //посчитаем производную на 100 точках и определим шаг разбиения h для метода
            int n = 1000;

            double[] deriv = new double[n];
            deriv[0] = (integrand.Execute(a + (b - a) / (n - 1)) - integrand.Execute(a)) / ((b - a) / (n - 1));
            for (int i = 1; i < n; ++i)
            {
                deriv[i] = (integrand.Execute(a + i * (b - a) / (n - 1)) - integrand.Execute(a + (i - 1) * (b - a) / (n - 1))) / ((b - a) / (n - 1));
            }
            //по значению производной посчитаем значение второй производной  и определим шаг разбиения h для метода
            double[] secDeriv = new double[n];
            secDeriv[0] = (deriv[1] - deriv[0]) / ((b - a) / (n - 1));
            double maxSecDeriv = Math.Abs(secDeriv[0]);

            for (int i = 1; i < n; ++i)
            {
                secDeriv[i] = (deriv[i] - deriv[i - 1]) / ((b - a) / (n - 1));
                if (Math.Abs(secDeriv[i]) > maxSecDeriv)
                {
                    maxSecDeriv = Math.Abs(secDeriv[i]);
                }
            }
            double h = (b - a) / Math.Ceiling(Math.Sqrt(maxSecDeriv * Math.Pow(b - a, 3) / (12 * eps)));
            //найдем значение интеграла
            double sum = integrand.Execute(a) + integrand.Execute(b);

            for (int i = 1; i *h < (b - a); ++i)
            {
                sum += 2 * integrand.Execute(a + i * h);
            }
            return(0.5 * h * sum);
        }