Участник:Greno4ka/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки: различия между версиями

Материал из Алговики
Перейти к навигации Перейти к поиску
Строка 66: Строка 66:
  
 
== Схема реализации последовательного алгоритма ==
 
== Схема реализации последовательного алгоритма ==
 +
    IntTrap (A, B)
 +
    {
 +
        J=0
 +
        fA = f(A)
 +
        fB = f(B)
 +
        sAB = (fA + fB) * (B - A) / 2
 +
        while (1)
 +
        {
 +
            C = (A + B) / 2
 +
            fc = fun(C)
 +
            sAC = (fA + fC) * (C - A) / 2
 +
            sCB = (fC + fB ) * (B-C)/2
 +
            sACB = sAC + sCB
 +
            if (|sAB - sACB| ≥ ε|sACB|) {
 +
                PUT_INTO_STACK(A, C, fA, fC, sAC)
 +
                A = C
 +
                fA = fC
 +
                sAB = sCB
 +
            } else {
 +
                J += sACB
 +
                if (STACK_IS_NOT_FREE)
 +
                    break
 +
                GET_FROM_STACK(A, B, fA, fB, sAB)
 +
            }
 +
        }
 +
        return J
 +
    }
  
 
== Последовательная сложность алгоритма ==
 
== Последовательная сложность алгоритма ==

Версия 23:15, 15 октября 2016

1 ЧАСТЬ. Свойства и структура алгоритмов

1.1 Общее описание алгоритма

На примере задачи вычисления определенного интеграла от аналитически заданной функции рассматриваются алгоритмы, минимизирующие время решения задачи на многопроцессорной вычислительной системе. Их использование обеспечивает снижение времени решения задачи относительно «наилучшего» доступного последовательного алгоритма. Определение эффективности параллельного алгоритма относительно собственной же последовательной версии, как правило, не корректно. Обладающий высокой эффективностью параллельный алгоритм может по времени выполнения проигрывать лучшему из доступных последовательных алгоритмов решения той же задачи. Далее рассматриваются алгоритмы, минимизирующие именно время решения задачи, оперирующей относительно небольшим объемом данных. Применяемые подходы могут быть полезны при решении широкого круга проблем.

1.2 Математическое описание алгоритма

В качестве модельной задачи рассматривается проблема вычисления с точностью ε значение определенного интеграла:

[math]I(a,b) = \int_a^b{f(x)dx}[/math]

Пусть на отрезке [math] [a,b] [/math] задана равномерная сетка, содержащая [math] n+1 [/math] узел:

[math] x_{i} = a + \frac{(b - a)} {n} i, i = 0,...,n [/math]

Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции [math] f (x) [/math] на отрезке [math][a,b][/math]:

[math] \int_a^b{f(x)dx} = \frac{b - a}{n} \left( \frac{f(x_0)}{2} + \sum^{n-1}_{i=1} {f(x_i)} + \frac{f(x_n)}{2} \right)[/math]

Будем полагать значение I найденным с точностью ε, если выполнено условие

[math] |I_{n_1} - I_{n_2}| \leq \epsilon |I_{n_2}|, n_1 \gt n_2, [/math] где [math] n_1 [/math] и [math] n_2 [/math] - количество узлов, образующих две разные сетки.

Данный метод неэффективен в силу ряда причин:

  • в некоторых точках значение функции будет вычисляться несколько раз;
  • на всём интервале интегрирования используется равномерная сетка, тогда как число точек, необходимых для достижения заданной точности, зависит от вида функции и может сильно различаться на разных участках сегмента интегрирования.

1.3 Вычислительное ядро алгоритма

1.4 Макроструктура алгоритма

Метод локального стека

   sp=0  //    указатель вершины стека
   struct {
         A, B, fA, fB, s
   } stk[1000]
   // макроопределения доступа к данным стека
   #define STACK_IS_NOT_FREE (sp>0)
   #define PUT_INTO_STACK(A, B, fA, fB, s)
   {
       stk[sp].A=A
       stk[sp].B=B
       stk[sp].fA=fA
       stk[sp].fB=fB
       stk[sp].s=s
       sp++
   } 
   #define GET_FROM_STACK(A, B, fA, fB, s)
   {
       sp--
       A=stk[sp].A
       B=stk[sp].B
       fA=stk[sp].fA
       fB=stk[sp].fB
       s=stk[sp].s
   }

1.5 Схема реализации последовательного алгоритма

   IntTrap (A, B)
   {
       J=0
       fA = f(A)
       fB = f(B)
       sAB = (fA + fB) * (B - A) / 2
       while (1)
       {
           C = (A + B) / 2
           fc = fun(C) 
           sAC = (fA + fC) * (C - A) / 2
           sCB = (fC + fB ) * (B-C)/2
           sACB = sAC + sCB
           if (|sAB - sACB| ≥ ε|sACB|) {
               PUT_INTO_STACK(A, C, fA, fC, sAC) 
               A = C
               fA = fC
               sAB = sCB
           } else {
               J += sACB
               if (STACK_IS_NOT_FREE)
                   break 
               GET_FROM_STACK(A, B, fA, fB, sAB)
           } 
       }
       return J 
   }

1.6 Последовательная сложность алгоритма

1.7 Информационный граф

1.8 Ресурс параллелизма алгоритма

1.9 Входные и выходные данные алгоритма

1.10 Свойства алгоритма

2 ЧАСТЬ. Программная реализация алгоритма

2.1 Масштабируемость алгоритма и его реализации

2.2 Существующие реализации алгоритма