<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sannikovats</id>
	<title>Алговики - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sannikovats"/>
	<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/ru/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/Sannikovats"/>
	<updated>2026-10-22T23:57:17Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=19136</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=19136"/>
		<updated>2016-11-25T07:27:36Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]](п. 1.1-1.6),[[Участник:Plukshin| Лукшин Петр Андреевич]](п. 1.7-1.10, 2.4, 2.7).&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| input_data        = 1 функция,зависящая от 1 переменной, 3 числа ( точность ε и границы отрезка интегрирования[A,B])&lt;br /&gt;
| output_data       = 1 число&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; В случае, когда можно вычислить интеграл по формуле Ньютона-Лейбница, зная первообразную искомой функции, проблем не возникает. Однако, если первообразной нет, решение можно получить благодаря численным методам. Так определенному интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1sann.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]][[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как уже упоминалось в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть рассматриваемого метода составляют рекурсивные операции нахождения середины отрезка &amp;lt;math&amp;gt; C=(A+B)/2 &amp;lt;/math&amp;gt;, вычисление значения функции в этой точке &amp;lt;math&amp;gt; fC=function(C)&amp;lt;/math&amp;gt;, нахождение площадей трапеций, образованных после разбиение отрезка и их суммирование &amp;lt;math&amp;gt; sAC=(fA+fC)*(C-A)/2,   sCB=(fC+fB)*(B-C)/2,   sACB=sAC+sCB &amp;lt;/math&amp;gt;, а также нахождение отношения модуля разности площади трапеции до разбиения отрезка и результату, полученному после разбиения, к сумме площадей после разбиения &amp;lt;math&amp;gt; |sAB - sACB|\leq \epsilon * |sACB| &amp;lt;/math&amp;gt;, что обеспечивает проверку условия устойчивости.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//на вход функции подаются границы отрезка и точность&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	//бесконечный цикл с предусловием, прерывающийся при выполнении условия на порядок точности&lt;br /&gt;
        while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В рамках этой функции поэтапно выполняются следующие операции:&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала (возвращение к пункту 2), &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла. &amp;lt;br /&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
[[Файл:Lukshin_01.png|1260px|thumb|left|Рис. Информационная структура алгоритма глобального стека]]  &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;      На рисунке изображена информационная структура алгоритма, на которой заметна его внутренняя цикличность.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить параллельную сложность рассмотренного алгоритма является такой же невыполнимой задачей, как и оценка последовательной сложности. Рекурсивное деление областей интегрирования и поиск на них частичных сумм зависит непосредственно от конкретной функции и ее свойств.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Рассмотренный алгоритм обладает свойством детерминированности, поскольку при определенных входных данных мы будем получать одинаковый результат. При этом он может адаптироваться в зависимости от сложности подынтегральной функции.&lt;br /&gt;
Кроме того, алгоритм обладает внутренним параллелизмом, так как является численно устойчивым как в последовательной, так и в параллельной версиях.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений === &lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
#Якобовский М.В. &lt;br /&gt;
Введение в параллельные методы решения задач&lt;br /&gt;
#М.В. Якобовский и Е.Ю. Кулькова &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot;&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=19135</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=19135"/>
		<updated>2016-11-25T07:15:55Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]](п. 1.1-1.6),[[Участник:Plukshin| Лукшин Петр Андреевич]](п. 1.7-1.10, 2.4, 2.7).&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| input_data        = 1 функция,зависящая от 1 переменной, 3 числа ( точность ε и границы отрезка интегрирования[A,B])&lt;br /&gt;
| output_data       = 1 число&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; В случае, когда можно вычислить интеграл по формуле Ньютона-Лейбница, зная первообразную искомой функции, проблем не возникает. Однако, если первообразной нет, решение можно получить благодаря численным методам. Так определенному интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1sann.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]][[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как уже упоминалось в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть рассматриваемого метода составляют рекурсивные операции нахождения середины отрезка &amp;lt;math&amp;gt; C=(A+B)/2 &amp;lt;/math&amp;gt;, вычисление значения функции в этой точке &amp;lt;math&amp;gt; fC=function(C)&amp;lt;/math&amp;gt;, нахождение площадей трапеций, образованных после разбиение отрезка и их суммирование &amp;lt;math&amp;gt; sAC=(fA+fC)*(C-A)/2,   sCB=(fC+fB)*(B-C)/2,   sACB=sAC+sCB &amp;lt;/math&amp;gt;, а также нахождение отношения модуля разности площади трапеции до разбиения отрезка и результату, полученному после разбиения, к сумме площадей после разбиения &amp;lt;math&amp;gt; |sAB - sACB|\leq \epsilon * |sACB| &amp;lt;/math&amp;gt;, что обеспечивает проверку условия устойчивости.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//на вход функции подаются границы отрезка и точность&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	//бесконечный цикл с предусловием, прерывающийся при выполнении условия на порядок точности&lt;br /&gt;
        while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В рамках этой функции поэтапно выполняются следующие операции:&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала (возвращение к пункту 2), &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла. &amp;lt;br /&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
[[Файл:Lukshin_01.png|1000px|thumb|left|Рис. Информационная структура алгоритма глобального стека]]  &amp;lt;br /&amp;gt;&lt;br /&gt;
На рисунке изображена информационная структура алгоритма, на которой заметна его внутренняя цикличность.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить параллельную сложность рассмотренного алгоритма является такой же невыполнимой задачей, как и оценка последовательной сложности. Рекурсивное деление областей интегрирования и поиск на них частичных сумм зависит непосредственно от конкретной функции и ее свойств.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Рассмотренный алгоритм обладает свойством детерминированности, поскольку при определенных входных данных мы будем получать одинаковый результат. При этом он может адаптироваться в зависимости от сложности подынтегральной функции.&lt;br /&gt;
Кроме того, алгоритм обладает внутренним параллелизмом, так как является численно устойчивым как в последовательной, так и в параллельной версиях.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений === &lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
#Якобовский М.В. &lt;br /&gt;
Введение в параллельные методы решения задач&lt;br /&gt;
#М.В. Якобовский и Е.Ю. Кулькова &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot;&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=18619</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=18619"/>
		<updated>2016-11-20T18:18:51Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| input_data        = 1 функция,зависящая от 1 переменной, 3 числа ( точность ε и границы отрезка интегрирования[A,B])&lt;br /&gt;
| output_data       = 1 число&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]](п.1.1-1.6),[[Участник:Plukshin| Лукшин Петр Андреевич]](п.1.7-1.10,2.4,2.7).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; В случае, когда можно вычислить интеграл по формуле Ньютона-Лейбница, зная первообразную искомой функции, проблем не возникает. Однако, если первообразной нет, решение можно получить благодаря численным методам. Так определенному интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1sann.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как уже упоминалось в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть рассматриваемого метода составляют рекурсивные операции нахождения середины отрезка &amp;lt;math&amp;gt; C=(A+B)/2 &amp;lt;/math&amp;gt;, вычисление значения функции в этой точке &amp;lt;math&amp;gt; fC=function(C)&amp;lt;/math&amp;gt;, нахождение площадей трапеций, образованных после разбиение отрезка и их суммирование &amp;lt;math&amp;gt; sAC=(fA+fC)*(C-A)/2,   sCB=(fC+fB)*(B-C)/2,   sACB=sAC+sCB &amp;lt;/math&amp;gt;, а также нахождение отношения модуля разности площади трапеции до разбиения отрезка и результату, полученному после разбиения, к сумме площадей после разбиения &amp;lt;math&amp;gt; |sAB - sACB|\leq \epsilon * |sACB| &amp;lt;/math&amp;gt;, что обеспечивает проверку условия устойчивости.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//на вход функции подаются границы отрезка и точность&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	//бесконечный цикл с предусловием, прерывающийся при выполнении условия на порядок точности&lt;br /&gt;
        while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В рамках этой функции поэтапно выполняются следующие операции:&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала (возвращение к пункту 2), &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
