コード例 #1
0
        public static double Aitken(IQuadratureFormula qf, int q, double tolerance, out int parts)
        {
            var initialPartsCount = qf.Parts;

            Console.WriteLine("Считаем интеграл с наперед заданной точностью {0}", tolerance);
            Console.Write("Определяем параметры m и количество интервалов разбиения. \nСтроим последовательность mi:");
            double mi = 0, miOld = 0;

            while (Math.Abs(mi - miOld) > 0.1 || miOld == 0)
            {
                var s0 = qf.CalculateIntegral();
                qf.Parts *= q;
                var s1 = qf.CalculateIntegral();
                qf.Parts *= q;
                var s2 = qf.CalculateIntegral();
                miOld              = mi;
                initialPartsCount *= q;
                qf.Parts           = initialPartsCount;
                mi = Math.Log((Math.Abs(s0 - s1) / Math.Abs(s1 - s2))) / Math.Log(q);
                Console.Write("{0} ", mi);
            }
            parts = qf.Parts;
            Console.WriteLine("\n\nСтепень при главном члене погрешности m={0}, количество интервалов разбиения={1}\n", mi, qf.Parts);
            return(mi);
        }
コード例 #2
0
        public static double Calculate(IQuadratureFormula qf, int L, int q, double tolerance, int maxr)
        {
            int    parts;
            double m              = Aitken(qf, q, tolerance, out parts);
            var    integrals      = new double[maxr + 2];
            var    H              = new double[maxr + 2];
            var    prevSystemSize = 0;

            for (int r = 0; r < maxr; r++)
            {
                Console.WriteLine("Составляем систему для r={0}", r);
                //нужно посчитать 2+r интегралов
                for (int i = 0; i < r + 2; i++)
                {
                    if (i <= prevSystemSize && (i + r) != 0)
                    {
                        continue;                                      //уже посчитанные интегралы не считаем
                    }
                    qf.Parts     = parts * (int)Math.Pow(L, i);
                    integrals[i] = qf.CalculateIntegral();
                    H[i]         = qf.H;
                    Console.WriteLine("{2}-ый интеграл по {0} частям равен {1} с шагом {3}", qf.Parts, integrals[i], i + 1, H[i]);
                    prevSystemSize = i;
                }
                var matrix = new double[r + 2, r + 3];
                for (int i = 0; i < 2 + r; i++)
                {
                    for (int j = 0; j <= r; j++)
                    {
                        matrix[i, j] = Math.Pow(H[i], j + m);
                    }
                    matrix[i, r + 1] = -1;
                    matrix[i, r + 2] = -integrals[i];
                }
                var answer  = Infrastructure.GaussSolve(matrix);
                var epsilon = Math.Abs(answer[r + 1] - integrals[r + 1]);
                Console.WriteLine("R={0}, Sj={1}, epsilon={2}\n", answer[r + 1], integrals[r + 1], epsilon);
                if (epsilon <= tolerance)
                {
                    Console.WriteLine("Заданная точность достигнута");
                    Console.WriteLine("Значение интеграла: {0} при разбиении на {1} частей", integrals[r + 1], qf.Parts);
                    return(integrals[r + 1]);
                }
            }
            throw new ApplicationException("Try increase maxr parameter");
        }