[[Файл:luksh.jpg]]&lt;br /&gt;
На рисунке изображен информационный граф, где k - это глубина алгоритма, а + обозначено суммирование площадей трапеций.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить параллельную сложность рассмотренного алгоритма является такой же невыполнимой задачей, как и оценка последовательной сложности. Рекурсивное деление областей интегрирования и поиск на них частичных сумм зависит непосредственно от конкретной функции и ее свойств.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Рассмотренный алгоритм обладает свойством детерминированности, поскольку при определенных входных данных мы будем получать одинаковый результат. При этом он может адаптироваться в зависимости от сложности подынтегральной функции.&lt;br /&gt;
Кроме того, алгоритм обладает внутренним параллелизмом, так как является численно устойчивым как в последовательной, так и в параллельной версиях.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений === &lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
#Якобовский М.В. &lt;br /&gt;
Введение в параллельные методы решения задач&lt;br /&gt;
#М.В. Якобовский и Е.Ю. Кулькова &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot;&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=17395</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=17395"/>
		<updated>2016-11-15T19:49:43Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| input_data        = 1 функция,зависящая от 1 переменной, 3 числа ( точность ε и границы отрезка интегрирования[A,B])&lt;br /&gt;
| output_data       = 1 число&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]](п.1.1-1.6),[[Участник:Plukshin| Лукшин Петр Андреевич]](п.1.7-2.2).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; В случае, когда можно вычислить интеграл по формуле Ньютона-Лейбница, зная первообразную искомой функции, проблем не возникает. Однако, если первообразной нет, решение можно получить благодаря численным методам. Так определенному интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1sann.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как уже упоминалось в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть рассматриваемого метода составляют рекурсивные операции нахождения середины отрезка &amp;lt;math&amp;gt; C=(A+B)/2 &amp;lt;/math&amp;gt;, вычисление значения функции в этой точке &amp;lt;math&amp;gt; fC=function(C)&amp;lt;/math&amp;gt;, нахождение площадей трапеций, образованных после разбиение отрезка и их суммирование &amp;lt;math&amp;gt; sAC=(fA+fC)*(C-A)/2,   sCB=(fC+fB)*(B-C)/2,   sACB=sAC+sCB &amp;lt;/math&amp;gt;, а также нахождение отношения модуля разности площади трапеции до разбиения отрезка и результату, полученному после разбиения, к сумме площадей после разбиения &amp;lt;math&amp;gt; |sAB - sACB|\leq \epsilon * |sACB| &amp;lt;/math&amp;gt;, что обеспечивает проверку условия устойчивости.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//на вход функции подаются границы отрезка и точность&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	//бесконечный цикл с предусловием, прерывающийся при выполнении условия на порядок точности&lt;br /&gt;
        while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В рамках этой функции поэтапно выполняются следующие операции:&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала (возвращение к пункту 2), &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
[[Файл:luksh.jpg]]&lt;br /&gt;
На рисунке изображен информационный граф, где k - это глубина алгоритма, а + обозначено суммирование площадей трапеций.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить параллельную сложность рассмотренного алгоритма является такой же невыполнимой задачей, как и оценка последовательной сложности. Рекурсивное деление областей интегрирования и поиск на них частичных сумм зависит непосредственно от конкретной функции и ее свойств.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Рассмотренный алгоритм обладает свойством детерминированности, поскольку при определенных входных данных мы будем получать одинаковый результат. При этом он может адаптироваться в зависимости от сложности подынтегральной функции.&lt;br /&gt;
Кроме того, алгоритм обладает внутренним параллелизмом, так как является численно устойчивым как в последовательной, так и в параллельной версиях.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений === &lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
#Якобовский М.В. &lt;br /&gt;
Введение в параллельные методы решения задач&lt;br /&gt;
#М.В. Якобовский и Е.Ю. Кулькова &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot;&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=16229</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=16229"/>
		<updated>2016-11-09T06:30:02Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| input_data        = 1 функция,зависящая от 1 переменной, 3 числа ( точность ε и границы отрезка интегрирования[A,B])&lt;br /&gt;
| output_data       = 1 число&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]](п.1.1-1.6),[[Участник:Plukshin| Лукшин Петр Андреевич]](п.1.7-2.2).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; В случае, когда можно вычислить интеграл по формуле Ньютона-Лейбница, зная первообразную искомой функции, проблем не возникает. Однако, если первообразной нет, решение можно получить благодаря численным методам. Так определенному интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1sann.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как уже упоминалось в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть рассматриваемого метода составляют рекурсивные операции нахождения середины отрезка &amp;lt;math&amp;gt; C=(A+B)/2 &amp;lt;/math&amp;gt;, вычисление значения функции в этой точке &amp;lt;math&amp;gt; fC=function(C)&amp;lt;/math&amp;gt;, нахождение площадей трапеций, образованных после разбиение отрезка и их суммирование &amp;lt;math&amp;gt; sAC=(fA+fC)*(C-A)/2,   sCB=(fC+fB)*(B-C)/2,   sACB=sAC+sCB &amp;lt;/math&amp;gt;, а также нахождение отношения модуля разности площади трапеции до разбиения отрезка и результату, полученному после разбиения, к сумме площадей после разбиения &amp;lt;math&amp;gt; |sAB - sACB|\leq \epsilon * |sACB| &amp;lt;/math&amp;gt;, что обеспечивает проверку условия устойчивости.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также в реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//на вход функции подаются границы отрезка и точность&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	//бесконечный цикл с предусловием, прерывающийся при выполнении условия на порядок точности&lt;br /&gt;
        while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В рамках этой функции поэтапно выполняются следующие операции:&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала (возвращение к пункту 2), &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
[[Файл:luksh.jpg]]&lt;br /&gt;
На рисунке изображен информационный граф, где k - это глубина алгоритма, а + обозначено суммирование площадей трапеций.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить параллельную сложность рассмотренного алгоритма является такой же невыполнимой задачей, как и оценка последовательной сложности. Рекурсивное деление областей интегрирования и поиск на них частичных сумм зависит непосредственно от конкретной функции и ее свойств.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Рассмотренный алгоритм обладает свойством детерминированности, поскольку при определенных входных данных мы будем получать одинаковый результат. При этом он может адаптироваться в зависимости от сложности подынтегральной функции.&lt;br /&gt;
Кроме того, алгоритм обладает внутренним параллелизмом, так как является численно устойчивым как в последовательной, так и в параллельной версиях.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений === &lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
#Якобовский М.В. &lt;br /&gt;
Введение в параллельные методы решения задач&lt;br /&gt;
#М.В. Якобовский и Е.Ю. Кулькова &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot;&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=15898</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=15898"/>
		<updated>2016-11-03T14:18:53Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| input_data        = 1 функция,зависящая от 1 переменной, 3 числа ( точность ε и границы отрезка интегрирования[A,B])&lt;br /&gt;
| output_data       = 1 число&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]](п.1.1-1.6),[[Участник:Plukshin| Лукшин Петр Андреевич]](п.1.7-2.2).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; В случае, когда можно вычислить интеграл по формуле Ньютона-Лейбница, зная первообразную искомой функции, проблем не возникает. Однако, если первообразной нет, решение можно получить благодаря численным методам. Так определенному интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1sann.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как уже упоминалось в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть рассматриваемого метода составляют рекурсивные операции нахождения середины отрезка &amp;lt;math&amp;gt; C=(A+B)/2 &amp;lt;/math&amp;gt;, вычисление значения функции в этой точке &amp;lt;math&amp;gt; fC=function(C)&amp;lt;/math&amp;gt;, нахождение площадей трапеций, образованных после разбиение отрезка и их суммирование &amp;lt;math&amp;gt; sAC=(fA+fC)*(C-A)/2,   sCB=(fC+fB)*(B-C)/2,   sACB=sAC+sCB &amp;lt;/math&amp;gt;, а также нахождение отношения модуля разности площади трапеции до разбиения отрезка и результату, полученному после разбиения, к сумме площадей после разбиения &amp;lt;math&amp;gt; |sAB - sACB|\leq \epsilon * |sACB| &amp;lt;/math&amp;gt;, что обеспечивает проверку условия устойчивости.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также в реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//на вход функции подаются границы отрезка и точность&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	//бесконечный цикл с предусловием, прерывающийся при выполнении условия на порядок точности&lt;br /&gt;
        while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В рамках этой функции поэтапно выполняются следующие операции:&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала (возвращение к пункту 2), &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
[[Файл:luksh.jpg]]&lt;br /&gt;
На рисунке изображен информационный граф, где k - это глубина алгоритма, а + обозначено суммирование площадей трапеций.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить параллельную сложность рассмотренного алгоритма является такой же невыполнимой задачей, как и оценка последовательной сложности. Рекурсивное деление областей интегрирования и поиск на них частичных сумм зависит непосредственно от конкретной функции и ее свойств.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Рассмотренный алгоритм обладает свойством детерминированности, поскольку при определенных входных данных мы будем получать одинаковый результат. При этом он может адаптироваться в зависимости от сложности подынтегральной функции.&lt;br /&gt;
Кроме того, алгоритм обладает внутренним параллелизмом, так как является численно устойчивым как в последовательной, так и в параллельной версиях.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
#Якобовский М.В. &lt;br /&gt;
Введение в параллельные методы решения задач&lt;br /&gt;
#М.В. Якобовский и Е.Ю. Кулькова &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot;&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=15749</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=15749"/>
		<updated>2016-11-02T10:34:21Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: /* Макроструктура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| input_data        = 1 функция,зависящая от 1 переменной, 3 числа ( точность ε и границы отрезка интегрирования[A,B])&lt;br /&gt;
| output_data       = 1 число&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]](п.1.1-1.6),[[Участник:Plukshin| Лукшин Петр Андреевич]](п.1.7-2.2).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; В случае, когда можно вычислить интеграл по формуле Ньютона-Лейбница, зная первообразную искомой функции, проблем не возникает. Однако, если первообразной нет, решение можно получить благодаря численным методам. Так определенному интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1sann.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как уже упоминалось в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть рассматриваемого метода составляют рекурсивные операции нахождения середины отрезка &amp;lt;math&amp;gt; C=(A+B)/2 &amp;lt;/math&amp;gt;, вычисление значения функции в этой точке &amp;lt;math&amp;gt; fC=function(C)&amp;lt;/math&amp;gt;, нахождение площадей трапеций, образованных после разбиение отрезка и их суммирование &amp;lt;math&amp;gt; sAC=(fA+fC)*(C-A)/2, sCB=(fC+fB)*(B-C)/2, sACB=sAC+sCB &amp;lt;/math&amp;gt;, а также нахождение отношения модуля разности площади трапеции до разбиения отрезка и результату, полученному после разбиения, к сумме площадей после разбиения &amp;lt;math&amp;gt; abs(sAB-sACB)≥ε*abs(sACB) &amp;lt;/math&amp;gt;, что обеспечивает проверку условия устойчивости.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также в реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В рамках этой функции поэтапно выполняются следующие операции:&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала (возвращение к пункту 2), &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
[[Файл:luksh.jpg]]&lt;br /&gt;
На рисунке изображен информационный граф, где k - это глубина алгоритма, а + обозначено суммирование площадей трапеций.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить параллельную сложность рассмотренного алгоритма является такой же невыполнимой задачей, как и оценка последовательной сложности. Рекурсивное деление областей интегрирования и поиск на них частичных сумм зависит непосредственно от конкретной функции и ее свойств.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Рассмотренный алгоритм обладает свойством детерминированности, поскольку при определенных входных данных мы будем получать одинаковый результат. При этом он может адаптироваться в зависимости от сложности подынтегральной функции.&lt;br /&gt;
Кроме того, алгоритм обладает внутренним параллелизмом, так как является численно устойчивым как в последовательной, так и в параллельной версиях.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
#Якобовский М.В. &lt;br /&gt;
Введение в параллельные методы решения задач&lt;br /&gt;
#М.В. Якобовский и Е.Ю. Кулькова &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot;&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=15748</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=15748"/>
		<updated>2016-11-02T10:32:50Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| input_data        = 1 функция,зависящая от 1 переменной, 3 числа ( точность ε и границы отрезка интегрирования[A,B])&lt;br /&gt;
| output_data       = 1 число&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]](п.1.1-1.6),[[Участник:Plukshin| Лукшин Петр Андреевич]](п.1.7-2.2).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; В случае, когда можно вычислить интеграл по формуле Ньютона-Лейбница, зная первообразную искомой функции, проблем не возникает. Однако, если первообразной нет, решение можно получить благодаря численным методам. Так определенному интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1sann.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Как уже упоминалось в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть рассматриваемого метода составляют операции нахождения середины отрезка &amp;lt;math&amp;gt; C=(A+B)/2 &amp;lt;/math&amp;gt;, вычисление значения функции в этой точке &amp;lt;math&amp;gt; fC=function(C)&amp;lt;/math&amp;gt;, нахождение площадей трапеций, образованных после разбиение отрезка и их суммирование &amp;lt;math&amp;gt; sAC=(fA+fC)*(C-A)/2, sCB=(fC+fB)*(B-C)/2, sACB=sAC+sCB &amp;lt;/math&amp;gt;, а также нахождение отношения модуля разности площади трапеции до разбиения отрезка и результату, полученному после разбиения, к сумме площадей после разбиения &amp;lt;math&amp;gt; abs(sAB-sACB)≥ε*abs(sACB) &amp;lt;/math&amp;gt;, что обеспечивает проверку условия устойчивости.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Также в реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В рамках этой функции поэтапно выполняются следующие операции:&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала (возвращение к пункту 2), &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
[[Файл:luksh.jpg]]&lt;br /&gt;
На рисунке изображен информационный граф, где k - это глубина алгоритма, а + обозначено суммирование площадей трапеций.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить параллельную сложность рассмотренного алгоритма является такой же невыполнимой задачей, как и оценка последовательной сложности. Рекурсивное деление областей интегрирования и поиск на них частичных сумм зависит непосредственно от конкретной функции и ее свойств.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Рассмотренный алгоритм обладает свойством детерминированности, поскольку при определенных входных данных мы будем получать одинаковый результат. При этом он может адаптироваться в зависимости от сложности подынтегральной функции.&lt;br /&gt;
Кроме того, алгоритм обладает внутренним параллелизмом, так как является численно устойчивым как в последовательной, так и в параллельной версиях.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
#Якобовский М.В. &lt;br /&gt;
Введение в параллельные методы решения задач&lt;br /&gt;
#М.В. Якобовский и Е.Ю. Кулькова &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot;&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=15613</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=15613"/>
		<updated>2016-11-01T16:15:29Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| input_data        = 1 функция,зависящая от 1 переменной, 3 числа ( точность ε и границы отрезка интегрирования[A,B])&lt;br /&gt;
| output_data       = 1 число&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]](п.1.1-1.6),[[Участник:Plukshin| Лукшин Петр Андреевич]](п.1.7-2.2).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; В случае, когда можно вычислить интеграл по формуле Ньютона-Лейбница, зная первообразную искомой функции, проблем не возникает. Однако, если первообразной нет, решение можно получить благодаря численным методам. Так определенному интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1sann.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В рамках этой функции поэтапно выполняются следующие операции:&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала (возвращение к пункту 2), &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
[[Файл:luksh.jpg]]&lt;br /&gt;
На рисунке изображен информационный граф, где k - это глубина алгоритма, а + обозначено суммирование площадей трапеций.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить параллельную сложность рассмотренного алгоритма является такой же невыполнимой задачей, как и оценка последовательной сложности. Рекурсивное деление областей интегрирования и поиск на них частичных сумм зависит непосредственно от конкретной функции и ее свойств.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Рассмотренный алгоритм обладает свойством детерминированности, поскольку при определенных входных данных мы будем получать одинаковый результат. При этом он может адаптироваться в зависимости от сложности подынтегральной функции.&lt;br /&gt;
Кроме того, алгоритм обладает внутренним параллелизмом, так как является численно устойчивым как в последовательной, так и в параллельной версиях.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
#Якобовский М.В. &lt;br /&gt;
Введение в параллельные методы решения задач&lt;br /&gt;
#М.В. Якобовский и Е.Ю. Кулькова &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot;&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=15563</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=15563"/>
		<updated>2016-11-01T14:44:20Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| input_data        = 1 функция,зависящая от 1 переменной, 3 числа ( точность ε и границы отрезка интегрирования[A,B])&lt;br /&gt;
| output_data       = 1 число&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]](п.1.1-1.6),[[Участник:Plukshin| Лукшин Петр Андреевич]](п.1.7-2.2).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; В случае, когда можно вычислить интеграл по формуле Ньютона-Лейбница, зная первообразную искомой функции, проблем не возникает. Однако, если первообразной нет, решение можно получить благодаря численным методам. Так определенному интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1sann.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
[[Файл:luksh.jpg]]&lt;br /&gt;
На рисунке изображен информационный граф, где k - это глубина алгоритма, а + обозначено суммирование площадей трапеций.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить параллельную сложность рассмотренного алгоритма является такой же невыполнимой задачей, как и оценка последовательной сложности. Рекурсивное деление областей интегрирования и поиск на них частичных сумм зависит непосредственно от конкретной функции и ее свойств.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Рассмотренный алгоритм обладает свойством детерминированности, поскольку при определенных входных данных мы будем получать одинаковый результат. При этом он может адаптироваться в зависимости от сложности подынтегральной функции.&lt;br /&gt;
Кроме того, алгоритм обладает внутренним параллелизмом, так как является численно устойчивым как в последовательной, так и в параллельной версиях.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
#Якобовский М.В. &lt;br /&gt;
Введение в параллельные методы решения задач&lt;br /&gt;
#М.В. Якобовский и Е.Ю. Кулькова &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot;&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=14732</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=14732"/>
		<updated>2016-10-29T17:58:47Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| input_data        = 1 функция,зависящая от 1 переменной, 3 числа ( точность ε и границы отрезка интегрирования[A,B])&lt;br /&gt;
| output_data       = 1 число&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]](п.1.1-1.6),[[Участник:Plukshin| Лукшин Петр Андреевич]](п.1.7-2.2).&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; В случае, когда можно вычислить интеграл по формуле Ньютона-Лейбница, зная первообразную искомой функции, проблем не возникает. Однако, если первообразной нет, решение можно получить благодаря численным методам. Так определенному интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
[[Файл:luksh.jpg]]&lt;br /&gt;
На рисунке изображен информационный граф, где k - это глубина алгоритма, а + обозначено суммирование площадей трапеций.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить параллельную сложность рассмотренного алгоритма является такой же невыполнимой задачей, как и оценка последовательной сложности. Рекурсивное деление областей интегрирования и поиск на них частичных сумм зависит непосредственно от конкретной функции и ее свойств.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Рассмотренный алгоритм обладает свойством детерминированности, поскольку при определенных входных данных мы будем получать одинаковый результат. При этом он может адаптироваться в зависимости от сложности подынтегральной функции.&lt;br /&gt;
Кроме того, алгоритм обладает внутренним параллелизмом, так как является численно устойчивым как в последовательной, так и в параллельной версиях.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
#Якобовский М.В. &lt;br /&gt;
Введение в параллельные методы решения задач&lt;br /&gt;
#М.В. Якобовский и Е.Ю. Кулькова &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot;&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=12038</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=12038"/>
		<updated>2016-10-15T20:56:37Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| input_data        = 1 функция,зависящая от 1 переменной, 3 числа ( точность ε и границы отрезка интегрирования[A,B])&lt;br /&gt;
| output_data       = 1 число&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; В случае, когда можно вычислить интеграл по формуле Ньютона-Лейбница, зная первообразную искомой функции, проблем не возникает. Однако, если первообразной нет, решение можно получить благодаря численным методам. Так определенному интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
[[Файл:luksh.jpg]]&lt;br /&gt;
На рисунке изображен информационный граф, где k - это глубина алгоритма, а + обозначено суммирование площадей трапеций.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить параллельную сложность рассмотренного алгоритма является такой же невыполнимой задачей, как и оценка последовательной сложности. Рекурсивное деление областей интегрирования и поиск на них частичных сумм зависит непосредственно от конкретной функции и ее свойств.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Рассмотренный алгоритм обладает свойством детерминированности, поскольку при определенных входных данных мы будем получать одинаковый результат. При этом он может адаптироваться в зависимости от сложности подынтегральной функции.&lt;br /&gt;
Кроме того, алгоритм обладает внутренним параллелизмом, так как является численно устойчивым как в последовательной, так и в параллельной версиях.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;br /&gt;
&lt;br /&gt;
==Литература==&lt;br /&gt;
Якобовский М.В. &lt;br /&gt;
Введение в параллельные методы решения задач&lt;br /&gt;
М.В. Якобовский и Е.Ю. Кулькова &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot;&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11969</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11969"/>
		<updated>2016-10-15T20:49:51Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| input_data        = 1 функция,зависящая от 1 переменной, 3 числа ( точность ε и границы отрезка интегрирования[A,B])&lt;br /&gt;
| output_data       = 1 число&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; В случае, когда можно вычислить интеграл по формуле Ньютона-Лейбница, зная первообразную искомой функции, проблем не возникает. Однако, если первообразной нет, решение можно получить благодаря численным методам. Так определенному интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
[[Файл:luksh.jpg]]&lt;br /&gt;
На рисунке изображен информационный граф, где k - это глубина алгоритма, а + обозначено суммирование площадей трапеций.&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить параллельную сложность рассмотренного алгоритма является такой же невыполнимой задачей, как и оценка последовательной сложности. Рекурсивное деление областей интегрирования и поиск на них частичных сумм зависит непосредственно от конкретной функции и ее свойств.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Рассмотренный алгоритм обладает свойством детерминированности, поскольку при определенных входных данных мы будем получать одинаковый результат. При этом он может адаптироваться в зависимости от сложности подынтегральной функции.&lt;br /&gt;
Кроме того, алгоритм обладает внутренним параллелизмом, так как является численно устойчивым как в последовательной, так и в параллельной версиях.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11844</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11844"/>
		<updated>2016-10-15T20:36:50Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| input_data        = 1 функция,зависящая от 1 переменной, 3 числа ( точность ε и границы отрезка интегрирования[A,B])&lt;br /&gt;
| output_data       = 1 число&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; В случае, когда можно вычислить интеграл по формуле Ньютона-Лейбница, зная первообразную искомой функции, проблем не возникает. Однако, если первообразной нет, решение можно получить благодаря численным методам. Так определенному интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
[[Файл:luksh.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить параллельную сложность рассмотренного алгоритма является такой же невыполнимой задачей, как и оценка последовательной сложности. Рекурсивное деление областей интегрирования и поиск на них частичных сумм зависит непосредственно от конкретной функции и ее свойств.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Рассмотренный алгоритм обладает свойством детерминированности, поскольку при определенных входных данных мы будем получать одинаковый результат. При этом он может адаптироваться в зависимости от сложности подынтегральной функции.&lt;br /&gt;
Кроме того, алгоритм обладает внутренним параллелизмом, так как является численно устойчивым как в последовательной, так и в параллельной версиях.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11819</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11819"/>
		<updated>2016-10-15T20:33:01Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| input_data        = 1 функция,зависящая от 1 переменной, 3 числа ( точность ε и границы отрезка интегрирования[A,B])&lt;br /&gt;
| output_data       = 1 число&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; В случае, когда можно вычислить интеграл по формуле Ньютона-Лейбница, зная первообразную искомой функции, проблем не возникает. Однако, если первообразной нет, решение можно получить благодаря численным методам. Так определенному интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить параллельную сложность рассмотренного алгоритма является такой же невыполнимой задачей, как и оценка последовательной сложности. Рекурсивное деление областей интегрирования и поиск на них частичных сумм зависит непосредственно от конкретной функции и ее свойств.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Рассмотренный алгоритм обладает свойством детерминированности, поскольку при определенных входных данных мы будем получать одинаковый результат. При этом он может адаптироваться в зависимости от сложности подынтегральной функции.&lt;br /&gt;
Кроме того, алгоритм обладает внутренним параллелизмом, так как является численно устойчивым как в последовательной, так и в параллельной версиях.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11799</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11799"/>
		<updated>2016-10-15T20:29:49Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; В случае, когда можно вычислить интеграл по формуле Ньютона-Лейбница, зная первообразную искомой функции, проблем не возникает. Однако, если первообразной нет, решение можно получить благодаря численным методам. Так определенному интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить параллельную сложность рассмотренного алгоритма является такой же невыполнимой задачей, как и оценка последовательной сложности. Рекурсивное деление областей интегрирования и поиск на них частичных сумм зависит непосредственно от конкретной функции и ее свойств.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Рассмотренный алгоритм обладает свойством детерминированности, поскольку при определенных входных данных мы будем получать одинаковый результат. При этом он может адаптироваться в зависимости от сложности подынтегральной функции.&lt;br /&gt;
Кроме того, алгоритм обладает внутренним параллелизмом, так как является численно устойчивым как в последовательной, так и в параллельной версиях.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11434</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11434"/>
		<updated>2016-10-15T19:30:08Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; В случае, когда можно вычислить интеграл по формуле Ньютона-Лейбница, зная первообразную искомой функции, проблем не возникает. Однако, если первообразной нет, решение можно получить благодаря численным методам. Так определенному интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11403</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11403"/>
		<updated>2016-10-15T19:24:44Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; Определенному&lt;br /&gt;
интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
 &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью eps методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;//площадь трапеции с основанием AС&lt;br /&gt;
	double sCB;//площадь трапеции с основанием СВ&lt;br /&gt;
	double sACB;//сумма sAC и sCB&lt;br /&gt;
	while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
                  //проверка выполнения условия на порядок точности:&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11303</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11303"/>
		<updated>2016-10-15T19:10:24Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; Определенному&lt;br /&gt;
интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
 &amp;lt;br /&amp;gt; &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
// Заданная функция f(x)&lt;br /&gt;
double f(double x);&lt;br /&gt;
&lt;br /&gt;
Рассмотрим функцию JLS, вычисляющую определенный интеграл от f(x) на [A,B] с заданной точностью &amp;amp;epsilon методом локального стека, которая является вычислительным ядром алгоритма:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
int JLS(double A, double B, double eps) {&lt;br /&gt;
	double J = 0;//значение интеграла&lt;br /&gt;
	double fA = f(A);//значение функции f(x)на границе A&lt;br /&gt;
	double fB = f(B);//значение функции f(x)на границе B&lt;br /&gt;
	double C;//середина отрезка [A,B]&lt;br /&gt;
	double fC;//значение функции f(x)в середине отрезка [A,B]&lt;br /&gt;
	double sAB = (fA + fB)*(B - A)/2;//вычисление площади трапеции с основанием AB&lt;br /&gt;
	double sAC;&lt;br /&gt;
	double sCB;&lt;br /&gt;
	double sACB;&lt;br /&gt;
	while(1) {&lt;br /&gt;
		C = (A + B)/2;//середина отрезка &lt;br /&gt;
		fC = f(C);&lt;br /&gt;
		sAC = (fA + fC)*(C - A)/2;&lt;br /&gt;
		sCB = (fC + fB )*(B - C)/2;&lt;br /&gt;
		sACB = sAC + sCB;&lt;br /&gt;
		if(abs(sAB - sACB) &amp;gt;= eps*abs(sACB)) {&lt;br /&gt;
			PUT_INTO_STACK(A, C, fA, fC, sAC);&lt;br /&gt;
			A = C;&lt;br /&gt;
			fA = fC;&lt;br /&gt;
			sAB = sCB;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			J += sACB;&lt;br /&gt;
			if(STACK_IS_NOT_FREE) {&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
			GET_FROM_STACK(A, B, fA, fB, sAB);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return J;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11136</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11136"/>
		<updated>2016-10-15T18:35:11Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; Определенному&lt;br /&gt;
интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
 &amp;lt;br /&amp;gt; &lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции: &amp;lt;br /&amp;gt; &lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11124</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11124"/>
		<updated>2016-10-15T18:33:22Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; Определенному&lt;br /&gt;
интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2sann.jpg]] [[Файл:3sann.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции:&lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
1)Проверка наличия элементов в стеке&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11107</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=11107"/>
		<updated>2016-10-15T18:28:44Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; Определенному&lt;br /&gt;
интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2.jpg]] [[Файл:3.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
В реализации алгоритма используется такая структура данных, как стек, в котором хранятся координаты концов отрезков.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
//Данные, описывающие стек&lt;br /&gt;
int sp = 0; // Указатель вершины стека&lt;br /&gt;
&lt;br /&gt;
// Массив структур, в которых хранятся отложенные задания&lt;br /&gt;
struct mstk {&lt;br /&gt;
	double A;//координата левой границы отрезка интегрирования&lt;br /&gt;
	double B;//координата правой границы отрезка интегрирования&lt;br /&gt;
	double fA;//значение функции на границе A&lt;br /&gt;
	double fB;//значение функции на границе B&lt;br /&gt;
	double s;//частичная сумма&lt;br /&gt;
} mstk[N];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В процедурах работы со стеком доступны следующие операции:&lt;br /&gt;
1)Проверка наличия элементов в стеке:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
1)Проверка наличия элементов в стеке&lt;br /&gt;
#define STACK_IS_NOT_FREE (sp &amp;gt; 0)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
2)Операция &amp;quot;положить в стек&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define PUT_INTO_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	mstk[sp].A = A;&lt;br /&gt;
	mstk[sp].B = B;&lt;br /&gt;
	mstk[sp].fA = fA;&lt;br /&gt;
	mstk[sp].fB = fB;&lt;br /&gt;
	mstk[sp].s = s;&lt;br /&gt;
	++sp;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
3)Операция &amp;quot;взять из стека верхний элемент&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#define GET_FROM_STACK(A, B, fA, fB, s) {&lt;br /&gt;
	--sp;&lt;br /&gt;
	A = mstk[sp].A;&lt;br /&gt;
	B = mstk[sp].B;&lt;br /&gt;
	fA = mstk[sp].fA;&lt;br /&gt;
	fB = mstk[sp].fB;&lt;br /&gt;
	s = mstk[sp].s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=10090</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=10090"/>
		<updated>2016-10-15T14:59:11Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt; Определенному&lt;br /&gt;
интегралу можно дать простую геометрическую интерпретацию  - он равен площади криволинейной трапеции, ограниченной слева и справа вертикальными прямыми x=a, x=b, снизу  -  прямой y=0, а сверху  –  кривой y=f(x).&lt;br /&gt;
&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2.jpg]] [[Файл:3.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=9810</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=9810"/>
		<updated>2016-10-15T14:03:34Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt;&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
Пусть на отрезке &amp;lt;math&amp;gt; [A,B] &amp;lt;/math&amp;gt; задана равномерная сетка, содержащая &amp;lt;math&amp;gt; n+1 &amp;lt;/math&amp;gt; узел:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; x_{i} = A + \frac{(B - A)} {n} i,   i = 0,...,n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда, согласно методу трапеций, можно численно найти определенный интеграл от функции &amp;lt;math&amp;gt; f(x) &amp;lt;/math&amp;gt; на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; J_n(A,B)=\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)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл: 2.jpg]] [[Файл:3.jpg]]&lt;br /&gt;
&lt;br /&gt;
Будем полагать значение &amp;lt;math&amp;gt; J &amp;lt;/math&amp;gt; найденным с точностью &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt;, если выполнено условие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; |J_{n_1} - J_{n_2}| \leq \epsilon |J_{n_2}|, n_1 &amp;gt; n_2, &amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;  n_1 &amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt; n_2 &amp;lt;/math&amp;gt; - количество узлов, образующих две разные сетки.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Используемые в алгоритме формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=9739</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=9739"/>
		<updated>2016-10-15T13:38:27Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt;&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
Используемые формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;):&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=9732</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=9732"/>
		<updated>2016-10-15T13:35:39Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt;&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
Используемые формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Оценить аналитически последовательную сложность представленного алгоритма невозможно в силу того, что нельзя указать количество разбиений отрезка интегрирования для каждой отдельно взятой функции.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
*Пусть есть доступный всем параллельным процессам список отрезков интегрирования,организованный в виде стека. Назовем его глобальным стеком.&lt;br /&gt;
*Пусть у каждого процесса есть свой, доступный только этому процессу локальный стек&lt;br /&gt;
*Перед запуском параллельных процессов в глобальный стек помещается единственная запись (в дальнейшем &amp;quot;отрезок&amp;quot;:&lt;br /&gt;
    координаты концов отрезка интегрирования, &lt;br /&gt;
    значения функции на концах,&lt;br /&gt;
    приближенное значение интеграла на этом отрезке.&lt;br /&gt;
*Тогда, предлагается следующая схема алгоритма, выполняемого каждым из параллельных процессов:&lt;br /&gt;
&lt;br /&gt;
Пока в глобальном стеке есть отрезки:&lt;br /&gt;
*взять один отрезок из глобального стека&lt;br /&gt;
*выполнить алгоритм локального стека, но,если при записи в локальный стек в нем есть несколько отрезков, а в глобальном стеке отрезки отсутствуют, то переместить часть отрезков из локального стека в глобальный стек&lt;br /&gt;
* по исчерпании локального стека добавить полученную частичную сумму к общему значению интеграла.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
В настоящее время проблемой вычисления определенного графа на адаптивной сетке по нашим сведениям занимались только М.В. Якобовский и Е.Ю. Кулькова, рассматривавшие в своей работе &amp;quot;РЕШЕНИЕ ЗАДАЧ НА МНОГОПРОЦЕССОРНЫХ ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМАХ С РАЗДЕЛЯЕМОЙ ПАМЯТЬЮ&amp;quot; методы локального и глобального стеков.&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=9266</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=9266"/>
		<updated>2016-10-15T11:29:35Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt;&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
Используемые формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=9264</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=9264"/>
		<updated>2016-10-15T11:28:53Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt;&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Входные данные:&#039;&#039; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;,точное решение, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Выходные данные:&#039;&#039; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
Используемые формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=9263</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=9263"/>
		<updated>2016-10-15T11:27:41Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt;&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Входные данные:&amp;quot; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;,точное решение, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;quot;Выходные данные:&amp;quot; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла   &amp;lt;br /&amp;gt;                                        &lt;br /&gt;
Используемые формулы:&amp;lt;br /&amp;gt;&lt;br /&gt;
*Из метода трапеций &amp;lt;math&amp;gt;sAB=\frac{f(A)+f(B)}{2}*(B-A)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
#нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
#вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
#определение выполнения условия точности:&lt;br /&gt;
#*если не выполняется, то продолжаем дробить область,&amp;quot;закладывая&amp;quot; в стек границы нового интервала, &lt;br /&gt;
#*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=9201</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=9201"/>
		<updated>2016-10-15T11:05:42Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt;&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Входные данные:&amp;quot; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;,точное решение, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;quot;Выходные данные:&amp;quot; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла                                           &lt;br /&gt;
 &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
1)нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
2)вычисление частичных сумм на подобластях методом трапеций;&amp;lt;br /&amp;gt;&lt;br /&gt;
3)определение выполнения условия точности &amp;lt;math&amp;gt;(|sAB-sACB|)/|sACB|&amp;lt;ε&amp;lt;/math&amp;gt;&lt;br /&gt;
*если не выполняется, то продолжаем дробить область путем перезаписывания в стеке границ интервала, &lt;br /&gt;
*иначе добавляем к результату вычисленную сумму, завершая цикл. &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=9110</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=9110"/>
		<updated>2016-10-15T10:43:27Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt;&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Входные данные:&amp;quot; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;,точное решение, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;quot;Выходные данные:&amp;quot; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла                                           &lt;br /&gt;
 &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Основное время работы алгоритма приходится на:&amp;lt;br /&amp;gt;&lt;br /&gt;
1)нахождение середины отрезка и значения функции в этой точке;&amp;lt;br /&amp;gt;&lt;br /&gt;
2)вычисление частичных сумм;&amp;lt;br /&amp;gt;&lt;br /&gt;
3)определение выполнения условия точности &amp;lt;math&amp;gt;(|sAB-sACB|)/|sACB|&amp;lt;ε&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=7366</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=7366"/>
		<updated>2016-10-14T11:25:19Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt;&lt;br /&gt;
Существуют различные последовательные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. Представим общее описание для методов рекурсивного деления и локального стека.&lt;br /&gt;
&lt;br /&gt;
====Метод рекурсивного деления====&lt;br /&gt;
&lt;br /&gt;
Простейший из них - это метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования. Интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью. Но при распараллеливании этого алгоритма (т.е. при запуске попарно подпрограмм, обрабатывающих половинки разбиваемого интервала) можно столкнуться со следующей проблемой: в реальной системе число процессоров ограничено и время, необходимое для порождения параллельных процессов существенно не равно нулю. А значит, запуск процессов, число которых значительно превышает число физических процессов системы при решении рассматриваемой задачи, приводит к увеличению времени ее решения по сравнению с последовательной программой. Основная сложность построения параллельного алгоритма на основе рассмотренного последовательного алгоритма, кроется в том, что, хотя несколько ветвей программы могли бы одновременно обрабатывать разные части интервала интегрирования, координаты концов этих отрезков хранятся в программном стеке процесса и фактически недоступны программисту. Если бы они были расположены в некотором явно описанном массиве, можно было бы передать их по частям для обработки разным нитям программы. Поэтому, необходимо рассмотреть метод локального стека, позволяющий распределить вычислительную работу между ограниченным числом процессов.&lt;br /&gt;
&lt;br /&gt;
====Метод локального стека====&lt;br /&gt;
&lt;br /&gt;
В основе этого алгоритма лежит описанный выше метод рекурсивного деления. Только данный метод использует массив данных, доступ к которым осуществляется по принципу стека - первым удаляется последний из добавленных элементов. В рассматриваемом алгоритме вместо стека можно было использовать и другие способы хранения заданий, например очередь. Стек выбран исключительно из соображений простоты реализации. Времена выполнения рассмотренных алгоритмов отличаются примерно на 5% в пользу локального стека, таким образом, алгоритм &amp;quot;локального стека&amp;quot; будем считать наилучшим из имеющихся в нашем распоряжении последовательных методов и на его примере построим дальнейшее описание.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Входные данные:&amp;quot; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;,точное решение, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;quot;Выходные данные:&amp;quot; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла                                           &lt;br /&gt;
 &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Lineprinter&amp;diff=7263</id>
		<title>Обсуждение участника:Lineprinter</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Lineprinter&amp;diff=7263"/>
		<updated>2016-10-14T10:07:04Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: /* Перенос */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Перенос ==&lt;br /&gt;
Статья: [[Алгоритм кластеризации, основанный на сетях Кохоннена]];&lt;br /&gt;
Выполняют:  Логвиненко Александра и Адиев Тохтар&lt;br /&gt;
&lt;br /&gt;
Статья: [[Ортогонализация Грама-Шмидта]];&lt;br /&gt;
Выполняют: [[Участник:KibAndrey| Кибанов Андрей]] и Аджиева Татьяна&lt;br /&gt;
&lt;br /&gt;
Статья: [[Самоорганизующиеся карты Кохонена]];&lt;br /&gt;
Выполняет: [[Участник:Anton goy| Гой Антон]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[ЕМ-алгоритм_(Тематическое_моделирование)]];&lt;br /&gt;
Выполняют: Мурат Апишев и Андрей Заночкин&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_Ланцоша_с_полной_переортогонализацией]];&lt;br /&gt;
Выполняет:[[Участник:Sfedotov| Федотов С.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм_k-средних]]&lt;br /&gt;
Выполняют: [[Участник:Error2407|Богомазов Евгений]], [[Участник:Илья_Егоров|Егоров Илья]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Решение_задачи_Коши_для_системы_ОДУ_методом_Рунге-Кутты_4_порядка]];&lt;br /&gt;
Выполняют: [[Участник:Алимов_Дамир_Алиевич|Алимов Дамир]] и [[Участник:Anlesnichiy|Антон Лесничий]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Строгий_алгоритм_С_средних_(Hard_C-Means,_HCM)]];&lt;br /&gt;
Выполняют: [[Участник:Светлана_Лукьяненко|Лукьяненко Светлана]] и [[Участник:Юрий_Комаров|Комаров Юрий]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм кластеризации, основанный на минимальном остовном дереве]];&lt;br /&gt;
Выполняет: [[Участник:Astandrik | Стандрик Антон Сергеевич]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Нахождение_собственных_чисел_квадратной_матрицы_методом_QR_разложения_(3)|Нахождение собственных чисел квадратной матрицы методом QR разложения (3)]];&lt;br /&gt;
Выполняют: [[Участник:Смирнова_Александра|Смирнова А.С.]], [[Участник:Александра_Киямова|Киямова А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод_Якоби_вычисления_сингулярных_чисел_и_векторов]];&lt;br /&gt;
Выполняют: [[Участница:Почернина_Елена| Почернина Елена]] и [[Участница:Светлана|Костюкова Светлана]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод_Ньютона_для_решения_систем_нелинейных_уравнений(2)]];&lt;br /&gt;
Выполняют: [[Участник:Oleggium|Гирняк О.Р.]], [[Участник:Dimx19|Васильков Д.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм_кластеризации_с_использованием_представлений]];&lt;br /&gt;
Выполняют: [[Участник:Cookie|Шатков С.А.]], [[Антохина Ю.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Быстрое_преобразование_Фурье_(FFT)|Быстрое преобразование Фурье (FFT)]];&lt;br /&gt;
Выполняют: [[Участник:Victoria_Stepanischeva|Степанищева Виктория]] и [[Участник:Igor_Munkin|Мунькин Игорь]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Быстрое_дискретное_преобразование_Фурье|Быстрое_дискретное_преобразование_Фурье]];&lt;br /&gt;
Выполняют: [[Участник:ivanov.kir.m | К.М.Иванов]], [[Участник:Pumpkin | А.C.Сапин]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_k_средних]]&lt;br /&gt;
Выполняют: [[Участник:Parkhomenko|Пархоменко Павел]], [[Участник:ivan.mashonskiy|Машонский Иван]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[EM-алгоритм_кластеризации]]&lt;br /&gt;
Выполняет: [[Участник:Noite|Зинченко Дмитрий]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_k_means]]&lt;br /&gt;
Выполняют: [[Участник:IanaV| Валуйская Яна]], [[Глотов Евгений]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод Якоби вычисления собственных значений симметричной матрицы ЗП |Метод Якоби вычисления собственных значений симметричной матрицы ЗП]];&lt;br /&gt;
Выполняют: [[Участник:Зиновьев Владимир|Зиновьев В.С.]], [[Участник:Пронин Андрей|Пронин А.М.]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_кластеризации,_основанный_на_минимальном_покрывающем_дереве]]&lt;br /&gt;
Выполняет: [[Участник:Kanast74|Дмитриева Анастасия]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Нахождение_собственных_чисел_квадратной_матрицы_методом_QR_разложения_(4)]]&lt;br /&gt;
Выполняют: [[Участник:F-morozov|Морозов Ф. В.]], [[Участник:Nataliya|Пащенко Н. Ф.]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Хранение_ненулевых_элементов_разреженных_матриц._Умножение_разреженной_матрицы_на_вектор]];&lt;br /&gt;
Выполняют: [[Участник:Trrufina|Третьякова Р.М.]] и [[Участник:Екатерина_Буторина|Буторина Е.В.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм_кластеризации_с_использованием_представлений2]];&lt;br /&gt;
Выполняет: [[Участник:Лукьянова Анна|Лукьянова А.Я.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод Якоби вычисления собственных значений симметричной матрицы]];&lt;br /&gt;
Выполняют: [[Участник: Galkina|Галкина А.С.]], [[Участник: Игорь|Плахов И.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод рекурсивной координатной бисекции]];&lt;br /&gt;
Выполняют: [[Участник: Obirvalger|Гордеев Михаил]], [[Участник: KolmakovEA|Колмаков Евгений]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Итерационный метод решения системы линейных алгебраических уравнений GMRES (обобщенный метод минимальных невязок)]];&lt;br /&gt;
Выполняют: [[Участник: Эльвира Ахиярова|Ахиярова Эльвира]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Хранение ненулевых элементов разреженной матрицы. Умножение разреженной матрицы на вектор]];&lt;br /&gt;
Выполняют: [[Участник: Janyell|Сычева Евгения]], [[Участник: Ahahalin|Хахалин Анатолий]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Построение матрицы Адамара произвольного размера]];&lt;br /&gt;
Выполняют: [[Участник: Бугаков Юрий|Бугаков Юрий]], Кужамалиев Ернур&lt;br /&gt;
&lt;br /&gt;
Статья: [[Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)]]&lt;br /&gt;
Выполняют: [[Участница:Sannikovats| Санникова Татьяна Сергеевна]], [[Участник:Plukshin| Лукшин Петр Андреевич]]&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=5587</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=5587"/>
		<updated>2016-10-12T07:00:21Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt;&lt;br /&gt;
Существуют различные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. В данной статье будет рассмотрен простейший метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования.&lt;br /&gt;
Суть метода: интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Входные данные:&amp;quot; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;,точное решение, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;quot;Выходные данные:&amp;quot; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла                                           &lt;br /&gt;
 &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=5479</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=5479"/>
		<updated>2016-10-11T20:50:28Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Петр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt;&lt;br /&gt;
Существуют различные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. В данной статье будет рассмотрен простейший метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования.&lt;br /&gt;
Суть метода: интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Исходные данные:&amp;quot; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;,точное решение, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;quot;Выходные данные:&amp;quot; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла                                           &lt;br /&gt;
 &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=5431</id>
		<title>Участница:Sannikovats/Вычисление определенного интеграла с использованием адаптивно сгущающейся сетки (1)</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats/%D0%92%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE_%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D0%BB%D0%B0_%D1%81_%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC_%D0%B0%D0%B4%D0%B0%D0%BF%D1%82%D0%B8%D0%B2%D0%BD%D0%BE_%D1%81%D0%B3%D1%83%D1%89%D0%B0%D1%8E%D1%89%D0%B5%D0%B9%D1%81%D1%8F_%D1%81%D0%B5%D1%82%D0%BA%D0%B8_(1)&amp;diff=5431"/>
		<updated>2016-10-11T19:35:45Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: Новая страница: «{{algorithm | name              = Вычисление определённого интеграла с использованием адаптивно сгуща…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Вычисление определённого интеграла с использованием адаптивно сгущающейся сетки&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;...&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания:[[Участница:Sannikovats| Санникова Татьяна Сергеевна]],[[Участник:Plukshin| Лукшин Пётр Андреевич]].&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Допустим, нам дана функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; , определенная на отрезке, и возможность получать ее численное значение в любой из точек области определения за фиксированное время. Задача — вычислить определенный интеграл данной функции по заданной области и дать оценку погрешности вычисления.&amp;lt;br /&amp;gt;&lt;br /&gt;
Существуют различные методы построения адаптивных подвижных сеток, которые позволяют значительно повысить точность вычисления определенного интеграла за счет учета характера изменения подынтегральной функции. В данной статье будет рассмотрен простейший метод рекурсивного деления, выигрыш от применения которого достигается за счет возможности использования сеток с разным числом узлов на разных участках интервала интегрирования.&lt;br /&gt;
Суть метода: интервал интегрирования разбивается на две части и независимо интегрируется функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; на каждой из них при соответствующих шагах интегрирования. Процедуру разбиения отрезков можно рекурсивно повторить до получения отрезков, на которых подынтегральная функция имеет простой вид и может быть аппроксимирована отрезком прямой с заданной точностью.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Исходные данные:&amp;quot; заданная функция &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt;, определенная на отрезке &amp;lt;math&amp;gt;[A,B]&amp;lt;/math&amp;gt;,точное решение, заданная точность решения ε.&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;quot;Выходные данные:&amp;quot; число, представляющее собой приближенное значение интеграла.&amp;lt;br /&amp;gt;&lt;br /&gt;
В качестве модельной задачи рассматривается проблема вычисления с точностью ε значения определенного интеграла                                           &lt;br /&gt;
 &lt;br /&gt;
[[Файл:1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats&amp;diff=5425</id>
		<title>Участница:Sannikovats</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:Sannikovats&amp;diff=5425"/>
		<updated>2016-10-11T19:18:48Z</updated>

		<summary type="html">&lt;p&gt;Sannikovats: Новая страница: «Санникова Татьяна - магистрантка факультета ВМК МГУ, 604 группа»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Санникова Татьяна - магистрантка факультета ВМК МГУ, 604 группа&lt;/div&gt;</summary>
		<author><name>Sannikovats</name></author>
	</entry>
</feed>