<?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=Dan</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=Dan"/>
	<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/Dan"/>
	<updated>2026-10-22T22:08:05Z</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%D0%BA:%D0%90%D0%BD%D1%8E%D1%88%D0%B5%D0%B2%D0%B0_%D0%98%D1%80%D0%B8%D0%BD%D0%B0/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES_(%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D0%BD%D0%B5%D0%B2%D1%8F%D0%B7%D0%BE%D0%BA)&amp;diff=19978</id>
		<title>Участник:Анюшева Ирина/Итерационный метод решения системы линейных алгебраических уравнений GMRES (обобщенный метод минимальных невязок)</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%D0%BA:%D0%90%D0%BD%D1%8E%D1%88%D0%B5%D0%B2%D0%B0_%D0%98%D1%80%D0%B8%D0%BD%D0%B0/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES_(%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D0%BD%D0%B5%D0%B2%D1%8F%D0%B7%D0%BE%D0%BA)&amp;diff=19978"/>
		<updated>2016-12-03T14:04:03Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = GMRES (обобщенный метод минимальных невязок)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(m^2n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(mn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(mn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n^2+2n&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[U:Анюшева Ирина|Анюшева Ирина]] (614 группа, разделы: 1.1-1.2, 1.7-1.8, 2.7, 3), Исхаков Эльдар (614 группа, разделы 1.3-1.6, 1.9-1.10)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритма =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Обобщенный метод минимальных невязок (GMRES) для решения системы линейных алгебраических уравнений аппроксимирует решение с помощью вектора в подпространстве Крылова с минимальным остатком. Метод GMRES разработан Ю.Саадом и Мартин Х. Шульцом в 1986 году.  Метод по праву считается одним из самых эффективных численных методов решения несимметричных систем. Он гарантирует неувеличение нормы невязки в ходе итерационного процесса, который основан на построении базиса в соответствующей системе подпространстве Крылова &amp;lt;math&amp;gt;K_j(A, r_0)&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем решение уточняется некоторой добавкой, представленной в виде разложения по этому базису.&lt;br /&gt;
&lt;br /&gt;
Метод обобщенных минимальных невязок популярен из-за наличия ряда преимуществ: он ошибкоустойчив, допускает эффективное распараллеливание, не требует нахождения параметра релаксации, обладает суперлинейной скоростью сходимости. Однако в чистом виде для больших систем метод не используется из-за чрезвычайно больших затрат памяти. Зато широкое распространение получила перезапускаемая версия метода, подоразумевающая перезапуск метода каждые m итераций. Уменьшение размерности пространства может привести к стагнации метода – процессу, при котором с каждой следующей итерацией норма невязки уменьшается незначительно, либо не уменьшается вовсе.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: система линейных алгебраических уравнений &amp;lt;math&amp;gt;Ax=b&amp;lt;/math&amp;gt;, где:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A=(a_{ij})&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt; вещественная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; вектора из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x^*&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt; точное решение системы.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: &amp;lt;math&amp;gt;x^{(s)} - &amp;lt;/math&amp;gt;приближенное решение системы.&lt;br /&gt;
&lt;br /&gt;
===Ортогонализация Арнольди===&lt;br /&gt;
Для построения базиса &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; в подпространстве Крылова в методе GMRES применяется ортогонализация Арнольди.&lt;br /&gt;
&lt;br /&gt;
Формулы метода:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(h_{i+1,i}v_{i+1}) &amp;amp; = Av_i - \sum_{j = 1}^{i} h_{j,i}v_j, \\&lt;br /&gt;
v_1 &amp;amp;= \frac{r_0}{\parallel r_0 \parallel},&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
В матрично-векторных обозначениях соотношение может быть записано как&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
AV_i &amp;amp;= V_i H_i + h_{i+1,i}v_{i+1} e_i^T &amp;amp;=V_{i+1}\overline{H}_i,&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
V_i &amp;amp;= [v_1|v_2|...|v_i], \overline{H}_i - \end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt; верхняя матрица Хессенберга размерности &amp;lt;math&amp;gt;(i+1)\times i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Минимизация невязки===&lt;br /&gt;
&lt;br /&gt;
Невязку уравнения можно определить как&lt;br /&gt;
&amp;lt;math&amp;gt; J(y) = \parallel b- A x\parallel = \parallel b- (Ax_0+V_m y)\parallel =\parallel \beta e_1 - \overline{H}_m y \parallel&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;y -&amp;lt;/math&amp;gt; вектор размерности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вектор &amp;lt;math&amp;gt;x_m&amp;lt;/math&amp;gt; может быть получен как &lt;br /&gt;
&amp;lt;math&amp;gt;x_m = x_0 + V_m y_m&amp;lt;/math&amp;gt;, вектор &amp;lt;math&amp;gt;y_m&amp;lt;/math&amp;gt; может найден как решение линейной задачи наименьших квадратов размера &amp;lt;math&amp;gt;(m+1)\times m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m&amp;lt;&amp;lt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для решения задачи минимизации приведем матрицу &amp;lt;math&amp;gt;\overline{H}_m&amp;lt;/math&amp;gt; к верхнему треугольному виду с помощью вращений Гивенса. На шаге &lt;br /&gt;
&amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; матрица вращения &amp;lt;math&amp;gt;\Omega_i&amp;lt;/math&amp;gt; имеет размеры &amp;lt;math&amp;gt;(m+1)\times (m+1)&amp;lt;/math&amp;gt; и имеет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\Omega_i= \begin{pmatrix}&lt;br /&gt;
1 &amp;amp; &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
&amp;amp;\ddots &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;\\&lt;br /&gt;
&amp;amp;&amp;amp;1&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\        &lt;br /&gt;
&amp;amp;&amp;amp;&amp;amp;c_i&amp;amp;s_i &amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
&amp;amp;&amp;amp;&amp;amp;-s_i&amp;amp; c_i &amp;amp;&amp;amp;&amp;amp;\\&lt;br /&gt;
&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;1&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;\ddots&amp;amp;\\&lt;br /&gt;
&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;1 \\  &lt;br /&gt;
\end{pmatrix}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
&lt;br /&gt;
В алгоритме GMRES присутствуют два ресурсоемких с точки зрения вычислительных мощностей этапа:&lt;br /&gt;
&lt;br /&gt;
* умножение исходной матрицы на вектор при вычислении невязок;&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;
1. Выбрать произвольное &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt;; вычислить &amp;lt;math&amp;gt;r_0=b-Ax_0&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v_1=\frac{r_0}{\parallel r_0 \parallel}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Задать матрицу &amp;lt;math&amp;gt;\overline{H}_m&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;(m+1)\times m&amp;lt;/math&amp;gt; и всем ее элементам присвоить нулевые значения&lt;br /&gt;
&lt;br /&gt;
3. Для &amp;lt;math&amp;gt;j=1,\dots,m&amp;lt;/math&amp;gt; выполнять:&lt;br /&gt;
&lt;br /&gt;
* для &amp;lt;math&amp;gt;i=1,\dots,j&amp;lt;/math&amp;gt; выполнять: &amp;lt;math&amp;gt;h_{i,j}=(Av_j,v_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\omega_j=Av_j-\sum_{i=1}^j h_{i,j}v_i&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;h_{j+1,j}={\parallel \omega_j \parallel}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;v_{j+1}=\frac{\omega_j}{h_{j+1,j}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Вычислить &amp;lt;math&amp;gt;y_m=\arg\min_{y} \parallel \beta e_1 - \overline{H}_my \parallel,\ y \in \mathbb{R}^m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;x_m=x_0+V_my_m&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. Вычислить &amp;lt;math&amp;gt;r_m=b-Ax_m&amp;lt;/math&amp;gt;. Если достигнутая точность удовлетворительна, остановиться.&lt;br /&gt;
&lt;br /&gt;
Иначе принять &amp;lt;math&amp;gt;x_0=x_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v_1=\frac{r_m}{\parallel r_m \parallel}&amp;lt;/math&amp;gt; и вернуться к пункту 2.&lt;br /&gt;
&lt;br /&gt;
===Решение задачи минимизации невязки===&lt;br /&gt;
&lt;br /&gt;
Для нахождения &amp;lt;math&amp;gt;y_m=\arg\min_{y} \parallel \beta e_1 - \overline{H}_my \parallel&amp;lt;/math&amp;gt; необходимо выполнить следующие шаги:&lt;br /&gt;
&lt;br /&gt;
1. Найти &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; матриц вращений Гивенса &amp;lt;math&amp;gt;\Omega_i(c_i,s_i),\ i=1,\dots,m&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;(m+1)\times(m+1)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;s_i=\frac{h_{i+1,i}}{\sqrt{h_{i,i}^2+h_{i+1,i}^2}}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_i=\frac{h_{i,i}}{\sqrt{h_{i,i}^2+h_{i+1,i}^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Вычислить &amp;lt;math&amp;gt;\overline{H}_m^{(m)}=\Omega_1\dots\Omega_m\overline{H}_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\overline{g}_m=\Omega_1\dots\Omega_m\beta e_1&amp;lt;/math&amp;gt;, удалить последнюю строку и последний элемент соответственно и решить СЛАУ с полученной верхнетреугольной матрицей и правой частью. Полученное решение &amp;lt;math&amp;gt;y_m&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;math&amp;gt;3m+1&amp;lt;/math&amp;gt; делений;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;2m+1&amp;lt;/math&amp;gt; вычислений квадратного корня;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{3m+5}{2}n&amp;lt;/math&amp;gt; умножений;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;O(\frac{m^2n^2}{2})&amp;lt;/math&amp;gt; сложений (вычитаний).&lt;br /&gt;
&lt;br /&gt;
==Информационный граф==&lt;br /&gt;
Метод состоит из двух блоков: ортогонализация и минимизация невязки. При ортогонализации основными операциями являются умножение матрицы на вектор и скалярное умножение векторов, для которых возможен параллелизм, что показано в блоке на темно-синем фоне. В блоке &amp;lt;math&amp;gt;min&amp;lt;/math&amp;gt; решается задача минимизации невязки, которая, строго говоря, является отдельной самостоятельной задачей.&lt;br /&gt;
[[file:gmres.jpg|thumb|center|700px|Рис.1. Информационная структура алгоритма GMRES]]&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
Для нахождения матрично-векторных произведений при вычислении невязок матрица СЛАУ должна быть подвергнута декомпозиции на строчные блоки, размеры которых определяются требованиями равномерности загрузки. Соответствующим образом подвергается декомпозиции и вектор правой части. Для наиболее эффективного вычисления скалярных произведений и линейных комбинаций векторов базиса каждый из векторов &amp;lt;math&amp;gt;v_j&amp;lt;/math&amp;gt; должен быть разбит на блоки равного размера по числу процессов; каждый из процессов при этом хранит соответствующие блоки всех векторов. Обработка вектора решения дублируется на всех процессах.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;;&lt;br /&gt;
* вектор-столбец &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;;&lt;br /&gt;
* вектор-столбец &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - начальное приближение;  &lt;br /&gt;
* натуральное число &amp;lt;math&amp;gt;m&amp;lt;&amp;lt;n&amp;lt;/math&amp;gt;, определяющее размерность подпространства Крылова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* вектор-столбец &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - решение системы.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
&lt;br /&gt;
* Вычислительная мощность: весьма маленькая и равна &amp;lt;math&amp;gt;m^2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;m&amp;lt;&amp;lt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Устойчивость: GMRES в этом плане является очень хорошим методом. Теоретически можно получить точное решение не более чем за &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итераций. Однако, очень приемлемые результаты получаются и за &amp;lt;math&amp;gt;m&amp;lt;&amp;lt;n&amp;lt;/math&amp;gt; итераций. Однако, есть примеры, в которых видно, что первые &amp;lt;math&amp;gt;m-1&amp;lt;/math&amp;gt; итераций дают невязку, равную некой константе, а на итерации под номером &amp;lt;math&amp;gt;m&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;
Исследование масштабируемости параллельной реализации итерационного метода решения системы линейных алгебраических уравнений GMRES проводилось в тестовой среде суперкомпьютера &amp;quot;Ломоносов&amp;quot;. Алгоритм реализован на языке С с использованием библиотеки IntelMPI версии 4.1.0. Сборка производилась при помощи компилятора, разработанным компанией Intel версии 13.1.0.&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска:&lt;br /&gt;
*число процессов [1 : 128] со значениями, равными степеням двойки;&lt;br /&gt;
*размер матрицы [128 : 2048] с шагом 128.&lt;br /&gt;
В результате проведенных экспериментов был получен следующий диапазон эффективности реализации алгоритма:&lt;br /&gt;
*минимальная эффективность реализации 0.002%;&lt;br /&gt;
*максимальная эффективность реализации 4.92%.&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации в зависимости от изменяемых параметров запуска. Размерность подпространства Крылова во всех случаях равна 10.&lt;br /&gt;
[[File:Anyusheva iskhakovPerformance.jpg|thumb|center|1500px|Рис.2 Изменение производительности выполнения в зависимости от числа процессов и размера входной матрицы]]&lt;br /&gt;
[[File:Anyusheva iskhakovEfficiency.jpg|thumb|center|1500px|Рис.3 Изменение эффективности выполнения в зависимости от числа процессов и размера входной матрицы]]&lt;br /&gt;
Из рисунков видно, что при увеличении количества процессов, а также при увеличении размерности задачи, производительность параллельной реализации алгоритма уменьшается, что говорит о плохой масштабируемости. &lt;br /&gt;
Исследуемая реализация алгоритма доступна по [http://pastebin.com/vEyb3kuS ссылке].&lt;br /&gt;
&lt;br /&gt;
==Динамические характеристики и эффективность реализации алгоритма==&lt;br /&gt;
&lt;br /&gt;
==Выводы для классов архитектур==&lt;br /&gt;
&lt;br /&gt;
==Существующие реализации алгоритма==&lt;br /&gt;
* Реализация алгоритма в библиотеке SciPy [https://docs.scipy.org/doc/scipy-0.17.0/reference/generated/scipy.sparse.linalg.gmres.html]&lt;br /&gt;
* Реализация алгоритма в библиотеке IML++ [http://math.nist.gov/iml++/gmres.h.txt]&lt;br /&gt;
* Библиотека для MATLAB [http://www.mathworks.com/help/matlab/ref/gmres.html]&lt;br /&gt;
&lt;br /&gt;
= Литература=&lt;br /&gt;
1. Y. Saad, M.H. Schultz. GMRES: A generalized minimal residual algorithm for solving nonsymmetric linear systems. SIAM J. Sci. Statist. Comput., 7 (1986), pp. 856–869&lt;br /&gt;
&lt;br /&gt;
2. Е.Е. Тыртышников. Методы численного анализа. – Москва: Академия, 2007&lt;br /&gt;
&lt;br /&gt;
3. М.Ю. Баландин, Э.П. Шурина. Некоторые оценки эффективности параллельных алгоритмов решения СЛАУ на подпространствах Крылова. - Вычислительные технологии, том 3, №1, 1998&lt;/div&gt;</summary>
		<author><name>Dan</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:%D0%90%D0%BD%D1%8E%D1%88%D0%B5%D0%B2%D0%B0_%D0%98%D1%80%D0%B8%D0%BD%D0%B0&amp;diff=19977</id>
		<title>Обсуждение участника:Анюшева Ирина</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:%D0%90%D0%BD%D1%8E%D1%88%D0%B5%D0%B2%D0%B0_%D0%98%D1%80%D0%B8%D0%BD%D0%B0&amp;diff=19977"/>
		<updated>2016-12-03T14:03:51Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK) К работе есть несколько замечаний по содержанию (отмечены моей подписью), помимо выполнения требований к работе&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 2.4 =&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 17:03, 3 декабря 2016 (MSK) Добавьте строки запуска и компиляции со всеми ключами&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.1 =&lt;br /&gt;
--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Обобщенный метод минимальных невязок (GMRES) для решения системы линейных алгебраических уравнений аппроксимирует решение с помощью вектора в подпространстве Крылова с минимальным остатком.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Что здесь подразумевается по «минимальным остатком»?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Метод по праву считается одним из самых эффективных численных методов решения несимметричных систем.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Чем GMRES эффективнее с вычислительной точки зрения, например, других итерационных Крыловских методов для несимметричных матриц? &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Метод обобщенных минимальных невязок популярен из-за наличия ряда преимуществ: он ошибкоустойчив, допускает эффективное распараллеливание, не требует нахождения параметра релаксации, обладает суперлинейной скоростью сходимости.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Нужно пояснить, что подразумевается под ошибкоустойчивостью метода? Причем здесь параметр релаксации? Обычно вместо «суперлинейной сходимости», пишут сверхлинейная сходимость. Хорошо бы выделить класс методов, с которыми сравнивается GMRES в плане эффективности и преимуществ. Так, например, стабилизированный метод бисопряженных градиентов также «допускает эффективное распараллеливание и не требует нахождения параметра релаксации».&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Зато широкое распространение получила перезапускаемая версия метода, подоразумевающая перезапуск метода каждые m итераций.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Сохраняются ли преимущества метода для версии метода GMRES с рестартами? Например, сверхлинейная сходимость и ошибкоустойчивость? Свойства (достоинства и недостатки) GMRES(m) лучше описать подробнее.&lt;br /&gt;
&lt;br /&gt;
Опечатка - &#039;&#039;&#039;подоразумевающая перезапуск метода каждые m итераций&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.2.1 =&lt;br /&gt;
--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
Нужно уточнить какая норма здесь рассматривается. Также в нескольких местах (в этом и следующих разделах) при записи нормы пропущена одна правая вертикальная скобка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.5.1 =&lt;br /&gt;
--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выбрать произвольное &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt;;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для любого &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt; достигается сходимость?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.6 =&lt;br /&gt;
--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
Нужно дополнить раздел оценками для разреженной матрицы по числу ненулевых элементов. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.7 =&lt;br /&gt;
--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
Хорошо бы подробнее описать структуру алгоритма в блоках ортогонализации и минимизации невязки. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.8 =&lt;br /&gt;
--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Для нахождения матрично-векторных произведений при вычислении невязок матрица СЛАУ должна быть подвергнута декомпозиции на строчные блоки, размеры которых определяются требованиями равномерности загрузки.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Можно ли рассматривать декомпозицию матрицы по «двумерным» блокам, а не только по строкам?&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Обработка вектора решения дублируется на всех процессах.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
В практических задачах размерность вектора решения может быть очень большой и не помещаться в память процессора. Как предлагается решать такие задачи? Если такие задачи не рассматриваются, то это нужно явно прописать.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.10 =&lt;br /&gt;
--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Однако, есть примеры, в которых видно, что первые &amp;lt;math&amp;gt;m-1&amp;lt;/math&amp;gt; итераций дают невязку, равную некой константе, а на итерации под номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; получаем точное решение&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Нужно привести такие примеры и описать подробнее данные случаи или указать ссылку на работу, где такие примеры построены.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 2.4 =&lt;br /&gt;
--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
Нужно описать структуру матрицы, которая рассматривалась в экспериментах. Какое условие на выход из итерационного процесса использовалось в расчетах?&lt;br /&gt;
&lt;br /&gt;
С чем связана такая низкая эффективность реализации?&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Из рисунков видно, что при увеличении количества процессов, а также при увеличении размерности задачи, производительность параллельной реализации алгоритма уменьшается, что говорит о плохой масштабируемости.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Нужно объяснить в чем причина плохой масштабируемости алгоритма. Особенно с учетом того, что в разделе 1.1 Вы пишите о том, что метод GMRES «допускает эффективное распараллеливание».&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Dan</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:%D0%90%D0%BD%D1%8E%D1%88%D0%B5%D0%B2%D0%B0_%D0%98%D1%80%D0%B8%D0%BD%D0%B0&amp;diff=19976</id>
		<title>Обсуждение участника:Анюшева Ирина</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:%D0%90%D0%BD%D1%8E%D1%88%D0%B5%D0%B2%D0%B0_%D0%98%D1%80%D0%B8%D0%BD%D0%B0&amp;diff=19976"/>
		<updated>2016-12-03T14:03:27Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK) К работе есть несколько замечаний по содержанию (отмечены моей подписью), помимо выполнения требований к работе&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 2.4 =&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 17:03, 3 декабря 2016 (MSK) Добавьте строки запуска и компиляции со всему ключами&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.1 =&lt;br /&gt;
--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Обобщенный метод минимальных невязок (GMRES) для решения системы линейных алгебраических уравнений аппроксимирует решение с помощью вектора в подпространстве Крылова с минимальным остатком.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Что здесь подразумевается по «минимальным остатком»?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Метод по праву считается одним из самых эффективных численных методов решения несимметричных систем.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Чем GMRES эффективнее с вычислительной точки зрения, например, других итерационных Крыловских методов для несимметричных матриц? &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Метод обобщенных минимальных невязок популярен из-за наличия ряда преимуществ: он ошибкоустойчив, допускает эффективное распараллеливание, не требует нахождения параметра релаксации, обладает суперлинейной скоростью сходимости.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Нужно пояснить, что подразумевается под ошибкоустойчивостью метода? Причем здесь параметр релаксации? Обычно вместо «суперлинейной сходимости», пишут сверхлинейная сходимость. Хорошо бы выделить класс методов, с которыми сравнивается GMRES в плане эффективности и преимуществ. Так, например, стабилизированный метод бисопряженных градиентов также «допускает эффективное распараллеливание и не требует нахождения параметра релаксации».&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Зато широкое распространение получила перезапускаемая версия метода, подоразумевающая перезапуск метода каждые m итераций.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Сохраняются ли преимущества метода для версии метода GMRES с рестартами? Например, сверхлинейная сходимость и ошибкоустойчивость? Свойства (достоинства и недостатки) GMRES(m) лучше описать подробнее.&lt;br /&gt;
&lt;br /&gt;
Опечатка - &#039;&#039;&#039;подоразумевающая перезапуск метода каждые m итераций&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.2.1 =&lt;br /&gt;
--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
Нужно уточнить какая норма здесь рассматривается. Также в нескольких местах (в этом и следующих разделах) при записи нормы пропущена одна правая вертикальная скобка.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.5.1 =&lt;br /&gt;
--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выбрать произвольное &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt;;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для любого &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt; достигается сходимость?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.6 =&lt;br /&gt;
--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
Нужно дополнить раздел оценками для разреженной матрицы по числу ненулевых элементов. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.7 =&lt;br /&gt;
--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
Хорошо бы подробнее описать структуру алгоритма в блоках ортогонализации и минимизации невязки. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.8 =&lt;br /&gt;
--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Для нахождения матрично-векторных произведений при вычислении невязок матрица СЛАУ должна быть подвергнута декомпозиции на строчные блоки, размеры которых определяются требованиями равномерности загрузки.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Можно ли рассматривать декомпозицию матрицы по «двумерным» блокам, а не только по строкам?&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Обработка вектора решения дублируется на всех процессах.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
В практических задачах размерность вектора решения может быть очень большой и не помещаться в память процессора. Как предлагается решать такие задачи? Если такие задачи не рассматриваются, то это нужно явно прописать.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.10 =&lt;br /&gt;
--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Однако, есть примеры, в которых видно, что первые &amp;lt;math&amp;gt;m-1&amp;lt;/math&amp;gt; итераций дают невязку, равную некой константе, а на итерации под номером &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; получаем точное решение&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Нужно привести такие примеры и описать подробнее данные случаи или указать ссылку на работу, где такие примеры построены.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 2.4 =&lt;br /&gt;
--[[Участник:Evgeny Mortikov|Evgeny Mortikov]] ([[Обсуждение участника:Evgeny Mortikov|обсуждение]]) 04:05, 3 декабря 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
Нужно описать структуру матрицы, которая рассматривалась в экспериментах. Какое условие на выход из итерационного процесса использовалось в расчетах?&lt;br /&gt;
&lt;br /&gt;
С чем связана такая низкая эффективность реализации?&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Из рисунков видно, что при увеличении количества процессов, а также при увеличении размерности задачи, производительность параллельной реализации алгоритма уменьшается, что говорит о плохой масштабируемости.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Нужно объяснить в чем причина плохой масштабируемости алгоритма. Особенно с учетом того, что в разделе 1.1 Вы пишите о том, что метод GMRES «допускает эффективное распараллеливание».&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:Alexander34396/%D0%9E%D0%B1%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D0%BD%D0%B5%D0%B2%D1%8F%D0%B7%D0%BE%D0%BA&amp;diff=19662</id>
		<title>Участник:Alexander34396/Обобщенный метод минимальных невязок</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%D0%BA:Alexander34396/%D0%9E%D0%B1%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D0%BD%D0%B5%D0%B2%D1%8F%D0%B7%D0%BE%D0%BA&amp;diff=19662"/>
		<updated>2016-11-30T16:10:08Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Dan}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[#Участник:Alexander34396|А.А.Ульянов]] (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Входные и выходные данные алгоритма|1.9]], [[#Существующие реализации алгоритма|2.7]]), [[#Участник:Kpetrov|К.Петров]] (разделы [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]]).&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Обобщенный метод минимальных невязок&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt; O(nm^2) &amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; (n + 1)^2 &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &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;
&#039;&#039;&#039;Обобщённый метод минимальных невязок&#039;&#039;&#039; ({{lang-en|Generalized minimal residual method, GMRES}}) - итерационный метод численного решения системы линейных алгебраических уравнений с невырожденной матрицей. Метод основан на минимизации квадратичного функционала невязки на подпространствах Крылова. Разработан Юсефом Саадом и Мартином Шульцем&amp;lt;ref&amp;gt; Y.Saad, M.H. Schultz, GMRES: A generalized minimal residual algorithm for solving nonsymmetric linear systems, SIAM J. Scientific and Stat. Comp. 7: 856-869 (1986) &amp;lt;/ref&amp;gt; в 1986 году как обобщение метода MINRES&amp;lt;ref&amp;gt;C. C. Paige and M. A. Saunders. Solution of sparse indefinite systems of linear equations, SIAM J. Numerical Analysis 12, 617-629 (1975)&amp;lt;/ref&amp;gt; на случай систем с несимметричными матрицами.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; &lt;br /&gt;
* система линейных алгебраических уравнений вида &amp;lt;math&amp;gt; Ax = b &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; — невырожденная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-на-&amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; - начальное приближение.&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; &lt;br /&gt;
* &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt; - приближённое решение исходной системы.&lt;br /&gt;
&lt;br /&gt;
Метод GMRES приближает точное решение исходной системы &amp;lt;math&amp;gt; Ax = b &amp;lt;/math&amp;gt; вектором &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt;, который минимизирует Евклидову норму невязки &amp;lt;math&amp;gt; r_m = Ax_m - b&amp;lt;/math&amp;gt; на подпространстве Крылова:&lt;br /&gt;
: &amp;lt;math&amp;gt; K_m = K_m(A,b) = \operatorname{span} \, \{ b, Ab, A^2b, \ldots, A^{m-1}b \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \operatorname{span} \, \{ a_1, a_2, \ldots, a_m \} &amp;lt;/math&amp;gt; - линейная оболочка системы векторов &amp;lt;math&amp;gt; \{ a_1, a_2, \ldots, a_m \} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На каждой итерации метода решение уточняется поправкой, представленной в виде разложения по ортонормированному базису пространства &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt;: &lt;br /&gt;
: &amp;lt;math&amp;gt; x_m = x_0 + z_m &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; - некоторое начальное приближение, &amp;lt;math&amp;gt; z_m \in K_m &amp;lt;/math&amp;gt; - поправка решения.&lt;br /&gt;
&lt;br /&gt;
=== Ортогонализация Арнольди ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортонормированного базиса &amp;lt;math&amp;gt; v_1, v_2, \ldots, v_m &amp;lt;/math&amp;gt; пространства Крылова &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt; метод использует процесс Арнольди.&lt;br /&gt;
&lt;br /&gt;
Идея процесса Арнольди состоит в том, что для нахождения вектора &amp;lt;math&amp;gt; v_{j+1} &amp;lt;/math&amp;gt; при известных векторах &amp;lt;math&amp;gt; v_1, v_2, \ldots, v_j &amp;lt;/math&amp;gt; необходимо вычислить вектор &amp;lt;math&amp;gt; Av_j &amp;lt;/math&amp;gt; и ортонормировать этот вектор относительно &amp;lt;math&amp;gt; v_1, v_2, \ldots, v_j &amp;lt;/math&amp;gt;:&lt;br /&gt;
: &amp;lt;math&amp;gt; v_{j+1} = \frac{\hat{v}_{j+1}}{\|\hat{v}_{j+1}\|_2} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \hat{v}_{j+1} = Av_j - \sum_{i=1}^j h_{ij}v_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Коэффициенты &amp;lt;math&amp;gt; h_{ij} = (Av_j, v_i) &amp;lt;/math&amp;gt; определяются из условия ортогональности:&lt;br /&gt;
: &amp;lt;math&amp;gt; A(v_j, v_k) - \sum_{i=1}^j h_{ij}(v_{i}, v_k)  = 0 &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \quad k=1,\ldots,j &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результат процедуры Арнольди совпадает с результатом процесса Грамма-Шмидта, применённого к векторам &amp;lt;math&amp;gt; \{b, Ab, A^2b, \ldots, A^{m-1}b\} &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; &lt;br /&gt;
* &amp;lt;math&amp;gt; v_1 &amp;lt;/math&amp;gt;, такой что &amp;lt;math&amp;gt; \|v_1\|_2 = 1 &amp;lt;/math&amp;gt;;&lt;br /&gt;
* матрица &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; размером &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;-на-&amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; &lt;br /&gt;
* &amp;lt;math&amp;gt; v_1, v_2, \ldots, v_m &amp;lt;/math&amp;gt; - ортонормированный базис пространства Крылова &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм процесса:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Выполнять для &amp;lt;math&amp;gt; \quad j=1,\ldots,m &amp;lt;/math&amp;gt;:&lt;br /&gt;
# &amp;lt;math&amp;gt; h_{ij} = (Av_j, v_i), \quad i=1,\ldots,j &amp;lt;/math&amp;gt;;&lt;br /&gt;
# &amp;lt;math&amp;gt; \hat{v}_{j+1} = Av_j - \sum_{i=1}^j h_{ij}v_{i} &amp;lt;/math&amp;gt;;&lt;br /&gt;
# &amp;lt;math&amp;gt; h_{j+1j} = \|\hat{v}_{j+1}\|_2 &amp;lt;/math&amp;gt;;&lt;br /&gt;
# &amp;lt;math&amp;gt; v_{j+1} = \frac{\hat{v}_{j+1}}{h_{j+1j}} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;При введении матричных обозначений можно записать:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Поправка решения:&lt;br /&gt;
: &amp;lt;math&amp;gt; z_m = V_my_m &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; y_m \in \mathbb{R}^m &amp;lt;/math&amp;gt; - вектор коэффициентов, &amp;lt;math&amp;gt; V_m = [v_1|v_2|...|v_m] &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Матричное представление процесса Арнольди:&lt;br /&gt;
: &amp;lt;math&amp;gt; AV_m = V_{m+1}H_{m+1m} = V_mH_m + h_{m+1m}v_{m+1} e_m^T &amp;lt;/math&amp;gt;, &lt;br /&gt;
где &lt;br /&gt;
: &amp;lt;math&amp;gt;H_{m+1m} = \begin{bmatrix}h_{11} &amp;amp; h_{12} &amp;amp; h_{13} &amp;amp;... &amp;amp; h_{1m-1} &amp;amp; h_{1m} \\ h_{21} &amp;amp; h_{22} &amp;amp; h_{23} &amp;amp; ... &amp;amp; h_{2m-1} &amp;amp; h_{2m} \\ 0 &amp;amp; h_{32} &amp;amp; h_{33} &amp;amp;...&amp;amp; h_{3m-1} &amp;amp; h_{3m} \\ ... &amp;amp; ... &amp;amp; ... &amp;amp; ... &amp;amp; ... &amp;amp; ... \\ 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; ... &amp;amp; h_{m m-1} &amp;amp; h_{mm} \\0 &amp;amp; 0 &amp;amp; 0 &amp;amp; ... &amp;amp; 0 &amp;amp; h_{m+1 m}\end{bmatrix}&amp;lt;/math&amp;gt;&lt;br /&gt;
- верхняя матрица Хессенберга размерности &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Минимизация функционала невязки ===&lt;br /&gt;
&lt;br /&gt;
Невязка исходной системы имеет вид:&lt;br /&gt;
: &amp;lt;math&amp;gt; r_m = b - A(x_0 + z_m) = r_0 - AV_my_m = \beta v_1 - V_{m+1}H_{m+1m}y_m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \beta = \|r_0\|_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
C учетом того, что матрица &amp;lt;math&amp;gt; V_{k+1} &amp;lt;/math&amp;gt; составлена из ортонормированных векторов:&lt;br /&gt;
: &amp;lt;math&amp;gt; r_m = \beta V_{m+1}e_1 - H_{m+1m}y_m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; e_1 = (1,0,0,\ldots,0)^T &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Норма невязки &amp;lt;math&amp;gt; r_m &amp;lt;/math&amp;gt;:&lt;br /&gt;
: &amp;lt;math&amp;gt; \|r_m\|_2 = \|\beta e_1 - H_{m+1m}y_m\|_2 &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Норма &amp;lt;math&amp;gt; \|r_m\|_2 &amp;lt;/math&amp;gt; достигает минимума при &amp;lt;math&amp;gt; \beta e_1 = H_{m+1m}y_m &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для нахождения решения такой системы, матрица &amp;lt;math&amp;gt; H_{m+1m} &amp;lt;/math&amp;gt; приводится к верхнему треугольному виду с помощью &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; последовательных [[Метод_Гивенса_(вращений)_QR-разложения_квадратной_матрицы_(вещественный_вариант)|вращений Гивенса]].&lt;br /&gt;
&lt;br /&gt;
=== Общая схема метода ===&lt;br /&gt;
&lt;br /&gt;
В общем виде m-aя итерация алгоритма GMRES может быть записан следующим образом:&lt;br /&gt;
&lt;br /&gt;
# найти ортонормированный базис &amp;lt;math&amp;gt; V_m &amp;lt;/math&amp;gt; подпространства &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt; с помощью ортогонализации Арнольди;&lt;br /&gt;
# найти &amp;lt;math&amp;gt; y_m &amp;lt;/math&amp;gt;, минимизирующий &amp;lt;math&amp;gt; \|r_m\|_2 &amp;lt;/math&amp;gt;;&lt;br /&gt;
# вычислить &amp;lt;math&amp;gt; x_m = x_0 + V_my_m &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; - начальное приближение;&lt;br /&gt;
# вычислить &amp;lt;math&amp;gt; r_m &amp;lt;/math&amp;gt; и остановиться,если требуемая точность была достигнута, иначе повторить.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода GMRES состоит из двух частей:&lt;br /&gt;
* Вычисление ортонормированного базиса &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt;;&lt;br /&gt;
* Формирование приближенного решения &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для вычисления ортонормированного базиса &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt; метод использует процесс Арнольди:&lt;br /&gt;
: &amp;lt;math&amp;gt; h_{j+1j}v_{j+1} = Av_j - \sum_{i=1}^j h_{ij}v_{j} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; h_{ij} = (Av_j, v_i)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; \quad j=1,\ldots,m &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для нахождения приближённого решения &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt; метод использует формулу:&lt;br /&gt;
: &amp;lt;math&amp;gt; x_m = x_0 + V_my_m &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;
На практике используется перезапускаемая версия метода - GMRES(m):&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;1 Подготовка перед итерационным процессом:&#039;&#039;&#039;&lt;br /&gt;
:1.1 Выбрать начальное приближение &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt;;&lt;br /&gt;
:1.2 Посчитать невязку &amp;lt;math&amp;gt; r_0 = b - Ax_0 &amp;lt;/math&amp;gt;;&lt;br /&gt;
:1.3 Вычислить &amp;lt;math&amp;gt; v_1 = \frac{r_0}{\|r_0\|_2} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2 Построение ортонормированного базиса &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
: Для всех &amp;lt;math&amp;gt; j &amp;lt;/math&amp;gt; от 1 до m по нарастанию выполнять:&lt;br /&gt;
:2.1 &amp;lt;math&amp;gt; h_{ij} := (Av_j, v_i), \quad i=1,\ldots,j &amp;lt;/math&amp;gt;;&lt;br /&gt;
:2.2 &amp;lt;math&amp;gt; \hat{v}_{j+1} := Av_j - \sum_{i=1}^j h_{ij}v_{i} &amp;lt;/math&amp;gt;;&lt;br /&gt;
:2.3 &amp;lt;math&amp;gt; h_{j+1j} = \|\hat{v}_{j+1}\|_2 &amp;lt;/math&amp;gt;;&lt;br /&gt;
:2.4 &amp;lt;math&amp;gt; v_{j+1} = \frac{\hat{v}_{j+1}}{h_{j+1j}} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3 Вычисление &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:3.1 &amp;lt;math&amp;gt; x_m = x_0 + V_my_m &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;y_m&amp;lt;/math&amp;gt; минимизирует &amp;lt;math&amp;gt;\|r_0 - AV_my_m\|_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
:3.2 Вычислить &amp;lt;math&amp;gt; r_m &amp;lt;/math&amp;gt;;&lt;br /&gt;
:3.3 Если требуемая точность достигнута, остановиться.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4 Перезапуск:&#039;&#039;&#039;&lt;br /&gt;
:4.1 &amp;lt;math&amp;gt;x_0 = x_m&amp;lt;/math&amp;gt;;&lt;br /&gt;
:4.2 &amp;lt;math&amp;gt;v_1 = \frac{r_m}{\|r_m\|_2}&amp;lt;/math&amp;gt;;&lt;br /&gt;
:4.3 Перейти к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Если пренебречь сложностью вычисления &amp;lt;math&amp;gt; y_m &amp;lt;/math&amp;gt;, то общую сложность алгоритма GMRES можно разделить на две части:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1. Сложность вычисления ортонормированного базиса пространства &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:a) Для вычисления &amp;lt;math&amp;gt; j &amp;lt;/math&amp;gt;-го вектора базиса &amp;lt;math&amp;gt; K_m, j &amp;lt; m &amp;lt;/math&amp;gt; требуется:&lt;br /&gt;
:: &amp;lt;math&amp;gt; NZ + (2j + 1)n &amp;lt;/math&amp;gt; мультипликативных операций, где &amp;lt;math&amp;gt; NZ &amp;lt;/math&amp;gt; - количество ненулевых элементов матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt;. &lt;br /&gt;
:b) Вычисление последнего вектора базиса требует:&lt;br /&gt;
:: &amp;lt;math&amp;gt; n(m + 1) &amp;lt;/math&amp;gt; мультипликативных операций. &lt;br /&gt;
:c) Общая мультипликативная сложность вычисления ортонормированного базиса &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt;: &lt;br /&gt;
:: &amp;lt;math&amp;gt; O(nm^2) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2. Сложность вычисления приближённого решения &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt;:&#039;&#039;&#039; &lt;br /&gt;
:a) Вычисление этой формулы требует &amp;lt;math&amp;gt; nm &amp;lt;/math&amp;gt; мультипликативных операций.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[File: Drawing.png|thumb|center|350px|&#039;&#039;&#039;Рис. 1&#039;&#039;&#039; &lt;br /&gt;
&#039;&#039;&#039;input&#039;&#039;&#039; - входные данные алгоритма (квадратная матрица, вектор правой части, начальное приближение, точность решения);&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;math&amp;gt; A_i &amp;lt;/math&amp;gt;&#039;&#039;&#039; - шаги алгоритма Арнольди, &amp;lt;math&amp;gt; x_i &amp;lt;/math&amp;gt; - нахождение невязки на &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt;-ой итерации; &lt;br /&gt;
&#039;&#039;&#039;if&#039;&#039;&#039; - вычисление &amp;lt;math&amp;gt; r_m &amp;lt;/math&amp;gt; и в случае достижения нужной точности - остановка.]]&lt;br /&gt;
Шаги алгоритма Арнольди выполняются строго последовательно, но вычисление &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt;-ой невязки может происходить параллельно&lt;br /&gt;
с &amp;lt;math&amp;gt; (i + 1) &amp;lt;/math&amp;gt;-ым шагом алгоритма Арнольди.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
В ходе анализа перезапускаемого метода обобщенных минимальных невязок был выявлен ряд подзадач, выполняющихся неоднократно: умножение матрицы на вектор, вычисление скалярного произведения векторов, нахождение нормы вектора, нормирование вектора, нахождение взвешенной суммы векторов. Наиболее трудоемкой среди перечисленных операций является умножение матрицы на вектор.&lt;br /&gt;
&lt;br /&gt;
Выполнение перечисленных операций занимает большую часть времени работы алгоритма GMRES. Поэтому при увеличении эффективности использования вычислительных ресурсов и ресурсов памяти вычислительной машины при выполнении этих операций повышается эффективность метода в целом. Достигается это применением при выполнении перечисленных операций аппарата параллельных вычислений.&lt;br /&gt;
&lt;br /&gt;
При выполнении параллельного алгоритма решения систем линейных алгебраических уравнений необходимо распределить входные данные наиболее рациональным способом. Матрица коэффициентов разбивается на непрерывные горизонтальные полосы. Распределение вектора правой части и начального приближения выполнено по принципу дублирования, т.е. все элементы векторов скопированы на все процессоры. Для рассматриваемой задачи решения СЛАУ такой подход распределения допустим, т.к. векторы содержат столько же элементов, сколько и одна строка или один столбец матрицы коэффициентов.&lt;br /&gt;
&lt;br /&gt;
Подзадачи можно разделить на 2 группы: операции между матрицей и вектором (например, умножение матрицы на вектор) и операции между двумя векторами (например, скалярное умножение). Подзадачи умножения константы на вектор и определение нормы вектора можно относить ко второй группе, так как их трудоемкость одного порядка.&lt;br /&gt;
&lt;br /&gt;
Результатом выполнения рассматриваемых операций является, вектор, части которого расположены на участвовавших в вычислениях процессорах. Для объединения результатов расчета и получения полного вектора на каждом процессоре вычислительной системы необходимо выполнить операцию сбора данных.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; – квадратная матрица размера &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;-на-&amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt; b &amp;lt;/math&amp;gt; – вектор правой части размера &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;; &lt;br /&gt;
* &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; – начальное приближение размера &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt; – погрешность решения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Для перезапускаемой версии алгоритма дополнительно:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; – число итераций.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt; n^2 + 2n + 1 &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: &lt;br /&gt;
* &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt; - вектор приближённого решения размера &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Обобщенный метод минимальных невязок предназначен для решения несимметричных систем линейных уравнений. GMRES использует перезазапуски для контроля требований к хранению данных.&lt;br /&gt;
&lt;br /&gt;
Если используется неперезапускаемый метод, GMRES будет сходиться за не более &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; шагов. Но это не имеет практического применения, когда &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; велико. Кроме того, требования к памяти и вычислениям при отсутствии перезапусков являются очень высокими. Важнейшим элементом для успешного применения &amp;lt;math&amp;gt; GMRES(m)&amp;lt;/math&amp;gt; являются перезапуски; то есть выбор &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Существуют примеры, для которых метод застаивается и сходимость есть только на &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;-м шаге. Для таких систем, любой выбор &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; меньше, чем &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; - не сходится.&lt;br /&gt;
&lt;br /&gt;
Основным недостатком GMRES является то, что объемы работ и ресурсы памяти, требуемые для итерации, линейно возрастают с увеличением числа итераций. Если не удалось получить чрезвычайно быструю сходимость - затраты будут очень высокими. Основной способ преодолеть это ограничение - это перезапуск итерации. После выбранного числа итераций &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; накопленные данные будут очищены и промежуточные результаты используются в качестве входных данных для последующих итераций. Эта процедура повторяется до тех пор, пока сходимость не будет достигнута. Трудность заключается в выборе подходящего значения &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Если &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; слишком мало, &amp;lt;math&amp;gt;GMRES(m)&amp;lt;/math&amp;gt;  может быть медленно сходиться, или не сойтись совсем. Значение &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;, большее, чем это необходимо, включает в себя чрезмерную работы и использует больше памяти. К сожалению, нет определенных правил, регулирующих выбор &amp;lt;math&amp;gt; m &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;
Масштабируемость рассматривалась в работах &amp;lt;ref&amp;gt;https://arxiv.org/pdf/1606.08740.pdf&amp;lt;/ref&amp;gt; и &amp;lt;ref&amp;gt;https://smartech.gatech.edu/bitstream/handle/1853/55635/PRATAPA-DISSERTATION-2016.pdf&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Для исследования масштабируемости была использована параллельная реализация с использованием объекта KSP(решатель СЛАУ) бибилиотеки PETSc(содержащей структуры, типы данных и подпрограммы для параллельной реализации методов на подпространствах Крылова), найденная на GitHub &amp;lt;ref&amp;gt;https://github.com/erdc-cm/petsc-dev/tree/master/src/ksp/ksp/impls/gmres&amp;lt;/ref&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Вычисления проводились на вычислительном кластере, состоящем из 16 узлов, со следующей конфигурацией:&lt;br /&gt;
Altus 1804i Server - 4P Interlagos Node, Quad AMD Opteron 6276, 16C,&lt;br /&gt;
2.3 GHz, 128GB, DDR3-1333 ECC, 80GB SSD, MLC, 2.5&amp;quot; HCA, Mellanox ConnectX 2, 1-port QSFP, QDR, memfree, CentOS, Version 5.&lt;br /&gt;
&lt;br /&gt;
На рис. 2 представлен график сильной масштабируемости.&lt;br /&gt;
&lt;br /&gt;
[[File:scaling.JPG|thumb|center|500px|&#039;&#039;&#039;Рис. 2&#039;&#039;&#039; Зависимость производительности от числа процессоров (запуск производился на 1, 8, 27, 64, 216, 512, 1000 процессорах)]]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Реализации алгоритма GMRES присутствуют во многих программных пакетах: &lt;br /&gt;
* [http://www.netlib.org/linpack/ LINPACK]&lt;br /&gt;
* [http://math.nist.gov/tnt/download.html/ JAMA/C++] &lt;br /&gt;
* [http://math-atlas.sourceforge.net/ ATLAS] &lt;br /&gt;
* [http://software.intel.com/mkl‎/ Intel MLK]&lt;br /&gt;
* [http://math.nist.gov/iml++/ IML++]&lt;br /&gt;
* [http://netlib.org/lapack/ LAPACK]&lt;br /&gt;
* [http://osl.iu.edu/research/mtl/ MTL]&lt;br /&gt;
* [http://www-users.cs.umn.edu/~saad/software/SPARSKIT/ SPARSKIT]&lt;br /&gt;
* [http://researcher.watson.ibm.com/researcher/view_group.php?id=1426 WSMP]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Dan</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:Alexander34396&amp;diff=19661</id>
		<title>Обсуждение участника:Alexander34396</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:Alexander34396&amp;diff=19661"/>
		<updated>2016-11-30T16:09:49Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Добрый день. Начал проверять статью и оставил следующие заметки&lt;br /&gt;
&lt;br /&gt;
Здравствуйте. Немного исправил статью, исходя из ваших замечаний.&lt;br /&gt;
&lt;br /&gt;
= 1.2 = &lt;br /&gt;
На мой взгляд, нужны определения&lt;br /&gt;
span?&lt;br /&gt;
l2-норма?&lt;br /&gt;
&lt;br /&gt;
: [[Участник:Alexander34396|Alexander34396]] Дано пояснение обозначения span.Вместо l2-норма теперь используется Евклидова норма.&lt;br /&gt;
&lt;br /&gt;
= 1.2.1 = &lt;br /&gt;
Вот я читаю этот раздел как человек со стороны и вижу много формул. Почему они именно такие? В чем суть этого алгоритма?&lt;br /&gt;
&lt;br /&gt;
: [[Участник:Alexander34396|Alexander34396]] Перед алгоритмом добавлено описание идеи алгоритма и пояснения к формулам.&lt;br /&gt;
&lt;br /&gt;
= 1.2.2 = &lt;br /&gt;
Новые определения&lt;br /&gt;
&lt;br /&gt;
: [[Участник:Alexander34396|Alexander34396]] Добавлены некоторые пояснения.Добавлена ссылка на статью - вращения Гивенса.&lt;br /&gt;
&lt;br /&gt;
Затем я остановился, и у меня главные вопрос. Возможно ли сделать статью такой, чтобы для ее прочтения не требовалось обращаться к куче дополнительных источников? Вот я человек со стороны, хотя и заканчивал мехмат. Я могу разобраться со всем написанным здесь, но для этого мне придется гуглить кучу материалов. Но, насколько я понимаю, цель таких статей - быть более полными.&lt;br /&gt;
&lt;br /&gt;
: [[Участник:Alexander34396|Alexander34396]]  На мой взгляд, формат статей algo-wiki не подразумевает подробных объяснений и выводов формул, поэтому я добавил только некоторые пояснения, которые делают повествование более последовательным и несколько более понятным. При этом для полного понимания описанного метода для человека со стороны всё равно придётся обращаться к сторонним источникам.&lt;br /&gt;
&lt;br /&gt;
Можете или добавить объяснений или возразить мне. В любом случае, пока с прочтением остановился, жду ответа или исправление (а лучше и того, и другого)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= 2.4 = &lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 19:09, 30 ноября 2016 (MSK) &#039;&#039;&#039;принято&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:Obirvalger/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D0%B2%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%BE%D1%80%D0%B4%D0%B8%D0%BD%D0%B0%D1%82%D0%BD%D0%BE%D0%B9_%D0%B1%D0%B8%D1%81%D0%B5%D0%BA%D1%86%D0%B8%D0%B8&amp;diff=19445</id>
		<title>Участник:Obirvalger/Метод рекурсивной координатной бисекции</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%D0%BA:Obirvalger/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D0%B2%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%BE%D1%80%D0%B4%D0%B8%D0%BD%D0%B0%D1%82%D0%BD%D0%BE%D0%B9_%D0%B1%D0%B8%D1%81%D0%B5%D0%BA%D1%86%D0%B8%D0%B8&amp;diff=19445"/>
		<updated>2016-11-29T08:39:29Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Dan}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Рекурсивная координатная бисекция&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n \log_2{n} \log_2{k})&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;\log_2{k}&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;N|V| + |G|&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы: [[Участник:Obirvalger|Гордеев Михаил]] (разделы 1.4, 1.6, 1.8, 1.10, 2.1, 2.4), [[Участник:KolmakovEA|Колмаков Евгений]] (разделы 1.1, 1.2, 1.3, 1.5, 1.7, 1.9, 2.1, 2.4, 2.7).&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;&#039;&#039; является одним из методов, применяемых для декомпозиции графов &amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2012. – 328 с., илл. – (Серия «Суперкомпьютерное образование»), ISBN 978-5-211-06382-2 URL: http://lira.imamod.ru/ITTPMOPS/&amp;lt;/ref&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;
Метод рекурсивной координатной бисекции является частным случаем более общего &#039;&#039;&#039;метода рекурсивной бисекции&#039;&#039;&#039;. В этом методе сетка последовательно за &amp;lt;math&amp;gt;k-1&amp;lt;/math&amp;gt; шаг делится на &amp;lt;math&amp;gt;k&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;
* отсортированное множество разбивается на две части, то есть указывается индекс &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; такой, что в первую часть попадают вершины с номерами меньшими либо равными &amp;lt;math&amp;gt;i&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;
Исходные данные: граф &amp;lt;math&amp;gt;G = (V, E) &amp;lt;/math&amp;gt;, вложенный в &amp;lt;math&amp;gt;\mathbb{R}^N&amp;lt;/math&amp;gt; (то есть каждая вершина этого графа - это точка в &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; мерном пространстве), и число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; доменов, на которое нужно разбить граф.&lt;br /&gt;
Под &#039;&#039;декомпозицией&#039;&#039; графа на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; доменов понимается разбиение множества вершин &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; подмножеств &amp;lt;math&amp;gt;V_1, \dots, V_k&amp;lt;/math&amp;gt; таких, что &lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;V = \bigcup_{i = 1}^k V_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;V_i \cap V_j = \varnothing&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;i \neq j&amp;lt;/math&amp;gt;.&amp;lt;/center&amp;gt; &lt;br /&gt;
&lt;br /&gt;
С каждым доменом можно связать порождённый им подграф &amp;lt;math&amp;gt;G(V_i) = (V_i, E_i)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;E_i \subseteq E&amp;lt;/math&amp;gt; - множество рёбер, оба конца которых принадлежат домену.&lt;br /&gt;
&lt;br /&gt;
Задача заключается в нахождении декомпозиции &amp;lt;math&amp;gt;V_1, \dots, V_k&amp;lt;/math&amp;gt;, доставляющей минимум некоторого функционала (см. [[#Критерии декомпозиции| соответствующий пункт]]), например, числа разрезанных рёбер &amp;lt;math&amp;gt;E_{\mbox{cut}} = |\{(u, v) \in E \mid u \in V_i, v \in V_j, i \neq j\}| = |E| - \sum_{i = 1}^k |E_i|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дадим формальное описание алгоритма. Как уже упоминалось, метод основан на алгоритме рекурсивной бисекции, поэтому представляет собой рекурсивную процедуру, на вход которой поступает граф  &amp;lt;math&amp;gt;G = (V, E) &amp;lt;/math&amp;gt; и число доменов &amp;lt;math&amp;gt;k&amp;lt;/math&amp;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;math&amp;gt;m^* \in \{1, \dots, N\}&amp;lt;/math&amp;gt;;&lt;br /&gt;
** в случае максимизации протяженности: для каждой оси &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; вычисляется величина &amp;lt;math&amp;gt;l_m = \max_{v \in V} v_m - \min_{v \in V} v_m&amp;lt;/math&amp;gt;, и выбирается ось &amp;lt;math&amp;gt;m^* = \arg\max_{m \in \{1, \dots, N\}} l_m&amp;lt;/math&amp;gt;;&lt;br /&gt;
** в случае минимизации числа разрезанных ребер: вершины упорядочиваются вдоль каждой из осей, для каждой оси вычисляется величина &amp;lt;math&amp;gt;E^m_{\mbox{cut}}&amp;lt;/math&amp;gt;, равная числу разрезанных ребер при разбиении вдоль данной оси, и выбирается ось &amp;lt;math&amp;gt;m^* = \arg\max_{m \in \{1, \dots, N\}} E^m_{\mbox{cut}}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* множество вершин сортируется по возрастанию координаты с номером &amp;lt;math&amp;gt;m^*&amp;lt;/math&amp;gt;;&lt;br /&gt;
* отсортированный массив вершин делится на две (непрерывные) части в соответствии с желаемым числом вершин в каждой из частей; &lt;br /&gt;
**как правило, выбирается индекс  &amp;lt;math&amp;gt;i = \lfloor\frac{k+1}{2k}\rfloor \cdot |V|&amp;lt;/math&amp;gt;, соответствующий примерно равному разделению текущего графа на части;&lt;br /&gt;
* первая часть состоит из вершин &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; с индексами &amp;lt;math&amp;gt;j \leqslant i&amp;lt;/math&amp;gt;, вторая - с индексами &amp;lt;math&amp;gt;j &amp;gt; i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро алгоритма составляют сортировки массива вершин сетки по выбранной координате при каждом из &amp;lt;math&amp;gt;k - 1&amp;lt;/math&amp;gt; вызовов процедуры бисекции. &lt;br /&gt;
&lt;br /&gt;
Также, в зависимости от критерия выбора координатной оси, требуются дополнительные вычисления:&lt;br /&gt;
*В случае максимизации протяженности при каждом вызове требуется вычисление величины &amp;lt;math&amp;gt;l_m&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В случае минимизации числа разрезанных ребер при каждом вызове требуется сортировка по каждой из координат (таким образом, при каждом разбиении осуществляется &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; сортировок).&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Как записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть метода составляют множественные (всего &amp;lt;math&amp;gt;k-1&amp;lt;/math&amp;gt;) сортировки (функция argsort в коде в [[#Схема реализации последовательного алгоритма |следующем разделе]]).&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Опишем последовательную реализацию метода рекурсивной координатной бисекции, где выбор оси производится исходя из условия максимизации протяженности вдоль этой оси. Ниже представлен код данного алгоритма на языке Python 3.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Переменная для хранения результата работы алгоритма&lt;br /&gt;
partition = []&lt;br /&gt;
&lt;br /&gt;
# V - numpy.ndarray размера |V| x N, k - число доменов&lt;br /&gt;
def recursive_bisection(V, k):&lt;br /&gt;
&lt;br /&gt;
    global partition&lt;br /&gt;
&lt;br /&gt;
    # Если текущая часть графа есть домен, добавляем ее к результату разбиения&lt;br /&gt;
    if (k &amp;lt;= 1):&lt;br /&gt;
        partition.append(V)&lt;br /&gt;
        return &lt;br /&gt;
&lt;br /&gt;
    # Вычисляем количество доменов в каждой из частей&lt;br /&gt;
    k1 = (k + 1) / 2&lt;br /&gt;
    k2 = k - k1&lt;br /&gt;
    &lt;br /&gt;
    # Производим разбиение  &lt;br /&gt;
    V1, V2 = bisect(V, k)&lt;br /&gt;
&lt;br /&gt;
    # Рекурсивно разбиваем каждую из частей&lt;br /&gt;
    recursive_bisect(V1, k1) &lt;br /&gt;
    recursive_bisect(V2, k2)&lt;br /&gt;
    &lt;br /&gt;
def bisect(V, k):&lt;br /&gt;
    # Вычисляем координату с наибольшей протяженностью&lt;br /&gt;
    t = V.max(axis=0) - V.min(axis=0)&lt;br /&gt;
    m = t.argmax()&lt;br /&gt;
    &lt;br /&gt;
    # Сортируем вершины по координате с номером m&lt;br /&gt;
    V_sorted = V[V[:, m].argsort()]&lt;br /&gt;
&lt;br /&gt;
    # Вычисляем индекс для разбиения в соответствии с числом доменов&lt;br /&gt;
    ind = (k + 1) * V.shape[0] // (2 * k)&lt;br /&gt;
&lt;br /&gt;
    return V_sorted[:ind, :], V_sorted[ind:, :]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведённый код предназначен для более подробного описания основных шагов в алгоритме, представляет собой лишь схему и не является максимально эффективным. Это сделано для того, чтобы код был более наглядным. В более эффективной реализации, например, вместо создания массивов в процедуре bisect можно везде оперировать только индексами.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Обозначим через &amp;lt;math&amp;gt;D_k(n)&amp;lt;/math&amp;gt; сложность алгоритма рекурсивной координатной бисекции для декомпозиции графа с &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; вершинами на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; доменов.&lt;br /&gt;
&lt;br /&gt;
Определим величину &amp;lt;math&amp;gt;D(n) = D_n(n)&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;D(n)&amp;lt;/math&amp;gt; имеет место следующее рекуррентное равенство:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{l}&lt;br /&gt;
D(n) = S(n) + 2D(\frac{n}{2}) \\&lt;br /&gt;
D(1) = S(1) = 0. \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;S(n)&amp;lt;/math&amp;gt; - это сложность алгоритма сортировки массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;S(n) = O(n\log_2{n})&amp;lt;/math&amp;gt; (например, для сортировки слиянием), тогда по теореме о рекуррентных соотношениях &amp;lt;ref&amp;gt;https://ru.wikipedia.org/wiki/Основная_теорема_о_рекуррентных_соотношениях&amp;lt;/ref&amp;gt; для произвольного положительного &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; имеет место оценка &amp;lt;math&amp;gt;D(n) \lesssim n^{1+\varepsilon}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Величину &amp;lt;math&amp;gt;D_k(n)&amp;lt;/math&amp;gt; можно явно посчитать по формуле &amp;lt;math&amp;gt;\sum\limits_{i=0}^{\lceil\log_2{k}\rceil}2^i S(\frac{n}{2^i})&amp;lt;/math&amp;gt;. Если использовать сортировку со сложностью &amp;lt;math&amp;gt;S(n) = O(n\log_2{n})&amp;lt;/math&amp;gt;, то &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;D_k(n) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;O(\sum\limits_{i=0}^{\lceil\log_2{k}\rceil}2^i \frac{n}{2^i} \log_2{\frac{n}{2^i}}) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;O(n\log_2(\prod\limits_{i=0}^{\lceil\log_2{k}\rceil}\frac{n}{2^i})) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;O(n\log_2{\frac{n^{\log_2{k}}}{2^\frac{\log_2{k}(\log_2{k}+1))}{2}}}) =&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; O(n(\log_2{n}\log_2{k} - \frac{\log^2_2{k}}{2})) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;O(n\log_2{n}\log_2{k})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Под операцией в данном пункте будем понимать макрооперацию сортировки. Передача данных происходит после разбиения множества вершин на две части.&lt;br /&gt;
Таким образом, информационный граф представляет из себя бинарное дерево с &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; листьями. На рисунке ниже приведена часть информационного графа для &amp;lt;math&amp;gt;k = 16&amp;lt;/math&amp;gt;. Зависимость от числа вершин &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; учитывается в самих узлах дерева. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Файл:Tree_sort.svg|thumb|center|800px|Рисунок 1. Граф алгоритма.]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Высота ярусно-параллельной формы - &amp;lt;math&amp;gt;\log_2{k}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ширина ярусно-параллельной формы - &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если рассматривать более мелкие операции, используемые в процессе сортировки, то глобально информационный граф будет выглядеть также, однако каждый&lt;br /&gt;
узел будет заменён на информационный граф используемого алгоритма сортировки (или &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; таких графов, если используется критерий минимизации числа разрезов).&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Данный алгоритм обладает координатным параллелизмом.&lt;br /&gt;
Для декомпозиции графа с &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; вершинами на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; доменов методом рекурсивной координатной бисекции в параллельном варианте требуется последовательно выполнить &amp;lt;math&amp;gt;\lceil\log_2{k}\rceil&amp;lt;/math&amp;gt; ярусов. На &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе будет выполнятся &amp;lt;math&amp;gt;2^i&amp;lt;/math&amp;gt; операций сортировки. &lt;br /&gt;
Рассмотрим два случая распараллеливания нашего алгоритма:&lt;br /&gt;
* Параллельное выполнение операций на каждом ярусе с использованием последовательного алгоритма сортировки со сложностью &amp;lt;math&amp;gt;O(n\log_2{n})&amp;lt;/math&amp;gt;. &lt;br /&gt;
# На первом шаге один процессор производит сортировку всех вершин, разделяет граф на два подграфа и передает однин из подрафов новому процессору.&lt;br /&gt;
# На &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом шаге каждый из уже получивший свой граф процессор производит сортировку всех вершин, разделяет граф на два подграфа и передает однин из подрафов новому процессору.&lt;br /&gt;
&lt;br /&gt;
Тогда сложность нашего алгоритма равна:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;D_k(n) = O(\sum\limits_{i=0}^{\lceil\log_2{k}\rceil}\frac{n}{2^i} \log_2{\frac{n}{2^i}}) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;n\sum\limits_{i=0}^{\lceil\log_2{k}\rceil}(\frac{\log_2{n}}{2^i} - \frac{i}{2^i}) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;O(n\log_2{n}) - O(n) = O(n\log_2{n})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Параллельное выполнение операций на каждом ярусе с использованием параллельного алгоритма сортировки со сложностью &amp;lt;math&amp;gt;O(\log_2^2{n})&amp;lt;/math&amp;gt;&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Batcher_odd–even_mergesort&amp;lt;/ref&amp;gt;.&lt;br /&gt;
На каждом шаге производится параллельная сортировка вершин и разбиение графа на два подграфа.&lt;br /&gt;
В этом случае &lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt; &lt;br /&gt;
&amp;lt;math&amp;gt;D_k(n) = \sum\limits_{i=0}^{\lceil\log_2{k}\rceil}\log^2_2\frac{n}{2^i} = O(\log^2_2{n}\log_2{k}) = O(\log^3_2{n})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Известно &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Sorting_algorithm&amp;lt;/ref&amp;gt;, что оптимальная параллельная сортировка имеет сложность &amp;lt;math&amp;gt;O(\log_2{n})&amp;lt;/math&amp;gt;. В этом случае  &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;D_k(n) = \sum\limits_{i=0}^{\lceil\log_2{k}\rceil}\log_2\frac{n}{2^i} = O(\log_2{n}\log_2{k})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; граф &amp;lt;math&amp;gt;G = (V, E) &amp;lt;/math&amp;gt;, вложенный в &amp;lt;math&amp;gt;\mathbb{R}^N&amp;lt;/math&amp;gt;, и число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; частей (доменов), на которое нужно разбить граф. Таким образом, помимо матрицы смежности (или любого другого представления графа) для каждой вершины &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; задан набор её координат &amp;lt;math&amp;gt;v = (v_1, \dots, v_N) \in \mathbb{R}^N&amp;lt;/math&amp;gt;, поэтому &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; задаётся массивом &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерных векторов или матрицей размера &amp;lt;math&amp;gt;|V| \times N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;N|V| + |G|&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|G|&amp;lt;/math&amp;gt; - объём данных, представляющих граф &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, который в общем случае зависит от выбранного представления.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; доменов графа &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, задающих его декомпозицию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - для каждого домена достаточно хранить соответствующие вершинам из этого домена индексы строк в матрице, представляющей множество вершин.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов является &#039;&#039;линейным&#039;&#039; (отношение &amp;lt;math&amp;gt;O(n\log{n})&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;O(\log{n}))&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;
Ниже приведен пример реализации последовательного алгоритма на языке C++. Следует отметить, что исходный массив вершин не изменяется, вся работа осуществляется с индексами.&lt;br /&gt;
&amp;lt;source lang = &amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;algorithm&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
#define N 5&lt;br /&gt;
#define M 5&lt;br /&gt;
#define STEP 0.01&lt;br /&gt;
&lt;br /&gt;
#define N_DIMS 2&lt;br /&gt;
#define N_DOMAINS 6&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;vector&amp;lt;double&amp;gt; &amp;gt; points_matrix(N_DIMS, vector&amp;lt;double&amp;gt;(N * M));&lt;br /&gt;
vector&amp;lt;vector&amp;lt;int&amp;gt; &amp;gt; graph_partition;&lt;br /&gt;
&lt;br /&gt;
double span(vector&amp;lt;double&amp;gt; x, vector&amp;lt;int&amp;gt; idx)&lt;br /&gt;
{ &lt;br /&gt;
    double max_value = x[idx[0]];&lt;br /&gt;
    double min_value = x[idx[0]];&lt;br /&gt;
    &lt;br /&gt;
    for (size_t i = 1; i &amp;lt; idx.size(); i++) {&lt;br /&gt;
        max_value = (x[idx[i]] &amp;gt; max_value) ? x[idx[i]] : max_value;&lt;br /&gt;
        min_value = (x[idx[i]] &amp;lt; min_value) ? x[idx[i]] : min_value; &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return max_value;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;int&amp;gt; bisect(vector&amp;lt;int&amp;gt; idx)&lt;br /&gt;
{&lt;br /&gt;
    double max_span = 0;&lt;br /&gt;
    double max_ind = 0;&lt;br /&gt;
    &lt;br /&gt;
    // finding coordinate with maximal span&lt;br /&gt;
    for (size_t i = 0; i &amp;lt; points_matrix.size(); i++) {&lt;br /&gt;
        double cur_span = span(points_matrix[i], idx);&lt;br /&gt;
        if (cur_span &amp;gt; max_span) {&lt;br /&gt;
            max_span = cur_span;&lt;br /&gt;
            max_ind = i;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // sorting vertices along this coordinate&lt;br /&gt;
    sort(idx.begin(), idx.end(), [&amp;amp;](const int&amp;amp; a, const int&amp;amp; b) {&lt;br /&gt;
                return points_matrix[max_ind][a] &amp;lt; points_matrix[max_ind][b];&lt;br /&gt;
            });&lt;br /&gt;
    &lt;br /&gt;
    return idx;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void recursive_bisection(vector&amp;lt;int&amp;gt; idx, int k)&lt;br /&gt;
{&lt;br /&gt;
    // adding current domain to partition&lt;br /&gt;
    if (k &amp;lt; 2) {&lt;br /&gt;
        graph_partition.push_back(idx);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    int k1 = (k + 1) / 2;&lt;br /&gt;
    int k2 = k - k1;&lt;br /&gt;
    &lt;br /&gt;
    // bisecting current graph&lt;br /&gt;
    vector&amp;lt;int&amp;gt; sorted_idx1 = bisect(idx);&lt;br /&gt;
    vector&amp;lt;int&amp;gt; sorted_idx2(make_move_iterator(sorted_idx1.begin() + k1 * sorted_idx1.size() / k),&lt;br /&gt;
                    make_move_iterator(sorted_idx1.end()));&lt;br /&gt;
    sorted_idx1.erase(sorted_idx1.begin() + k1 * sorted_idx1.size() / k, sorted_idx1.end());&lt;br /&gt;
    &lt;br /&gt;
    recursive_bisection(sorted_idx1, k1);&lt;br /&gt;
    recursive_bisection(sorted_idx2, k2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    // example: uniform MxN-mesh &lt;br /&gt;
    for(size_t i = 0; i &amp;lt; N; ++i)&lt;br /&gt;
        for(size_t j = 0; j &amp;lt; M; ++j) {&lt;br /&gt;
    	    points_matrix[0][M * i + j] = i * STEP;&lt;br /&gt;
	    points_matrix[1][M * i + j] = j * STEP;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
    vector&amp;lt;int&amp;gt; idx(M * N);&lt;br /&gt;
    iota(idx.begin(), idx.end(), 0);&lt;br /&gt;
&lt;br /&gt;
    recursive_bisection(idx, K);&lt;br /&gt;
    &lt;br /&gt;
    // partitioning results&lt;br /&gt;
    for(size_t i = 0; i &amp;lt; graph_partition.size(); ++i) {&lt;br /&gt;
        for(size_t j = 0; j &amp;lt; graph_partition[i].size(); ++j)&lt;br /&gt;
            cout &amp;lt;&amp;lt; graph_partition[i][j] &amp;lt;&amp;lt; &amp;quot; &amp;quot;;&lt;br /&gt;
        cout &amp;lt;&amp;lt; endl;&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;
Эксперименты проводились на компьютере с четырехъядерным процессором Intel Core i7 3610QM 2300 Mhz, который поддерживает до 8 потоков и оперативной памятью типа DDR3 1600 МГц размером 8 Gb.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число потоков от 1 до 8 с шагом 1;&lt;br /&gt;
*	размер сетки N x N, n от 500 до 2000 с шагом 500;&lt;br /&gt;
*	число доменов k 100 и от 2000 до 10000 с шагом 1000;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Файл:Perf_500.svg|thumb|center|800px|Рисунок 2. График производительности на сетке 500 x 500.]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Файл:Perf_1000.svg|thumb|center|800px|Рисунок 3. График производительности на сетке 1000 x 1000.]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Файл:Perf_1500.svg|thumb|center|800px|Рисунок 4. График производительности на сетке 1500 x 1500.]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Файл:Perf_2000.svg|thumb|center|800px|Рисунок 5. График производительности на сетке 2000 x 2000.]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Файл:Eff_500.svg|thumb|center|800px|Рисунок 6. График эффективности на сетке 500 x 500.]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Файл:Eff_1000.svg|thumb|center|800px|Рисунок 7. График эффективности на сетке 1000 x 1000.]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Файл:Eff_1500.svg|thumb|center|800px|Рисунок 8. График эффективности на сетке 1500 x 1500.]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Файл:Eff_2000.svg|thumb|center|800px|Рисунок 9. График эффективности на сетке 2000 x 2000.]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://pastebin.com/hCqz7vBU Параллельная реализация алгоритма на языке C++]&lt;br /&gt;
&lt;br /&gt;
В статье &amp;lt;ref&amp;gt;http://glaros.dtc.umn.edu/gkhome/node/112&amp;lt;/ref&amp;gt; приводятся результаты работы алгоритма декомпозиции графов из пакета ParMETIS. В таблице ниже приведено время работы алгоритма в зависимости от числа вершин в графе и используемого числа процессоров. Рассмотравились следующие графы:&lt;br /&gt;
граф mrng2 с 1 миллионом вершин, mrng3 с 4 миллионами и граф mrgn4 с 7.5 миллионами вершин.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Время выполнения разбиения графа с использованием Parmetis&lt;br /&gt;
|-&lt;br /&gt;
! Graph&lt;br /&gt;
! 8 processors&lt;br /&gt;
! 16 processors&lt;br /&gt;
! 32 processors&lt;br /&gt;
! 64 processors&lt;br /&gt;
! 128 processors&lt;br /&gt;
|-&lt;br /&gt;
| mrng2&lt;br /&gt;
| 5.4&lt;br /&gt;
| 3.1&lt;br /&gt;
| 2.1&lt;br /&gt;
| 1.5&lt;br /&gt;
| 1.7&lt;br /&gt;
|-&lt;br /&gt;
| mrng3&lt;br /&gt;
| 15.8&lt;br /&gt;
| 8.8&lt;br /&gt;
| 4.8&lt;br /&gt;
| 3.0&lt;br /&gt;
| 2.7&lt;br /&gt;
|-&lt;br /&gt;
| mrng4&lt;br /&gt;
| 38.6&lt;br /&gt;
| 16.2&lt;br /&gt;
| 8.8&lt;br /&gt;
| 5.0&lt;br /&gt;
| 3.6&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Описанный алгоритм реализован во многих пакетах декомпозиции графов, включающих в себя и другие версии алгоритма бисекции.&lt;br /&gt;
&lt;br /&gt;
Последовательная версия алгоритма реализована в пакетах Chaco, JOSTLE, [http://glaros.dtc.umn.edu/gkhome/metis/metis/overview METIS], [https://www.labri.fr/perso/pelegrin/scotch/ SCOTCH]. &lt;br /&gt;
&lt;br /&gt;
Параллельная версия реализована в пакетах JOSTLE, [http://glaros.dtc.umn.edu/gkhome/metis/parmetis/overview ParMETIS], [https://www.labri.fr/perso/pelegrin/scotch/ PT-SCOTCH].&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что пакеты METIS и ParMETIS распространяются свободно.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&lt;br /&gt;
[[en:Recursive coordinate bisection method]]&lt;/div&gt;</summary>
		<author><name>Dan</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:Obirvalger&amp;diff=19444</id>
		<title>Обсуждение участника:Obirvalger</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:Obirvalger&amp;diff=19444"/>
		<updated>2016-11-29T08:39:19Z</updated>

		<summary type="html">&lt;p&gt;Dan: /* Пункт 2.4 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Пункт 2.4 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:Lvs/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES&amp;diff=19013</id>
		<title>Участник:Lvs/Итерационный метод решения системы линейных алгебраических уравнений GMRES</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%D0%BA:Lvs/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES&amp;diff=19013"/>
		<updated>2016-11-23T11:03:44Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Dan}}&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Итерационный метод решения системы линейных алгебраических уравнений GMRES (или обобщенный метод минимальных невязок) используется для решения систем линейных алгебраических уравнений с заданной точностью приближения. Метод основан на процессе Арнольди, посредст­вом которого матрица СЛАУ приводится к (верхней) хессенберговой форме.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Дана система линейных алгебраических уравнений &amp;lt;math&amp;gt;Ax = b&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; - квадратная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляется последовательность приближённых решений уравнения &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt;, которая сходится к точному решению уравнения &amp;lt;math&amp;gt;x^*&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Подпространство Крылова размерности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;, порожденное вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; и матрицей &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; – линейное пространство&lt;br /&gt;
&amp;lt;math&amp;gt;K_m(A, v)&amp;lt;/math&amp;gt;, являющееся линейной оболочкой векторов &amp;lt;math&amp;gt;b, Ab, A^2b, ..., A^{m-1}b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Приближённое решение считается по формуле &amp;lt;math&amp;gt; x_m = Q_my_m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_m&amp;lt;/math&amp;gt; - матрица размера &amp;lt;math&amp;gt;n \times m&amp;lt;/math&amp;gt;, составленная из векторов ортонормированного базиса пространства &amp;lt;math&amp;gt;K_m(A, v)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;y_m \in \mathbb{R}^m&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итоговым считается решение, минимизирующее норму невязки (&amp;lt;math&amp;gt;||r||_2 = ||b - Ax_m||_2&amp;lt;/math&amp;gt;) с заданной точностью.&lt;br /&gt;
&lt;br /&gt;
Для вычисления векторов ортонормированного базиса используется алгоритм Арнольди:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
q[1] = b/||b||&lt;br /&gt;
for j = 1, ..., n-1 do&lt;br /&gt;
    z = Aq[j]; //очередной вектор&lt;br /&gt;
    for i = 1,..., j do&lt;br /&gt;
        h[i][j] = (z, q[i]);&lt;br /&gt;
        z = z − h[i][j]q[i];&lt;br /&gt;
    end i&lt;br /&gt;
    h[j+1][j] = ||z||;&lt;br /&gt;
    if (h[j+1][j] == 0) break;&lt;br /&gt;
    q[j+1] = z/h[j+1][j];&lt;br /&gt;
end j&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Сложность алгоритма &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На каждом шаге алгоритма получаются векторы &amp;lt;math&amp;gt;q_1, q_2, ..., q_m&amp;lt;/math&amp;gt;, являющиеся ортонормированным базисом Крыловского пространства &amp;lt;math&amp;gt;K_m(A, b)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Значения &amp;lt;math&amp;gt;h_{i,j}&amp;lt;/math&amp;gt; образуют верхнюю матрицу Хессенберга (обозначим как &amp;lt;math&amp;gt;H_m&amp;lt;/math&amp;gt;, размерность &amp;lt;math&amp;gt;m+1 \times m&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_k = \begin{bmatrix}h_{11} &amp;amp; h_{12} &amp;amp; h_{13} &amp;amp;... &amp;amp; h_{1m-1} &amp;amp; h_{1m} \\ h_{21} &amp;amp; h_{22} &amp;amp; h_{23} &amp;amp; ... &amp;amp; h_{2m-1} &amp;amp; h_{2m} \\ 0 &amp;amp; h_{32} &amp;amp; h_{33} &amp;amp;...&amp;amp; h_{3m-1} &amp;amp; h_{3m} \\ ... &amp;amp; ... &amp;amp; ... &amp;amp; ... &amp;amp; ... &amp;amp; ... \\ 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; ... &amp;amp; h_{m m-1} &amp;amp; h_{mm} \\0 &amp;amp; 0 &amp;amp; 0 &amp;amp; ... &amp;amp; 0 &amp;amp; h_{m+1 m}\end{bmatrix}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вектор невязки задан уравнением &amp;lt;math&amp;gt;r_m = H_my_m - ||b - Ax_0||e_1&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt; - вектор начального приближения. Минимизация второй нормы вектора невязки представляет из себя решение линейной задачи минимальных квадратов размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Приближённое решение вычисляется по формуле &amp;lt;math&amp;gt; x_m = Q_my_m&amp;lt;/math&amp;gt; после нахождения соответствующего значения минимизирующего вторую невязку вектора. Сложность вычислений &amp;lt;math&amp;gt;O(nm)&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;
&amp;lt;source&amp;gt;&lt;br /&gt;
    Вычислить ортонормированный базис размера m&lt;br /&gt;
    Вычислить минимальное приближение&lt;br /&gt;
    if (приближение &amp;lt; заданная точность)&lt;br /&gt;
        Вычислить результат&lt;br /&gt;
        return;&lt;br /&gt;
    else&lt;br /&gt;
        Повторить для m = m+1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность вычислений собственных векторов на каждом шаге - &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, но может уменьшиться до &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; при более разреженной матрице.&lt;br /&gt;
&lt;br /&gt;
Сложность решения задачи минимальных квадратов &amp;lt;math&amp;gt;O(m^2)&amp;lt;/math&amp;gt;, но при последовательном выполнении алгоритма можно понизить сложность до &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;gt; путём использования подсчитанных на прошлых итерациях значений.&lt;br /&gt;
&lt;br /&gt;
Сложность вычисления решения &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;, поэтому его целесообразно вычислять только в конце.&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
Основной ресурс параллелизма - умножение матрицы на вектор. Для этой операции информационный граф представлен на рисунке.&lt;br /&gt;
&lt;br /&gt;
[[file:GraphLvs2FM.jpg|thumb|center|700px|Рис.1. Информационный граф умножения матрицы на вектор]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
# Параллельное умножение матрицы на вектор выполняется в &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; ярусов умножений и сложений.&lt;br /&gt;
# Шаги алгоритма Арнольди выполняются строго последовательно, однако последующее нахождение невязки можно выполнять параллельно с запуском следующего шага алгоритма.&lt;br /&gt;
# Сложность решения задачи минимальных квадратов зависит от используемого алгоритма. В отличие от последовательного метода данные, полученные на прошлых шагах здесь использовать нельзя.&lt;br /&gt;
# Вычисление результата выполняется один раз, его можно выполнить параллельно в &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; ярусов умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; Матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;, вектор &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;, точность &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Объём: &amp;lt;math&amp;gt;n^2 + n + 1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Вектор &amp;lt;math&amp;gt;x_m&amp;lt;/math&amp;gt;. Объём: &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Теоретически на каждой итерации алгоритма сложность вычислений составляет &amp;lt;math&amp;gt;n + X&amp;lt;/math&amp;gt; операций умножения, где &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - сложность алгоритма для решения задачи минимальных квадратов. Таким образом в худшем случае сложность будет примерно равна &amp;lt;math&amp;gt;n^2 + X*n + n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Несмотря на то, что в теории итерации алгоритма можно выполнять параллельно после выполнения алгоритма Арнольди, на практике необходимая точность может быть достигнута раньше чем на n-й итерации, что потребует какого-нибудь способа прервать последующие итерации. Для избегания лишних вычисление возможно оптимально оставить эту часть последовательной.&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
Для исследования масштабируемости алгоритма была использована параллельная реализация, найденная на просторах GitHub&amp;lt;ref&amp;gt;Parallel GMRES Algorithm for Solving Giant Sparse System of Linear Equations https://github.com/arrgasm/paraGMRES/&amp;lt;/ref&amp;gt;. Программа была запущена на суперкомпьютере BlueGene на разреженной матрице размера 90448х90448. Параметрами запуска являются 100 итераций алгоритма и 10 перезапусков алгоритм (повторный запуск алгоритма с использованием решения, полученного на предыдущем запуске, в качестве начального приближения). График зависимости времени выполнения от числа процессоров представлен на рисунке 2.&lt;br /&gt;
[[file:PlotLvs1.png|thumb|center|400px|Рис 2. График зависимости времени выполнения от числа процессоров]]&lt;br /&gt;
График эффективности для полученного времени выполнения указан на рисунке 3.&lt;br /&gt;
[[file:PlotLvs2.png|thumb|center|400px|Рис 3. График зависимости эффективности реализации от числа процессоров]]&lt;br /&gt;
Параметры компиляции:&lt;br /&gt;
&amp;lt;code&amp;gt;mpixlc_r -qsmp=omp -O3&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Параметры запуска:&lt;br /&gt;
&amp;lt;code&amp;gt;gmres mat.mtx void 100 0 10&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Реализации алгоритма GMRES присутствуют во многих программных продуктах как части стандартных библиотек, например Matlab или DEFORM3D. Также существую отдельные библиотеки, например MGMRES для языка С++.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Тыртышников Е. Е. Методы численного анализа — М., Академия, 2007.&lt;br /&gt;
&lt;br /&gt;
[2] М. Дана, А. Г. Зыков, Х. Д. Икрамов Метод минимальных невязок для специального класса линейных систем с нормальными матрицами коэффициентов - Ж. вычисл. матем. и матем. физ., 2005, том 45, номер 11&lt;/div&gt;</summary>
		<author><name>Dan</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:Lvs&amp;diff=19012</id>
		<title>Обсуждение участника:Lvs</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:Lvs&amp;diff=19012"/>
		<updated>2016-11-23T11:03:32Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Пункт 1.2 =&lt;br /&gt;
Это определение пространства Крылова?&lt;br /&gt;
Не совсем понятно описание алгоритма, если не знаешь, о чем речь&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.3 =&lt;br /&gt;
Он достаточно длинный. Посмотрите описания готовых алгоритмов на алговики. Псевдокод здесь не читается, ядро должно лучше восприниматься&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.4 =&lt;br /&gt;
Если макроструктура это указанные 3 пункта, то нужно пояснить, почему именно пункт 1 является ядром. Он самый ресурсоемкий?&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.7 =&lt;br /&gt;
Почему это основной ресурс. Это основная операция в алгоритме? Требуются пояснения&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 2.4 =&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 14:03, 23 ноября 2016 (MSK) &#039;&#039;&#039;принято&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:Lvs/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES&amp;diff=18957</id>
		<title>Участник:Lvs/Итерационный метод решения системы линейных алгебраических уравнений GMRES</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%D0%BA:Lvs/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES&amp;diff=18957"/>
		<updated>2016-11-22T13:42:00Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Итерационный метод решения системы линейных алгебраических уравнений GMRES (или обобщенный метод минимальных невязок) используется для решения систем линейных алгебраических уравнений с заданной точностью приближения. Метод основан на процессе Арнольди, посредст­вом которого матрица СЛАУ приводится к (верхней) хессенберговой форме.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Дана система линейных алгебраических уравнений &amp;lt;math&amp;gt;Ax = b&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; - квадратная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляется последовательность приближённых решений уравнения &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt;, которая сходится к точному решению уравнения &amp;lt;math&amp;gt;x^*&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Подпространство Крылова размерности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;, порожденное вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; и матрицей &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; – линейное пространство&lt;br /&gt;
&amp;lt;math&amp;gt;K_m(A, v)&amp;lt;/math&amp;gt;, являющееся линейной оболочкой векторов &amp;lt;math&amp;gt;b, Ab, A^2b, ..., A^{m-1}b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Приближённое решение считается по формуле &amp;lt;math&amp;gt; x_m = Q_my_m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_m&amp;lt;/math&amp;gt; - матрица размера &amp;lt;math&amp;gt;n \times m&amp;lt;/math&amp;gt;, составленная из векторов ортонормированного базиса пространства &amp;lt;math&amp;gt;K_m(A, v)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;y_m \in \mathbb{R}^m&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итоговым считается решение, минимизирующее норму невязки (&amp;lt;math&amp;gt;||r||_2 = ||b - Ax_m||_2&amp;lt;/math&amp;gt;) с заданной точностью.&lt;br /&gt;
&lt;br /&gt;
Для вычисления векторов ортонормированного базиса используется алгоритм Арнольди:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
q[1] = b/||b||&lt;br /&gt;
for j = 1, ..., n-1 do&lt;br /&gt;
    z = Aq[j]; //очередной вектор&lt;br /&gt;
    for i = 1,..., j do&lt;br /&gt;
        h[i][j] = (z, q[i]);&lt;br /&gt;
        z = z − h[i][j]q[i];&lt;br /&gt;
    end i&lt;br /&gt;
    h[j+1][j] = ||z||;&lt;br /&gt;
    if (h[j+1][j] == 0) break;&lt;br /&gt;
    q[j+1] = z/h[j+1][j];&lt;br /&gt;
end j&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Сложность алгоритма &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На каждом шаге алгоритма получаются векторы &amp;lt;math&amp;gt;q_1, q_2, ..., q_m&amp;lt;/math&amp;gt;, являющиеся ортонормированным базисом Крыловского пространства &amp;lt;math&amp;gt;K_m(A, b)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Значения &amp;lt;math&amp;gt;h_{i,j}&amp;lt;/math&amp;gt; образуют верхнюю матрицу Хессенберга (обозначим как &amp;lt;math&amp;gt;H_m&amp;lt;/math&amp;gt;, размерность &amp;lt;math&amp;gt;m+1 \times m&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_k = \begin{bmatrix}h_{11} &amp;amp; h_{12} &amp;amp; h_{13} &amp;amp;... &amp;amp; h_{1m-1} &amp;amp; h_{1m} \\ h_{21} &amp;amp; h_{22} &amp;amp; h_{23} &amp;amp; ... &amp;amp; h_{2m-1} &amp;amp; h_{2m} \\ 0 &amp;amp; h_{32} &amp;amp; h_{33} &amp;amp;...&amp;amp; h_{3m-1} &amp;amp; h_{3m} \\ ... &amp;amp; ... &amp;amp; ... &amp;amp; ... &amp;amp; ... &amp;amp; ... \\ 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; ... &amp;amp; h_{m m-1} &amp;amp; h_{mm} \\0 &amp;amp; 0 &amp;amp; 0 &amp;amp; ... &amp;amp; 0 &amp;amp; h_{m+1 m}\end{bmatrix}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вектор невязки задан уравнением &amp;lt;math&amp;gt;r_m = H_my_m - ||b - Ax_0||e_1&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt; - вектор начального приближения. Минимизация второй нормы вектора невязки представляет из себя решение линейной задачи минимальных квадратов размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Приближённое решение вычисляется по формуле &amp;lt;math&amp;gt; x_m = Q_my_m&amp;lt;/math&amp;gt; после нахождения соответствующего значения минимизирующего вторую невязку вектора. Сложность вычислений &amp;lt;math&amp;gt;O(nm)&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;
&amp;lt;source&amp;gt;&lt;br /&gt;
    Вычислить ортонормированный базис размера m&lt;br /&gt;
    Вычислить минимальное приближение&lt;br /&gt;
    if (приближение &amp;lt; заданная точность)&lt;br /&gt;
        Вычислить результат&lt;br /&gt;
        return;&lt;br /&gt;
    else&lt;br /&gt;
        Повторить для m = m+1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность вычислений собственных векторов на каждом шаге - &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, но может уменьшиться до &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; при более разреженной матрице.&lt;br /&gt;
&lt;br /&gt;
Сложность решения задачи минимальных квадратов &amp;lt;math&amp;gt;O(m^2)&amp;lt;/math&amp;gt;, но при последовательном выполнении алгоритма можно понизить сложность до &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;gt; путём использования подсчитанных на прошлых итерациях значений.&lt;br /&gt;
&lt;br /&gt;
Сложность вычисления решения &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;, поэтому его целесообразно вычислять только в конце.&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
Основной ресурс параллелизма - умножение матрицы на вектор. Для этой операции информационный граф представлен на рисунке.&lt;br /&gt;
&lt;br /&gt;
[[file:GraphLvs2FM.jpg|thumb|center|700px|Рис.1. Информационный граф умножения матрицы на вектор]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
# Параллельное умножение матрицы на вектор выполняется в &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; ярусов умножений и сложений.&lt;br /&gt;
# Шаги алгоритма Арнольди выполняются строго последовательно, однако последующее нахождение невязки можно выполнять параллельно с запуском следующего шага алгоритма.&lt;br /&gt;
# Сложность решения задачи минимальных квадратов зависит от используемого алгоритма. В отличие от последовательного метода данные, полученные на прошлых шагах здесь использовать нельзя.&lt;br /&gt;
# Вычисление результата выполняется один раз, его можно выполнить параллельно в &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; ярусов умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; Матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;, вектор &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;, точность &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Объём: &amp;lt;math&amp;gt;n^2 + n + 1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Вектор &amp;lt;math&amp;gt;x_m&amp;lt;/math&amp;gt;. Объём: &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Теоретически на каждой итерации алгоритма сложность вычислений составляет &amp;lt;math&amp;gt;n + X&amp;lt;/math&amp;gt; операций умножения, где &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - сложность алгоритма для решения задачи минимальных квадратов. Таким образом в худшем случае сложность будет примерно равна &amp;lt;math&amp;gt;n^2 + X*n + n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Несмотря на то, что в теории итерации алгоритма можно выполнять параллельно после выполнения алгоритма Арнольди, на практике необходимая точность может быть достигнута раньше чем на n-й итерации, что потребует какого-нибудь способа прервать последующие итерации. Для избегания лишних вычисление возможно оптимально оставить эту часть последовательной.&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
Для исследования масштабируемости алгоритма была использована параллельная реализация, найденная на просторах GitHub&amp;lt;ref&amp;gt;Parallel GMRES Algorithm for Solving Giant Sparse System of Linear Equations https://github.com/arrgasm/paraGMRES/&amp;lt;/ref&amp;gt;. Программа была запущена на суперкомпьютере BlueGene на разреженной матрице размера 90448х90448. Параметрами запуска являются 100 итераций алгоритма и 10 перезапусков алгоритм (повторный запуск алгоритма с использованием решения, полученного на предыдущем запуске, в качестве начального приближения). График зависимости времени выполнения от числа процессоров представлен на рисунке 2.&lt;br /&gt;
[[file:PlotLvs1.png|thumb|center|400px|Рис 2. График зависимости времени выполнения от числа процессоров]]&lt;br /&gt;
График эффективности для полученного времени выполнения указан на рисунке 3.&lt;br /&gt;
[[file:PlotLvs2.png|thumb|center|400px|Рис 3. График зависимости эффективности реализации от числа процессоров]]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Реализации алгоритма GMRES присутствуют во многих программных продуктах как части стандартных библиотек, например Matlab или DEFORM3D. Также существую отдельные библиотеки, например MGMRES для языка С++.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Тыртышников Е. Е. Методы численного анализа — М., Академия, 2007.&lt;br /&gt;
&lt;br /&gt;
[2] М. Дана, А. Г. Зыков, Х. Д. Икрамов Метод минимальных невязок для специального класса линейных систем с нормальными матрицами коэффициентов - Ж. вычисл. матем. и матем. физ., 2005, том 45, номер 11&lt;/div&gt;</summary>
		<author><name>Dan</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:Lvs&amp;diff=18956</id>
		<title>Обсуждение участника:Lvs</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:Lvs&amp;diff=18956"/>
		<updated>2016-11-22T13:41:47Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Пункт 1.2 =&lt;br /&gt;
Это определение пространства Крылова?&lt;br /&gt;
Не совсем понятно описание алгоритма, если не знаешь, о чем речь&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.3 =&lt;br /&gt;
Он достаточно длинный. Посмотрите описания готовых алгоритмов на алговики. Псевдокод здесь не читается, ядро должно лучше восприниматься&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.4 =&lt;br /&gt;
Если макроструктура это указанные 3 пункта, то нужно пояснить, почему именно пункт 1 является ядром. Он самый ресурсоемкий?&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.7 =&lt;br /&gt;
Почему это основной ресурс. Это основная операция в алгоритме? Требуются пояснения&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 2.4 =&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 14:16, 17 ноября 2016 (MSK) необходимо доработать:&lt;br /&gt;
Требования были такие: &lt;br /&gt;
- Реализация: полностью собственная или обращение к библиотечной функции (Intel MKL, PETSc, FFTW, ScaLAPACK). В любом случае, текст исследуемой программы должен быть представлен в отчете. &lt;br /&gt;
- Компьютерная платформа может быть любой (Ломоносов, BlueGene или что-то иное). Описание компьютерной платформы должно быть в отчете. &lt;br /&gt;
- Должен быть представлен график сильной масштабируемости (зависимости производительности от числа процессов; если при этом&lt;br /&gt;
ещё и зависимость от размера задачи - это только в плюс). График должен выглядеть пристойно и понятно, оси и единицы измерения должны быть подписаны. К графику обязательно должны быть словесные пояснения! Требовалось подобрать такие размеры задачи и числа процессоров, чтобы отразить на графике характерные точки, описывающие свойства алгоритма и программы.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;В ПРОЦЕССЕ!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 10:56, 21 ноября 2016 (MSK) приведите код, параметры компиляции&lt;br /&gt;
&lt;br /&gt;
Реализация не моя, ссылку на GitHub с кодом я указал, что ещё надо?&lt;br /&gt;
&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 16:41, 22 ноября 2016 (MSK) Укажите явно: 1) параметры компиляции и 2) строку запуска (комментарии в тексте оставьте)&lt;/div&gt;</summary>
		<author><name>Dan</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:Lexaloris&amp;diff=18685</id>
		<title>Обсуждение участника:Lexaloris</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:Lexaloris&amp;diff=18685"/>
		<updated>2016-11-21T08:00:07Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основной вопрос. Ядро это все-таки умножение матрицы или строки матрицы? Соответственно под это нужно подстраивать и остальной текст, потому что можно понять и так, и так.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 2.4 =&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 14:17, 17 ноября 2016 (MSK) необходимо доработать:&lt;br /&gt;
&lt;br /&gt;
Требования были такие: &lt;br /&gt;
- Реализация: полностью собственная или обращение к библиотечной функции (Intel MKL, PETSc, FFTW, ScaLAPACK). В любом случае, текст исследуемой программы должен быть представлен в отчете. &lt;br /&gt;
- Компьютерная платформа может быть любой (Ломоносов, BlueGene или что-то иное). Описание компьютерной платформы должно быть в отчете. &lt;br /&gt;
- Должен быть представлен график сильной масштабируемости (зависимости производительности от числа процессов; если при этом&lt;br /&gt;
ещё и зависимость от размера задачи - это только в плюс). График должен выглядеть пристойно и понятно, оси и единицы измерения должны быть подписаны. К графику обязательно должны быть словесные пояснения! Требовалось подобрать такие размеры задачи и числа процессоров, чтобы отразить на графике характерные точки, описывающие свойства алгоритма и программы.&lt;br /&gt;
&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 11:00, 21 ноября 2016 (MSK) &lt;br /&gt;
- Приведите код, параметры компиляции.&lt;br /&gt;
&lt;br /&gt;
- График построен по каким значениям? &lt;br /&gt;
&lt;br /&gt;
- Укажите все параметры, при которой исследовалась задача: размер матрицы и т.д.&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:Lexaloris/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B6%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%BD%D0%B0_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80&amp;diff=18684</id>
		<title>Участник:Lexaloris/Умножение разреженной матрицы на вектор</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%D0%BA:Lexaloris/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B6%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%BD%D0%B0_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80&amp;diff=18684"/>
		<updated>2016-11-21T07:56:59Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Умножение разреженной матрицы на вектор&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;k + m&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Авторы страницы:&#039;&#039;&#039; [[Участник:Lexaloris|A.Д. Новоселов]] и [[Участник:kochet|П.А. Кочетков]]&lt;br /&gt;
&lt;br /&gt;
Кочетков Павел ответственен за программную реализацию алгоритма, Новоселов Алексей ответственен за оформление статьи. &lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&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;. Эта&lt;br /&gt;
схема предъявляет минимальные требования к памяти и в то же время оказывается очень удобной для умножения разреженной матрицы на вектор.&lt;br /&gt;
Например, рассмотрим формат хранения разряженной матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
[[File:RRCOMatrix.png]]&lt;br /&gt;
&lt;br /&gt;
Значения нену­левых элементов матрицы и соответствующие столбцовые индексы хранятся в этой схеме по строкам в двух массивах &amp;lt;math&amp;gt;AN&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JA&amp;lt;/math&amp;gt; соответственно. Используется также массив указателей &amp;lt;math&amp;gt;IA&amp;lt;/math&amp;gt;, отмечающих позиции массивов &amp;lt;math&amp;gt;AN&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JA&amp;lt;/math&amp;gt;, с которых начинается описание очередной строки. Дополнительная компо­нента в &amp;lt;math&amp;gt;IA&amp;lt;/math&amp;gt; содержит указатель первой свободной позиции в &amp;lt;math&amp;gt;JA&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;AN&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; представляется в виде:&lt;br /&gt;
&lt;br /&gt;
   IA = [ 1 4 4 6 ]&lt;br /&gt;
   JA = [ 3 4 8 6 8 ]&lt;br /&gt;
   AN = [ 1 3 5 7 1 ]&lt;br /&gt;
&lt;br /&gt;
Данный способ представления называют &#039;&#039;полным&#039;&#039;, поскольку представлена вся матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;, и &#039;&#039;упорядоченным&#039;&#039;, поскольку эле­менты каждой строки хранятся в соответствии с возрастанием столбцовых индексов. Таким образом, это строчное представление, полное и упорядоченное, или сокращенно &#039;&#039;&#039;(RR (С) О)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Неупорядоченное представление ====&lt;br /&gt;
&lt;br /&gt;
Представления разреженных матриц необязательно должны быть упорядочены в том смысле, что, хотя упорядоченность строк поддерживается, внутри каждой строки элементы могут храниться в произвольном порядке. Для матрицы А нашего примера вполне можно было бы использовать и строчное представление, полное, но &#039;&#039;неупорядоченное&#039;&#039; &#039;&#039;&#039;(RR (С) U )&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Неупорядоченное представление &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
   IA = [ 1 4 4 6 ]&lt;br /&gt;
   JA = [ 8 3 4 8 6 ]&lt;br /&gt;
   AN = [ 5 1 3 1 7 ]&lt;br /&gt;
&lt;br /&gt;
Неупорядоченные представления могут быть очень удобны. Результаты большинства матричных операций получаются не­ упорядоченными, и упорядочение их стоило бы больших затрат машинного времени. В то же время, за немногими исключениями, алгоритмы для разреженных матриц не требуют, чтобы представления были упорядоченными.&lt;br /&gt;
&lt;br /&gt;
=== Умножение разреженной матрицы на вектор ===&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число строк матрицы. &lt;br /&gt;
Для каждой ее строки &amp;lt;math&amp;gt;I&amp;lt;/math&amp;gt; матрицы мы находим с помощью &amp;lt;math&amp;gt;IA&amp;lt;/math&amp;gt; значения первой &amp;lt;math&amp;gt;IAA&amp;lt;/math&amp;gt; и последней &amp;lt;math&amp;gt;IAB&amp;lt;/math&amp;gt; позиций, занимаемых элементами строки &amp;lt;math&amp;gt;I&amp;lt;/math&amp;gt; в массивах &amp;lt;math&amp;gt;JA&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;AN&amp;lt;/math&amp;gt;. Затем, чтобы вычислить скалярное произведение строки &amp;lt;math&amp;gt;I&amp;lt;/math&amp;gt; и вектора &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;, мы просто просматриваем &amp;lt;math&amp;gt;JA&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;AN&amp;lt;/math&amp;gt; на отрезке от &amp;lt;math&amp;gt;IAA&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;IAB&amp;lt;/math&amp;gt;:&lt;br /&gt;
каждое значение, хранимое в &amp;lt;math&amp;gt;JA&amp;lt;/math&amp;gt;, есть столбцовый индекс и используется для извлечения из массива &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; элемента, который должен быть умножен на соответствующее число из &amp;lt;math&amp;gt;AN&amp;lt;/math&amp;gt;. Результат каж­дого умножения прибавляется к &amp;lt;math&amp;gt;C(I)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;IA, JA, AN&amp;lt;/math&amp;gt; - заданная матрица в форме &#039;&#039;&#039;(RR (С) U)&#039;&#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; - заданный заполненный вектор;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; - число строк матрицы.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039; &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; вектор-произведение размерности &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Формулы метода:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; IAA_{i} = IA(i), \quad i \in [1, N], \\&lt;br /&gt;
&amp;amp; IAB_{i} = IA(i + 1) - 1, \quad i \in [1, N], \\&lt;br /&gt;
&amp;amp; c_{i} = \sum\limits_{j = IAA_{i}}^{IAB_{i}} AN(j)B(JA(j)), \quad i \in [1, N] \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром, т.е. той частью алгоритма, на которую приходится основное время его работы, является вычисление значения &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го элемента &amp;lt;math&amp;gt;c_{i}&amp;lt;/math&amp;gt; вектора-произведения, т.е произведения строки &amp;lt;math&amp;gt;I&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и вектора &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; по формуле:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; c_{i} = \sum\limits_{j = IAA_{i}}^{IAB_{i}} AN(j)B(JA(j)), \quad i \in [1, N] \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Основу алгоритма составляет вычисление значения &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го элемента &amp;lt;math&amp;gt;c_{i}&amp;lt;/math&amp;gt; вектора-произведения:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; c_{i} = \sum\limits_{j = IAA_{i}}^{IAB_{i}} AN(j)B(JA(j)), \quad i \in [1, N] \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&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;math&amp;gt;i&amp;lt;/math&amp;gt; от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; по нарастанию выполняются:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt; c_{i} = 0; IAA = IA(i); IAB = IA(i + 1 ) - 1 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После этого, если &amp;lt;math&amp;gt;(IAB \le IAA)&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
2. Для всех &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; от &amp;lt;math&amp;gt;IAA&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;IAB&amp;lt;/math&amp;gt; выполняется: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;c_{i} = \sum\limits_{j = IAA_{i}}^{IAB_{i}} AN(j)B(JA(j))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Псевдокод алгоритма: &lt;br /&gt;
&lt;br /&gt;
    FOR I = 1, N                          (1)&lt;br /&gt;
       U = 0.                             (2) &lt;br /&gt;
       IAA = IA(I)                        (3) &lt;br /&gt;
       IAB = IA(I + 1 ) - 1               (4)&lt;br /&gt;
       IF NOT(IAB.LT.IAA)                 (5)&lt;br /&gt;
           FOR J = IAA, IAB               (6)&lt;br /&gt;
           C(I) = U + AN(J)*B(JA(J))      (7)&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для всего алгоритма потребуется выполнить &amp;lt;math&amp;gt;O(k)&amp;lt;/math&amp;gt; операций, как в строке стр.7 псевдокода алгоритма ([[#Схема реализации последовательного алгоритма|п.1.5]]), где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - число ненулевых эле­ментов матрицы.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
На рисунке 1 изображен информационный граф алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:InfoGrafMatrixRRCUandVextor.jpg|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма.]]&lt;br /&gt;
 &lt;br /&gt;
По оси &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; для отдельной строки &amp;lt;math&amp;gt;I&amp;lt;/math&amp;gt; матрицы отложены в пределах первой &amp;lt;math&amp;gt;IAA&amp;lt;/math&amp;gt; и последней &amp;lt;math&amp;gt;IAB&amp;lt;/math&amp;gt; позиций ненулевых элементов значения &amp;lt;math&amp;gt;AN&amp;lt;/math&amp;gt; и соответствуюие им по столбцовомым индексам, хранимимым в &amp;lt;math&amp;gt;JA&amp;lt;/math&amp;gt;, значения &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; элементов. &lt;br /&gt;
Пары этих значений обозначены желтыми квадратиками &amp;lt;math&amp;gt;(in)&amp;lt;/math&amp;gt;. Значения in попарно скалярно перемножаются (зеленый кружочек) и суммируются (синий кружочек) в результат значения элемента вектора-произведения &amp;lt;math&amp;gt;c_{i}&amp;lt;/math&amp;gt;, т.е &amp;lt;math&amp;gt;out&amp;lt;/math&amp;gt;(красный квадратик) с строковым индексом, соответствующем номеру строки матрицы.&lt;br /&gt;
&lt;br /&gt;
По оси &amp;lt;math&amp;gt;Y&amp;lt;/math&amp;gt; отложена схема вычисление значения каждого элемента вектора-произведения для каждой строки матрицы.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм обладает возможностью выполняться параллельно, что позволяет значительно ускорить вычисления.&lt;br /&gt;
Вычисление значения каждого элемента вектора-произведения для каждой строки матрицы и элемента вектора &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно проводить на отдельных процессорах. &lt;br /&gt;
Максимальная эффективность вычислений достигается при наличии не менее, чем &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; процессоров, т.е отдельный процессор на вычисление значения каждого элемента вектора-произведения. На процессоре выполняется &amp;lt;math&amp;gt;k(i)&amp;lt;/math&amp;gt; последовательных операций умножения и сложения. Поэтому число ярусов для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ого процессора равно &amp;lt;math&amp;gt;k(i)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для параллельного выполнения алгоритма требуется:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов умножений и сложений,&lt;br /&gt;
* в каждом из ярусов &amp;lt;math&amp;gt;k &amp;lt;&amp;lt; m&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, алгоритм имеет линейную сложность. При классификации по высоте ЯПФ также линейную.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;IA, JA, AN&amp;lt;/math&amp;gt; - заданная матрица в форме &#039;&#039;&#039;(RR (С) U)&#039;&#039;&#039; c &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ненулевыми элементами и &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; строками, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; столбцами;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; - заданный заполненный вектор c &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; элементами;&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;k + m&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; вектор-произведение размерности &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;N&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;
На вычислительном комплексе &#039;&#039;IBM Blue Gene/P&#039;&#039; было проведено экспериментальное исследование масштабируемости программной реализации умножения разряженной матрицы на вектор. Результаты исследования представлены на рис.2:&lt;br /&gt;
&lt;br /&gt;
[[Файл:DependeceOfTheExecutionTime.jpg |thumb|center|900px|Рисунок 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;
* SparseLib++[http://math.nist.gov/sparselib++/] &lt;br /&gt;
* cuSPARSE [http://docs.nvidia.com/cuda/cusparse/]&lt;br /&gt;
* uBLAS [http://www.boost.org/doc/libs/1_62_0/libs/numeric/ublas/doc/]&lt;br /&gt;
* Intel MKL [https://software.intel.com/en-us/intel-mkl]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&lt;br /&gt;
* [1] С. Писсанецки. Технология разреженных матриц. Изд. Мир, 1988.&lt;br /&gt;
* [2] В. В. Воеводин, Вл.В. Воеводин. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002.&lt;/div&gt;</summary>
		<author><name>Dan</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:Lvs&amp;diff=18683</id>
		<title>Обсуждение участника:Lvs</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:Lvs&amp;diff=18683"/>
		<updated>2016-11-21T07:56:36Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Пункт 1.2 =&lt;br /&gt;
Это определение пространства Крылова?&lt;br /&gt;
Не совсем понятно описание алгоритма, если не знаешь, о чем речь&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.3 =&lt;br /&gt;
Он достаточно длинный. Посмотрите описания готовых алгоритмов на алговики. Псевдокод здесь не читается, ядро должно лучше восприниматься&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.4 =&lt;br /&gt;
Если макроструктура это указанные 3 пункта, то нужно пояснить, почему именно пункт 1 является ядром. Он самый ресурсоемкий?&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.7 =&lt;br /&gt;
Почему это основной ресурс. Это основная операция в алгоритме? Требуются пояснения&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 2.4 =&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 14:16, 17 ноября 2016 (MSK) необходимо доработать:&lt;br /&gt;
Требования были такие: &lt;br /&gt;
- Реализация: полностью собственная или обращение к библиотечной функции (Intel MKL, PETSc, FFTW, ScaLAPACK). В любом случае, текст исследуемой программы должен быть представлен в отчете. &lt;br /&gt;
- Компьютерная платформа может быть любой (Ломоносов, BlueGene или что-то иное). Описание компьютерной платформы должно быть в отчете. &lt;br /&gt;
- Должен быть представлен график сильной масштабируемости (зависимости производительности от числа процессов; если при этом&lt;br /&gt;
ещё и зависимость от размера задачи - это только в плюс). График должен выглядеть пристойно и понятно, оси и единицы измерения должны быть подписаны. К графику обязательно должны быть словесные пояснения! Требовалось подобрать такие размеры задачи и числа процессоров, чтобы отразить на графике характерные точки, описывающие свойства алгоритма и программы.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;В ПРОЦЕССЕ!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 10:56, 21 ноября 2016 (MSK) приведите код, параметры компиляции&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:Lvs/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES&amp;diff=18678</id>
		<title>Участник:Lvs/Итерационный метод решения системы линейных алгебраических уравнений GMRES</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%D0%BA:Lvs/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES&amp;diff=18678"/>
		<updated>2016-11-21T07:54:55Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Итерационный метод решения системы линейных алгебраических уравнений GMRES (или обобщенный метод минимальных невязок) используется для решения систем линейных алгебраических уравнений с заданной точностью приближения. Метод основан на процессе Арнольди, посредст­вом которого матрица СЛАУ приводится к (верхней) хессенберговой форме.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Дана система линейных алгебраических уравнений &amp;lt;math&amp;gt;Ax = b&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; - квадратная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляется последовательность приближённых решений уравнения &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt;, которая сходится к точному решению уравнения &amp;lt;math&amp;gt;x^*&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Подпространство Крылова размерности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;, порожденное вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; и матрицей &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; – линейное пространство&lt;br /&gt;
&amp;lt;math&amp;gt;K_m(A, v)&amp;lt;/math&amp;gt;, являющееся линейной оболочкой векторов &amp;lt;math&amp;gt;b, Ab, A^2b, ..., A^{m-1}b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Приближённое решение считается по формуле &amp;lt;math&amp;gt; x_m = Q_my_m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_m&amp;lt;/math&amp;gt; - матрица размера &amp;lt;math&amp;gt;n \times m&amp;lt;/math&amp;gt;, составленная из векторов ортонормированного базиса пространства &amp;lt;math&amp;gt;K_m(A, v)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;y_m \in \mathbb{R}^m&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итоговым считается решение, минимизирующее норму невязки (&amp;lt;math&amp;gt;||r||_2 = ||b - Ax_m||_2&amp;lt;/math&amp;gt;) с заданной точностью.&lt;br /&gt;
&lt;br /&gt;
Для вычисления векторов ортонормированного базиса используется алгоритм Арнольди:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
q[1] = b/||b||&lt;br /&gt;
for j = 1, ..., n-1 do&lt;br /&gt;
    z = Aq[j]; //очередной вектор&lt;br /&gt;
    for i = 1,..., j do&lt;br /&gt;
        h[i][j] = (z, q[i]);&lt;br /&gt;
        z = z − h[i][j]q[i];&lt;br /&gt;
    end i&lt;br /&gt;
    h[j+1][j] = ||z||;&lt;br /&gt;
    if (h[j+1][j] == 0) break;&lt;br /&gt;
    q[j+1] = z/h[j+1][j];&lt;br /&gt;
end j&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Сложность алгоритма &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На каждом шаге алгоритма получаются векторы &amp;lt;math&amp;gt;q_1, q_2, ..., q_m&amp;lt;/math&amp;gt;, являющиеся ортонормированным базисом Крыловского пространства &amp;lt;math&amp;gt;K_m(A, b)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Значения &amp;lt;math&amp;gt;h_{i,j}&amp;lt;/math&amp;gt; образуют верхнюю матрицу Хессенберга (обозначим как &amp;lt;math&amp;gt;H_m&amp;lt;/math&amp;gt;, размерность &amp;lt;math&amp;gt;m+1 \times m&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_k = \begin{bmatrix}h_{11} &amp;amp; h_{12} &amp;amp; h_{13} &amp;amp;... &amp;amp; h_{1m-1} &amp;amp; h_{1m} \\ h_{21} &amp;amp; h_{22} &amp;amp; h_{23} &amp;amp; ... &amp;amp; h_{2m-1} &amp;amp; h_{2m} \\ 0 &amp;amp; h_{32} &amp;amp; h_{33} &amp;amp;...&amp;amp; h_{3m-1} &amp;amp; h_{3m} \\ ... &amp;amp; ... &amp;amp; ... &amp;amp; ... &amp;amp; ... &amp;amp; ... \\ 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; ... &amp;amp; h_{m m-1} &amp;amp; h_{mm} \\0 &amp;amp; 0 &amp;amp; 0 &amp;amp; ... &amp;amp; 0 &amp;amp; h_{m+1 m}\end{bmatrix}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вектор невязки задан уравнением &amp;lt;math&amp;gt;r_m = H_my_m - ||b - Ax_0||e_1&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt; - вектор начального приближения. Минимизация второй нормы вектора невязки представляет из себя решение линейной задачи минимальных квадратов размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Приближённое решение вычисляется по формуле &amp;lt;math&amp;gt; x_m = Q_my_m&amp;lt;/math&amp;gt; после нахождения соответствующего значения минимизирующего вторую невязку вектора. Сложность вычислений &amp;lt;math&amp;gt;O(nm)&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;
&amp;lt;source&amp;gt;&lt;br /&gt;
    Вычислить ортонормированный базис размера m&lt;br /&gt;
    Вычислить минимальное приближение&lt;br /&gt;
    if (приближение &amp;lt; заданная точность)&lt;br /&gt;
        Вычислить результат&lt;br /&gt;
        return;&lt;br /&gt;
    else&lt;br /&gt;
        Повторить для m = m+1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность вычислений собственных векторов на каждом шаге - &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, но может уменьшиться до &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; при более разреженной матрице.&lt;br /&gt;
&lt;br /&gt;
Сложность решения задачи минимальных квадратов &amp;lt;math&amp;gt;O(m^2)&amp;lt;/math&amp;gt;, но при последовательном выполнении алгоритма можно понизить сложность до &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;gt; путём использования подсчитанных на прошлых итерациях значений.&lt;br /&gt;
&lt;br /&gt;
Сложность вычисления решения &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;, поэтому его целесообразно вычислять только в конце.&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
Основной ресурс параллелизма - умножение матрицы на вектор. Для этой операции информационный граф представлен на рисунке.&lt;br /&gt;
&lt;br /&gt;
[[file:GraphLvs2FM.jpg|thumb|center|700px|Рис.1. Информационный граф умножения матрицы на вектор]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
# Параллельное умножение матрицы на вектор выполняется в &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; ярусов умножений и сложений.&lt;br /&gt;
# Шаги алгоритма Арнольди выполняются строго последовательно, однако последующее нахождение невязки можно выполнять параллельно с запуском следующего шага алгоритма.&lt;br /&gt;
# Сложность решения задачи минимальных квадратов зависит от используемого алгоритма. В отличие от последовательного метода данные, полученные на прошлых шагах здесь использовать нельзя.&lt;br /&gt;
# Вычисление результата выполняется один раз, его можно выполнить параллельно в &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; ярусов умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; Матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;, вектор &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;, точность &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Объём: &amp;lt;math&amp;gt;n^2 + n + 1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Вектор &amp;lt;math&amp;gt;x_m&amp;lt;/math&amp;gt;. Объём: &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Теоретически на каждой итерации алгоритма сложность вычислений составляет &amp;lt;math&amp;gt;n + X&amp;lt;/math&amp;gt; операций умножения, где &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - сложность алгоритма для решения задачи минимальных квадратов. Таким образом в худшем случае сложность будет примерно равна &amp;lt;math&amp;gt;n^2 + X*n + n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Несмотря на то, что в теории итерации алгоритма можно выполнять параллельно после выполнения алгоритма Арнольди, на практике необходимая точность может быть достигнута раньше чем на n-й итерации, что потребует какого-нибудь способа прервать последующие итерации. Для избегания лишних вычисление возможно оптимально оставить эту часть последовательной.&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;ref&amp;gt;Parallel GMRES Algorithm for Solving Giant Sparse System of Linear Equations https://github.com/arrgasm/paraGMRES/&amp;lt;/ref&amp;gt;. Программа была запущена на суперкомпьютере BlueGene на разреженной матрице размера 90448х90448. Параметрами запуска являются 100 итераций алгоритма и 10 перезапусков алгоритм (повторный запуск алгоритма с использованием решения, полученного на предыдущем запуске, в качестве начального приближения). График зависимости времени выполнения от числа процессоров представлен на рисунке 2.&lt;br /&gt;
[[file:PlotLvs1.png|thumb|center|400px|Рис 2. График зависимости времени выполнения от числа процессоров]]&lt;br /&gt;
График эффективности для полученного времени выполнения указан на рисунке 3.&lt;br /&gt;
[[file:PlotLvs2.png|thumb|center|400px|Рис 3. График зависимости эффективности реализации от числа процессоров]]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Реализации алгоритма GMRES присутствуют во многих программных продуктах как части стандартных библиотек, например Matlab или DEFORM3D. Также существую отдельные библиотеки, например MGMRES для языка С++.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Тыртышников Е. Е. Методы численного анализа — М., Академия, 2007.&lt;br /&gt;
&lt;br /&gt;
[2] М. Дана, А. Г. Зыков, Х. Д. Икрамов Метод минимальных невязок для специального класса линейных систем с нормальными матрицами коэффициентов - Ж. вычисл. матем. и матем. физ., 2005, том 45, номер 11&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:%D0%A1%D0%B5%D1%80%D0%B3%D0%B5%D0%B9/%D0%A5%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B5%D0%BD%D1%83%D0%BB%D0%B5%D0%B2%D1%8B%D1%85_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B6%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B._%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B6%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%BD%D0%B0_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80&amp;diff=18677</id>
		<title>Участник:Сергей/Хранение ненулевых элементов разреженной матрицы. Умножение разреженной матрицы на вектор</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%D0%BA:%D0%A1%D0%B5%D1%80%D0%B3%D0%B5%D0%B9/%D0%A5%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B5%D0%BD%D1%83%D0%BB%D0%B5%D0%B2%D1%8B%D1%85_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B6%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B._%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B6%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%BD%D0%B0_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80&amp;diff=18677"/>
		<updated>2016-11-21T07:54:16Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Dan}}&lt;br /&gt;
&lt;br /&gt;
Автор: [[U:Сергей|Герасимов Сергей]] (619)&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Разреженная матрица&#039;&#039;&#039; — это матрица с преимущественно нулевыми элементами. В противном случае, если бо́льшая часть элементов матрицы ненулевые, матрица считается плотной.&lt;br /&gt;
&lt;br /&gt;
Нет единства в определении того, какое именно количество ненулевых элементов делает матрицу разрежённой. Разные авторы предлагают различные варианты. Для матрицы порядка n число ненулевых элементов:&lt;br /&gt;
&lt;br /&gt;
~ есть O(n). Такое определение подходит разве что для теоретического анализа асимптотических свойств матричных алгоритмов;&lt;br /&gt;
&lt;br /&gt;
~ в каждой строке не превышает 10 в типичном случае;&lt;br /&gt;
&lt;br /&gt;
~ ограничено &amp;lt;math&amp;gt;n^{1+\gamma}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\gamma &amp;lt; 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Огромные разрежённые матрицы часто возникают при решении таких задач, как дифференциальное уравнение в частных производных.&lt;br /&gt;
&lt;br /&gt;
При хранении и преобразовании разрежённых матриц в компьютере бывает полезно, а часто и необходимо, использовать специальные алгоритмы и структуры данных, которые учитывают разрежённую структуру матрицы. Операции и алгоритмы, применяемые для работы с обычными, плотными матрицами, применительно к большим разрежённым матрицам работают относительно медленно и требуют значительных объёмов памяти. Однако разрежённые матрицы могут быть легко сжаты путём записи только своих ненулевых элементов, что снижает требования к компьютерной памяти.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Существуют различные форматы хранения разреженных матриц.&#039;&#039;&#039; Одни предназначены для хранения матриц специального вида (например, ленточных), другие обеспечивают работу с матрицами общего вида. Ниже рассмотрим некоторые весьма распространенные способы представления разреженных матриц.&lt;br /&gt;
&lt;br /&gt;
По-видимому, наиболее очевидным способом хранения произвольной разреженной матрицы является &#039;&#039;&#039;координатный формат&#039;&#039;&#039;: хранятся только ненулевые элементы матрицы, и их координаты (номера строк и столбцов). При данном подходе хранение матрицы A можно обеспечить в трех одномерных массивах:&lt;br /&gt;
&lt;br /&gt;
~ массив ненулевых элементов матрицы A (обозначим его как values);&lt;br /&gt;
&lt;br /&gt;
~ массив номеров строк матрицы A, соответствующих элементам массива values (обозначим его как rows);&lt;br /&gt;
&lt;br /&gt;
~ массив номеров столбцов матрицы A, соответствующих элементам массива values (обозначим его как cols);&lt;br /&gt;
&lt;br /&gt;
Данный способ представления называют полным, поскольку представлена вся матрица А, и неупорядоченным, поскольку элементы матрицы могут храниться в произвольном порядке.&lt;br /&gt;
&lt;br /&gt;
Хотя многие математические библиотеки поддерживают матрично-векторные операции в координатном формате, данный формат обеспечивает медленный доступ к элементам матрицы, и является затратным по используемой памяти. В рассмотренном выше примере избыточность по памяти образом проявляется в массиве rows, в котором строчные координаты хранятся неоптимальным образом.&lt;br /&gt;
&lt;br /&gt;
Перейдем далее к рассмотрению более экономных форматов хранения. &#039;&#039;&#039;Разреженный строчный формат&#039;&#039;&#039; - это одна из наиболее широко используемых схем хранения разреженных матриц. Эта схема предъявляет минимальные требования к памяти и в то же время оказывается очень удобной для нескольких важных операций над разреженными матрицами: сложения, умножения, перестановок строк и столбцов, транспонирования, решения линейных систем с разреженными матрицами коэффициентов как прямыми, так и итерационными методами и т. д.&lt;br /&gt;
&lt;br /&gt;
В соответствии с рассматриваемой схемой для хранения матрицы A требуется три одномерных массива:&lt;br /&gt;
&lt;br /&gt;
~ массив ненулевых элементов матрицы A, в котором они перечислены по строкам от первой до последней (обозначим его опять как values);&lt;br /&gt;
&lt;br /&gt;
~ массив номеров столбцов для соответствующих элементов массива values (обозначим его как cols);&lt;br /&gt;
&lt;br /&gt;
~ массив указателей позиций, с которых начинается описание очередной строки (обозначим его pointer). Описание k-й строки хранится в позициях с pointer[k]-й по (pointer[k+1]–1)-ю массивов values и cols. Если pointer[k]=pointer[k+1], то k-я строка пустая. Если матрица A состоит из n строк, то длина массива pointer будет n+1.&lt;br /&gt;
&lt;br /&gt;
Данный способ представления также является полным, и упорядоченным, поскольку элементы каждой строки хранятся в соответствии с возрастанием столбцовых индексов.&lt;br /&gt;
&lt;br /&gt;
Очевидно, что объем памяти, требуемый для хранения вектора pointer, значительно меньше, чем для хранения вектора rows. Более того, разреженный строчный формат обеспечивает эффективный доступ к строчкам матрицы; доступ к столбцам по прежнему затруднен. Поэтому предпочтительно использовать этот способ хранения в тех алгоритмах, в которых преобладают строчные операции.&lt;br /&gt;
&lt;br /&gt;
Существует также &#039;&#039;&#039;разреженный столбцовый формат&#039;&#039;&#039;, который строится аналогичным способом.&lt;br /&gt;
&lt;br /&gt;
Теперь, разобравшись со способами хранения разреженных матриц, можно перейти к &#039;&#039;алгоритму умножения разреженной матрицы на вектор&#039;&#039;. Умножение матрицы на вектор является подзадачей для нахождения решений СЛАУ итерационными методами.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Пусть матрица размером &amp;lt;math&amp;gt;N\times M&amp;lt;/math&amp;gt; содержит в себе &amp;lt;math&amp;gt;NZ&amp;lt;/math&amp;gt; ненулевых элементов, где &amp;lt;math&amp;gt;NZ\ll N^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Условимся использовать строчный формат хранения матрицы, который описан выше.&lt;br /&gt;
&lt;br /&gt;
На входе у нас 4 массива: val(ненулевые элементы матрицы), col(номера столбцов), row(массив указателей) и vec(вектор, на который мы умножаем матрицу).&lt;br /&gt;
&lt;br /&gt;
На выходе получим вектор out.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;out_i = \sum_{j=row_i}^{row_{i+1} - 1} val_j \cdot vec_{col_j}, \ i=\overline{0,N-1}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;N&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;
&amp;lt;math&amp;gt;out_i = \sum_{j=row_i}^{row_{i+1} - 1} val_j \cdot vec_{col_j}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итого: &amp;lt;math&amp;gt;NZ&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; сложений(&amp;lt;math&amp;gt;NZ-N&amp;lt;x&amp;lt;NZ-1&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;
[[Файл:sparse.jpg|thumb|center|500px|Рис.1 Умножение разреженной матрицы на вектор]]&lt;br /&gt;
&lt;br /&gt;
Элементы из массива val умножаются на элементы из массива vec с соответствующим индексом. Черным отмечены ненулевые элементы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Предполагается, что матрица представлена в разреженном строчном формате.&lt;br /&gt;
&lt;br /&gt;
    for(i=0; i&amp;lt;N; i++)&lt;br /&gt;
    {&lt;br /&gt;
        out[i]=0;&lt;br /&gt;
        for(j=row[i]; j&amp;lt;row[i+1]; j++)&lt;br /&gt;
        {&lt;br /&gt;
            out[i] += val[j]*vec[col[j]];&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Внешний цикл - цикл по элементам выходного вектора. Внутренний - цикл по строкам разреженной матрицы.&lt;br /&gt;
Во внутреннем цикле реализовано накопление сумм произведений в выходной элемент.&lt;br /&gt;
Индекс &#039;&#039;j&#039;&#039; показывает с какого по какой элемент нужно считать из &#039;&#039;val&#039;&#039; (вектор с ненулевыми значениями матрицы), а также позволяет определить в каких столбцах расположены эти значения в матрице (с помощью вектора &#039;&#039;col&#039;&#039;).&lt;br /&gt;
Минимальное и максимальное значение &#039;&#039;j&#039;&#039; узнается из вектора &#039;&#039;row&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bullet \ NZ&amp;lt;/math&amp;gt; умножений &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bullet \ x&amp;lt;/math&amp;gt; сложений(&amp;lt;math&amp;gt;NZ-N&amp;lt;x&amp;lt;NZ-1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Всего &amp;lt;math&amp;gt;2NZ&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;NZ&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;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция вычисляет функцию &amp;lt;math&amp;gt;a \cdot b&amp;lt;/math&amp;gt;. Координаты области следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;0&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;\cdot&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt;, принимая все натуральные значения,&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;k = k(i) = row[i+1]-row[i]&amp;lt;/math&amp;gt;. (На рисунке вместо обозначения &#039;&#039;row&#039;&#039; использовано обозначение &#039;&#039;r&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Результаты операции - &#039;&#039;&#039;промежуточные&#039;&#039;&#039; данные алгоритма.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция вычисляет функцию &amp;lt;math&amp;gt;a + b&amp;lt;/math&amp;gt;. &lt;br /&gt;
Координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;0&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;\cdot&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;k-1&amp;lt;/math&amp;gt;, принимая все натуральные значения,&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;k = k(i) = row[i+1]-row[i]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результат операции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;j &amp;lt; k - 1&amp;lt;/math&amp;gt; является &#039;&#039;&#039;промежуточным&#039;&#039;&#039; данным алгоритма;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;j = k - 1&amp;lt;/math&amp;gt; является &#039;&#039;&#039;выходным&#039;&#039;&#039; данным &amp;lt;math&amp;gt;out[i]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Описанный граф изображен на Рис.2. Здесь вершины первой группы обозначены красным цветом и отмечены знаком умножения, вершины второй - зелёным цветом и знаком сложения. Вершины, соответствующие входным данным обозначены белым цветом и выходным - синим.&lt;br /&gt;
&lt;br /&gt;
[[Файл:new_sparse.png|thumb|center|1000px|Рис.2 Умножение разреженной матрицы на вектор. Информационный граф]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
При наличии бесконечного числа процессоров для умножения разреженной матрицы на вектор потребуется:&lt;br /&gt;
&lt;br /&gt;
~ 1 ярус умножений&lt;br /&gt;
&lt;br /&gt;
~ &amp;lt;math&amp;gt;Z-1&amp;lt;/math&amp;gt; операция сложения, где Z - максимальное число ненулевых элементов в строке.&lt;br /&gt;
&lt;br /&gt;
Максимальное число требуемых процессоров - NZ.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
~ массив ненулевых элементов матрицы A, в котором они перечислены по строкам от первой до последней (обозначим его как val);&lt;br /&gt;
&lt;br /&gt;
~ массив номеров столбцов для соответствующих элементов массива val (обозначим его как col);&lt;br /&gt;
&lt;br /&gt;
~ массив указателей позиций, с которых начинается описание очередной строки (обозначим его row);&lt;br /&gt;
&lt;br /&gt;
~ вектор, на который будет умножаться матрица (обозначим его vec).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Для матрицы размером &amp;lt;math&amp;gt;N\times M&amp;lt;/math&amp;gt;, содержащей в себе &amp;lt;math&amp;gt;NZ&amp;lt;/math&amp;gt; ненулевых элементов, где &amp;lt;math&amp;gt;NZ\ll N^2&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
~ вектор val - NZ элементов;&lt;br /&gt;
&lt;br /&gt;
~ вектор col - NZ элементов;&lt;br /&gt;
&lt;br /&gt;
~ вектор row - N+1 элемент;&lt;br /&gt;
&lt;br /&gt;
~ вектор vec - M элементов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Вектор out размером N.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является &#039;&#039;линейным&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных – чуть меньше &#039;&#039;единицы&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм обладает свойством детерминированности.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Проведём исследование масштабируемости параллельной реализации умножения разреженной матрицы на вектор. Исследование проводилось на вычислительном комплексе [http://hpc.cmc.msu.ru/bgp Blue Gene/P]&amp;lt;ref&amp;gt; Blue Gene/P http://hpc.cmc.msu.ru/bgp&amp;lt;/ref&amp;gt;. Вычисления проводились с помощью следующего программного [https://www.dropbox.com/s/gx0s5r0jg58y8wa/main.c кода]&amp;lt;ref&amp;gt;Sparse matrix-vector MPI multiplication &amp;lt;/ref&amp;gt;. &lt;br /&gt;
Матрицы генерировались случайным образом.&lt;br /&gt;
&lt;br /&gt;
На следующем рисунке показана зависимость времени выполнения алгоритма от числа используемых процессоров и количества ненулевых элементов матрицы. Можно заметить, что скорость вычисления при переходе с последовательной на параллельную версию возросла значительно. Однако, дальнейшее увеличение числа вычислительных устройств не дает сильного прироста производительности. Это объясняется быстрым ростом накладных расходов на организацию параллельного выполнения.&lt;br /&gt;
&lt;br /&gt;
[[Файл:plot_more_points.png|thumb|center|1000px|Рис.3 Умножение разреженной матрицы на вектор. Масштабируемость]]&lt;br /&gt;
&lt;br /&gt;
На рисунке ниже изображен график эффективности в зависимости от числа процессоров и размера задачи. Можно заметить небольшой всплеск эффективности при использовании 64 процессоров.&lt;br /&gt;
&lt;br /&gt;
[[Файл:plot_eff_new.png|thumb|center|1000px|Рис.4 Умножение разреженной матрицы на вектор. Эффективность]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Эффективная работа с разреженными матрицами реализована во многих библиотеках, например, [https://software.intel.com/en-us/intel-mkl Intel Math Kernel Library], базирующуюся на библиотеках BLAS и LAPACK, также математических пакет [http://matlab.ru/products/matlab Matlab] имеет собственную реализацию.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
[1] Писсанецки С. Технология разреженных матриц. - М.: Мир, 1988. — 410 с.&lt;br /&gt;
&lt;br /&gt;
[2] https://software.intel.com/sites/default/files/m/d/4/1/d/8/LW_SparseMM_ppt.pdf&lt;/div&gt;</summary>
		<author><name>Dan</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:%D0%A1%D0%B5%D1%80%D0%B3%D0%B5%D0%B9&amp;diff=18676</id>
		<title>Обсуждение участника:Сергей</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:%D0%A1%D0%B5%D1%80%D0%B3%D0%B5%D0%B9&amp;diff=18676"/>
		<updated>2016-11-21T07:54:08Z</updated>

		<summary type="html">&lt;p&gt;Dan: Содержимое страницы заменено на «= Правки = Не удаляйте замечания»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Правки =&lt;br /&gt;
Не удаляйте замечания&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:Alexander34396/%D0%9E%D0%B1%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D0%BD%D0%B5%D0%B2%D1%8F%D0%B7%D0%BE%D0%BA&amp;diff=17893</id>
		<title>Участник:Alexander34396/Обобщенный метод минимальных невязок</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%D0%BA:Alexander34396/%D0%9E%D0%B1%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D0%BD%D0%B5%D0%B2%D1%8F%D0%B7%D0%BE%D0%BA&amp;diff=17893"/>
		<updated>2016-11-17T11:25:26Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[#Участник:Alexander34396|А.А.Ульянов]] (разделы [[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Последовательная сложность алгоритма|1.6]], [[#Входные и выходные данные алгоритма|1.9]], [[#Существующие реализации алгоритма|2.7]]), [[#Участник:Kpetrov|К.Петров]] (разделы [[#Информационный граф|1.7]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Свойства алгоритма|1.10]], [[#Масштабируемость алгоритма и его реализации|2.4]]).&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Обобщенный метод минимальных невязок&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt; O(nm^2) &amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt; (n + 1)^2 &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt; n &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;
&#039;&#039;&#039;Обобщённый метод минимальных невязок&#039;&#039;&#039; ({{lang-en|Generalized minimal residual method, GMRES}}) - итерационный метод численного решения системы линейных алгебраических уравнений с невырожденной матрицей. Метод основан на минимизации квадратичного функционала невязки на подпространствах Крылова. Разработан Юсефом Саадом и Мартином Шульцем&amp;lt;ref&amp;gt; Y.Saad, M.H. Schultz, GMRES: A generalized minimal residual algorithm for solving nonsymmetric linear systems, SIAM J. Scientific and Stat. Comp. 7: 856-869 (1986) &amp;lt;/ref&amp;gt; в 1986 году как обобщение метода MINRES&amp;lt;ref&amp;gt;C. C. Paige and M. A. Saunders. Solution of sparse indefinite systems of linear equations, SIAM J. Numerical Analysis 12, 617-629 (1975)&amp;lt;/ref&amp;gt; на случай систем с несимметричными матрицами.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; &lt;br /&gt;
* система линейных алгебраических уравнений вида &amp;lt;math&amp;gt; Ax = b &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; — невырожденная матрица размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-на-&amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; - начальное приближение.&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; &lt;br /&gt;
* &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt; - приближённое решение исходной системы.&lt;br /&gt;
&lt;br /&gt;
Метод GMRES приближает точное решение исходной системы &amp;lt;math&amp;gt; Ax = b &amp;lt;/math&amp;gt; вектором &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt;, который минимизирует Евклидову норму невязки &amp;lt;math&amp;gt; r_m = Ax_m - b&amp;lt;/math&amp;gt; на подпространстве Крылова:&lt;br /&gt;
: &amp;lt;math&amp;gt; K_m = K_m(A,b) = \operatorname{span} \, \{ b, Ab, A^2b, \ldots, A^{m-1}b \} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \operatorname{span} \, \{ a_1, a_2, \ldots, a_m \} &amp;lt;/math&amp;gt; - линейная оболочка системы векторов &amp;lt;math&amp;gt; \{ a_1, a_2, \ldots, a_m \} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На каждой итерации метода решение уточняется поправкой, представленной в виде разложения по ортонормированному базису пространства &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt;: &lt;br /&gt;
: &amp;lt;math&amp;gt; x_m = x_0 + z_m &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; - некоторое начальное приближение, &amp;lt;math&amp;gt; z_m \in K_m &amp;lt;/math&amp;gt; - поправка решения.&lt;br /&gt;
&lt;br /&gt;
=== Ортогонализация Арнольди ===&lt;br /&gt;
&lt;br /&gt;
Для построения ортонормированного базиса &amp;lt;math&amp;gt; v_1, v_2, \ldots, v_m &amp;lt;/math&amp;gt; пространства Крылова &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt; метод использует процесс Арнольди.&lt;br /&gt;
&lt;br /&gt;
Идея процесса Арнольди состоит в том, что для нахождения вектора &amp;lt;math&amp;gt; v_{j+1} &amp;lt;/math&amp;gt; при известных векторах &amp;lt;math&amp;gt; v_1, v_2, \ldots, v_j &amp;lt;/math&amp;gt; необходимо вычислить вектор &amp;lt;math&amp;gt; Av_j &amp;lt;/math&amp;gt; и ортонормировать этот вектор относительно &amp;lt;math&amp;gt; v_1, v_2, \ldots, v_j &amp;lt;/math&amp;gt;:&lt;br /&gt;
: &amp;lt;math&amp;gt; v_{j+1} = \frac{\hat{v}_{j+1}}{\|\hat{v}_{j+1}\|_2} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \hat{v}_{j+1} = Av_j - \sum_{i=1}^j h_{ij}v_{i} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Коэффициенты &amp;lt;math&amp;gt; h_{ij} = (Av_j, v_i) &amp;lt;/math&amp;gt; определяются из условия ортогональности:&lt;br /&gt;
: &amp;lt;math&amp;gt; A(v_j, v_k) - \sum_{i=1}^j h_{ij}(v_{i}, v_k)  = 0 &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \quad k=1,\ldots,j &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результат процедуры Арнольди совпадает с результатом процесса Грамма-Шмидта, применённого к векторам &amp;lt;math&amp;gt; \{b, Ab, A^2b, \ldots, A^{m-1}b\} &amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; &lt;br /&gt;
* &amp;lt;math&amp;gt; v_1 &amp;lt;/math&amp;gt;, такой что &amp;lt;math&amp;gt; \|v_1\|_2 = 1 &amp;lt;/math&amp;gt;;&lt;br /&gt;
* матрица &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; размером &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;-на-&amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; &lt;br /&gt;
* &amp;lt;math&amp;gt; v_1, v_2, \ldots, v_m &amp;lt;/math&amp;gt; - ортонормированный базис пространства Крылова &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Алгоритм процесса:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Выполнять для &amp;lt;math&amp;gt; \quad j=1,\ldots,m &amp;lt;/math&amp;gt;:&lt;br /&gt;
# &amp;lt;math&amp;gt; h_{ij} = (Av_j, v_i), \quad i=1,\ldots,j &amp;lt;/math&amp;gt;;&lt;br /&gt;
# &amp;lt;math&amp;gt; \hat{v}_{j+1} = Av_j - \sum_{i=1}^j h_{ij}v_{i} &amp;lt;/math&amp;gt;;&lt;br /&gt;
# &amp;lt;math&amp;gt; h_{j+1j} = \|\hat{v}_{j+1}\|_2 &amp;lt;/math&amp;gt;;&lt;br /&gt;
# &amp;lt;math&amp;gt; v_{j+1} = \frac{\hat{v}_{j+1}}{h_{j+1j}} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;При введении матричных обозначений можно записать:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Поправка решения:&lt;br /&gt;
: &amp;lt;math&amp;gt; z_m = V_my_m &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; y_m \in \mathbb{R}^m &amp;lt;/math&amp;gt; - вектор коэффициентов, &amp;lt;math&amp;gt; V_m = [v_1|v_2|...|v_m] &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Матричное представление процесса Арнольди:&lt;br /&gt;
: &amp;lt;math&amp;gt; AV_m = V_{m+1}H_{m+1m} = V_mH_m + h_{m+1m}v_{m+1} e_m^T &amp;lt;/math&amp;gt;, &lt;br /&gt;
где &lt;br /&gt;
: &amp;lt;math&amp;gt;H_{m+1m} = \begin{bmatrix}h_{11} &amp;amp; h_{12} &amp;amp; h_{13} &amp;amp;... &amp;amp; h_{1m-1} &amp;amp; h_{1m} \\ h_{21} &amp;amp; h_{22} &amp;amp; h_{23} &amp;amp; ... &amp;amp; h_{2m-1} &amp;amp; h_{2m} \\ 0 &amp;amp; h_{32} &amp;amp; h_{33} &amp;amp;...&amp;amp; h_{3m-1} &amp;amp; h_{3m} \\ ... &amp;amp; ... &amp;amp; ... &amp;amp; ... &amp;amp; ... &amp;amp; ... \\ 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; ... &amp;amp; h_{m m-1} &amp;amp; h_{mm} \\0 &amp;amp; 0 &amp;amp; 0 &amp;amp; ... &amp;amp; 0 &amp;amp; h_{m+1 m}\end{bmatrix}&amp;lt;/math&amp;gt;&lt;br /&gt;
- верхняя матрица Хессенберга размерности &amp;lt;math&amp;gt; m+1 &amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Минимизация функционала невязки ===&lt;br /&gt;
&lt;br /&gt;
Невязка исходной системы имеет вид:&lt;br /&gt;
: &amp;lt;math&amp;gt; r_m = b - A(x_0 + z_m) = r_0 - AV_my_m = \beta v_1 - V_{m+1}H_{m+1k}y_m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; \beta = \|r_0\|_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
C учетом того, что матрица &amp;lt;math&amp;gt; V_{k+1} &amp;lt;/math&amp;gt; составлена из ортонормированных векторов:&lt;br /&gt;
: &amp;lt;math&amp;gt; r_m = \beta V_{m+1}e_1 - H_{m+1m}y_m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; e_1 = (1,0,0,\ldots,0)^T &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Норма невязки &amp;lt;math&amp;gt; r_m &amp;lt;/math&amp;gt;:&lt;br /&gt;
: &amp;lt;math&amp;gt; \|r_m\|_2 = \|\beta e_1 - H_{m+1m}y_m\|_2 &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Норма &amp;lt;math&amp;gt; \|r_m\|_2 &amp;lt;/math&amp;gt; достигает минимума при &amp;lt;math&amp;gt; \beta e_1 = H_{m+1m}y_m &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для нахождения решения такой системы, матрица &amp;lt;math&amp;gt; H_{m+1m} &amp;lt;/math&amp;gt; приводится к верхнему треугольному виду с помощью &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; последовательных [[Метод_Гивенса_(вращений)_QR-разложения_квадратной_матрицы_(вещественный_вариант)|вращений Гивенса]].&lt;br /&gt;
&lt;br /&gt;
=== Общая схема метода ===&lt;br /&gt;
&lt;br /&gt;
В общем виде m-aя итерация алгоритма GMRES может быть записан следующим образом:&lt;br /&gt;
&lt;br /&gt;
# найти ортонормированный базис &amp;lt;math&amp;gt; V_m &amp;lt;/math&amp;gt; подпространства &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt; с помощью ортогонализации Арнольди;&lt;br /&gt;
# найти &amp;lt;math&amp;gt; y_m &amp;lt;/math&amp;gt;, минимизирующий &amp;lt;math&amp;gt; \|r_m\|_2 &amp;lt;/math&amp;gt;;&lt;br /&gt;
# вычислить &amp;lt;math&amp;gt; x_m = x_0 + V_my_m &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; - начальное приближение;&lt;br /&gt;
# вычислить &amp;lt;math&amp;gt; r_m &amp;lt;/math&amp;gt; и остановиться,если требуемая точность была достигнута, иначе повторить.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро последовательной версии метода GMRES состоит из двух частей:&lt;br /&gt;
* Вычисление ортонормированного базиса &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt;;&lt;br /&gt;
* Формирование приближенного решения &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для вычисления ортонормированного базиса &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt; метод использует процесс Арнольди:&lt;br /&gt;
: &amp;lt;math&amp;gt; h_{j+1j}v_{j+1} = Av_j - \sum_{i=1}^j h_{ij}v_{j} &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; h_{ij} = (Av_j, v_i)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; \quad j=1,\ldots,m &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для нахождения приближённого решения &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt; метод использует формулу:&lt;br /&gt;
: &amp;lt;math&amp;gt; x_m = x_0 + V_my_m &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;
На практике используется перезапускаемая версия метода - GMRES(m):&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;1 Подготовка перед итерационным процессом:&#039;&#039;&#039;&lt;br /&gt;
:1.1 Выбрать начальное приближение &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt;;&lt;br /&gt;
:1.2 Посчитать невязку &amp;lt;math&amp;gt; r_0 = b - Ax_0 &amp;lt;/math&amp;gt;;&lt;br /&gt;
:1.3 Вычислить &amp;lt;math&amp;gt; v_1 = \frac{r_0}{\|r_0\|_2} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2 Построение ортонормированного базиса &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
: Для всех &amp;lt;math&amp;gt; j &amp;lt;/math&amp;gt; от 1 до m по нарастанию выполнять:&lt;br /&gt;
:2.1 &amp;lt;math&amp;gt; h_{ij} := (Av_j, v_i), \quad i=1,\ldots,j &amp;lt;/math&amp;gt;;&lt;br /&gt;
:2.2 &amp;lt;math&amp;gt; \hat{v}_{j+1} := Av_j - \sum_{i=1}^j h_{ij}v_{i} &amp;lt;/math&amp;gt;;&lt;br /&gt;
:2.3 &amp;lt;math&amp;gt; h_{j+1j} = \|\hat{v}_{j+1}\|_2 &amp;lt;/math&amp;gt;;&lt;br /&gt;
:2.4 &amp;lt;math&amp;gt; v_{j+1} = \frac{\hat{v}_{j+1}}{h_{j+1j}} &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3 Вычисление &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:3.1 &amp;lt;math&amp;gt; x_m = x_0 + V_my_m &amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;y_m&amp;lt;/math&amp;gt; минимизирует &amp;lt;math&amp;gt;\|r_0 - AV_my_m\|_2&amp;lt;/math&amp;gt;;&lt;br /&gt;
:3.2 Вычислить &amp;lt;math&amp;gt; r_m &amp;lt;/math&amp;gt;;&lt;br /&gt;
:3.3 Если требуемая точность достигнута, остановиться.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;4 Перезапуск:&#039;&#039;&#039;&lt;br /&gt;
:4.1 &amp;lt;math&amp;gt;x_0 = x_m&amp;lt;/math&amp;gt;;&lt;br /&gt;
:4.2 &amp;lt;math&amp;gt;v_1 = \frac{r_m}{\|r_m\|_2}&amp;lt;/math&amp;gt;;&lt;br /&gt;
:4.3 Перейти к шагу 2.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Если пренебречь сложностью вычисления &amp;lt;math&amp;gt; y_m &amp;lt;/math&amp;gt;, то общую сложность алгоритма GMRES можно разделить на две части:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1. Сложность вычисления ортонормированного базиса пространства &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt;:&#039;&#039;&#039;&lt;br /&gt;
:a) Для вычисления &amp;lt;math&amp;gt; j &amp;lt;/math&amp;gt;-го вектора базиса &amp;lt;math&amp;gt; K_m, j &amp;lt; m &amp;lt;/math&amp;gt; требуется:&lt;br /&gt;
:: &amp;lt;math&amp;gt; NZ + (2j + 1)n &amp;lt;/math&amp;gt; мультипликативных операций, где &amp;lt;math&amp;gt; NZ &amp;lt;/math&amp;gt; - количество ненулевых элементов матрицы &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt;. &lt;br /&gt;
:b) Вычисление последнего вектора базиса требует:&lt;br /&gt;
:: &amp;lt;math&amp;gt; n(m + 1) &amp;lt;/math&amp;gt; мультипликативных операций. &lt;br /&gt;
:c) Общая мультипликативная сложность вычисления ортонормированного базиса &amp;lt;math&amp;gt; K_m &amp;lt;/math&amp;gt;: &lt;br /&gt;
:: &amp;lt;math&amp;gt; O(nm^2) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2. Сложность вычисления приближённого решения &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt;:&#039;&#039;&#039; &lt;br /&gt;
:a) Вычисление этой формулы требует &amp;lt;math&amp;gt; nm &amp;lt;/math&amp;gt; мультипликативных операций.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
[[File: Drawing.png|thumb|center|350px|&#039;&#039;&#039;Рис. 1&#039;&#039;&#039; &lt;br /&gt;
&#039;&#039;&#039;input&#039;&#039;&#039; - входные данные алгоритма (квадратная матрица, вектор правой части, начальное приближение, точность решения);&lt;br /&gt;
 &#039;&#039;&#039;&amp;lt;math&amp;gt; A_i &amp;lt;/math&amp;gt;&#039;&#039;&#039; - шаги алгоритма Арнольди, &amp;lt;math&amp;gt; x_i &amp;lt;/math&amp;gt; - нахождение невязки на &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt;-ой итерации; &lt;br /&gt;
&#039;&#039;&#039;if&#039;&#039;&#039; - вычисление &amp;lt;math&amp;gt; r_m &amp;lt;/math&amp;gt; и в случае достижения нужной точности - остановка.]]&lt;br /&gt;
Шаги алгоритма Арнольди выполняются строго последовательно, но вычисление &amp;lt;math&amp;gt; i &amp;lt;/math&amp;gt;-ой невязки может происходить параллельно&lt;br /&gt;
с &amp;lt;math&amp;gt; (i + 1) &amp;lt;/math&amp;gt;-ым шагом алгоритма Арнольди.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
В ходе анализа перезапускаемого метода обобщенных минимальных невязок был выявлен ряд подзадач, выполняющихся неоднократно: умножение матрицы на вектор, вычисление скалярного произведения векторов, нахождение нормы вектора, нормирование вектора, нахождение взвешенной суммы векторов. Наиболее трудоемкой среди перечисленных операций является умножение матрицы на вектор.&lt;br /&gt;
&lt;br /&gt;
Выполнение перечисленных операций занимает большую часть времени работы алгоритма GMRES. Поэтому при увеличении эффективности использования вычислительных ресурсов и ресурсов памяти вычислительной машины при выполнении этих операций повышается эффективность метода в целом. Достигается это применением при выполнении перечисленных операций аппарата параллельных вычислений.&lt;br /&gt;
&lt;br /&gt;
При выполнении параллельного алгоритма решения систем линейных алгебраических уравнений необходимо распределить входные данные наиболее рациональным способом. Матрица коэффициентов разбивается на непрерывные горизонтальные полосы. Распределение вектора правой части и начального приближения выполнено по принципу дублирования, т.е. все элементы векторов скопированы на все процессоры. Для рассматриваемой задачи решения СЛАУ такой подход распределения допустим, т.к. векторы содержат столько же элементов, сколько и одна строка или один столбец матрицы коэффициентов.&lt;br /&gt;
&lt;br /&gt;
Подзадачи можно разделить на 2 группы: операции между матрицей и вектором (например, умножение матрицы на вектор) и операции между двумя векторами (например, скалярное умножение). Подзадачи умножения константы на вектор и определение нормы вектора можно относить ко второй группе, так как их трудоемкость одного порядка.&lt;br /&gt;
&lt;br /&gt;
Результатом выполнения рассматриваемых операций является, вектор, части которого расположены на участвовавших в вычислениях процессорах. Для объединения результатов расчета и получения полного вектора на каждом процессоре вычислительной системы необходимо выполнить операцию сбора данных.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt; A &amp;lt;/math&amp;gt; – квадратная матрица размера &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;-на-&amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt; b &amp;lt;/math&amp;gt; – вектор правой части размера &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;; &lt;br /&gt;
* &amp;lt;math&amp;gt; x_0 &amp;lt;/math&amp;gt; – начальное приближение размера &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;;&lt;br /&gt;
* &amp;lt;math&amp;gt; \epsilon &amp;lt;/math&amp;gt; – погрешность решения.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Для перезапускаемой версии алгоритма дополнительно:&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; – число итераций.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt; n^2 + 2n + 1 &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: &lt;br /&gt;
* &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt; - вектор приближённого решения размера &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Обобщенный метод минимальных невязок предназначен для решения несимметричных систем линейных уравнений. GMRES использует перезазапуски для контроля требований к хранению данных.&lt;br /&gt;
&lt;br /&gt;
Если используется неперезапускаемый метод, GMRES будет сходиться за не более &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; шагов. Но это не имеет практического применения, когда &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; велико. Кроме того, требования к памяти и вычислениям при отсутствии перезапусков являются очень высокими. Важнейшим элементом для успешного применения &amp;lt;math&amp;gt; GMRES(m)&amp;lt;/math&amp;gt; являются перезапуски; то есть выбор &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Существуют примеры, для которых метод застаивается и сходимость есть только на &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;-м шаге. Для таких систем, любой выбор &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; меньше, чем &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; - не сходится.&lt;br /&gt;
&lt;br /&gt;
Основным недостатком GMRES является то, что объемы работ и ресурсы памяти, требуемые для итерации, линейно возрастают с увеличением числа итераций. Если не удалось получить чрезвычайно быструю сходимость - затраты будут очень высокими. Основной способ преодолеть это ограничение - это перезапуск итерации. После выбранного числа итераций &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; накопленные данные будут очищены и промежуточные результаты используются в качестве входных данных для последующих итераций. Эта процедура повторяется до тех пор, пока сходимость не будет достигнута. Трудность заключается в выборе подходящего значения &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;. Если &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt; слишком мало, &amp;lt;math&amp;gt;GMRES(m)&amp;lt;/math&amp;gt;  может быть медленно сходиться, или не сойтись совсем. Значение &amp;lt;math&amp;gt; m &amp;lt;/math&amp;gt;, большее, чем это необходимо, включает в себя чрезмерную работы и использует больше памяти. К сожалению, нет определенных правил, регулирующих выбор &amp;lt;math&amp;gt; m &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;
В статье &amp;lt;ref&amp;gt; M. Sosonkina, Donald C. S. Allison, Layne T. Watson: Scalability analysis of parallel GMRES implementations &amp;lt;/ref&amp;gt; анализируется параллельная реализация &amp;lt;math&amp;gt;GMRES(k)&amp;lt;/math&amp;gt; на Intel Paragon, IBM SP2 и Cray T3E. &lt;br /&gt;
Системы Intel Paragon и IBM SP2 не имеют двухуровневого кэша, что значительно сказывается на времени работы из-за больших потерь скорости и частых обращений к памяти.&lt;br /&gt;
В Cray T3E каждый процессор соединен с 8-килобайтовым кэшем данных и 96-килобайтовым двухуровневым кэшем данных. Также имеется дополнительный кэш объемом 4 мегабайта. Это достаточная емкость кэш-памяти для хранения всех данных с плавающей точкой с высоким коэффициентом попаданий кэша.&lt;br /&gt;
&lt;br /&gt;
Ниже представлены графики экспериментальных результатов, где штриховыми линиями указывается теоретическая связь между коэффициентом масштабируемости &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; и числом процессоров &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; для фиксированного значения эффективности. Сплошная линия является аппроксимацией экспериментальных данных методом наименьших квадратов. На всех графиках вертикальная ось представляет &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt;, а горизонтальная ось - &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Intel paragon.JPG|thumb|center|800px|&#039;&#039;&#039;Рис. 2&#039;&#039;&#039; Intel Paragon]]&lt;br /&gt;
[[File:Ibm sp2.JPG|thumb|center|800px|&#039;&#039;&#039;Рис. 3&#039;&#039;&#039; IBM SP2]]&lt;br /&gt;
[[File:Cray t3e.JPG|thumb|center|800px|&#039;&#039;&#039;Рис. 4&#039;&#039;&#039; Cray T3E]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теоретические и экспериментальные результаты показывают, что параллельные реализации &amp;lt;math&amp;gt;GMRES(k)&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;
Реализации алгоритма GMRES присутствуют во многих программных пакетах: &lt;br /&gt;
* [http://www.netlib.org/linpack/ LINPACK]&lt;br /&gt;
* [http://math.nist.gov/tnt/download.html/ JAMA/C++] &lt;br /&gt;
* [http://math-atlas.sourceforge.net/ ATLAS] &lt;br /&gt;
* [http://software.intel.com/mkl‎/ Intel MLK]&lt;br /&gt;
* [http://math.nist.gov/iml++/ IML++]&lt;br /&gt;
* [http://netlib.org/lapack/ LAPACK]&lt;br /&gt;
* [http://osl.iu.edu/research/mtl/ MTL]&lt;br /&gt;
* [http://www-users.cs.umn.edu/~saad/software/SPARSKIT/ SPARSKIT]&lt;br /&gt;
* [http://researcher.watson.ibm.com/researcher/view_group.php?id=1426 WSMP]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Dan</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:Alexander34396&amp;diff=17892</id>
		<title>Обсуждение участника:Alexander34396</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:Alexander34396&amp;diff=17892"/>
		<updated>2016-11-17T11:24:48Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Добрый день. Начал проверять статью и оставил следующие заметки&lt;br /&gt;
&lt;br /&gt;
Здравствуйте. Немного исправил статью, исходя из ваших замечаний.&lt;br /&gt;
&lt;br /&gt;
= 1.2 = &lt;br /&gt;
На мой взгляд, нужны определения&lt;br /&gt;
span?&lt;br /&gt;
l2-норма?&lt;br /&gt;
&lt;br /&gt;
: [[Участник:Alexander34396|Alexander34396]] Дано пояснение обозначения span.Вместо l2-норма теперь используется Евклидова норма.&lt;br /&gt;
&lt;br /&gt;
= 1.2.1 = &lt;br /&gt;
Вот я читаю этот раздел как человек со стороны и вижу много формул. Почему они именно такие? В чем суть этого алгоритма?&lt;br /&gt;
&lt;br /&gt;
: [[Участник:Alexander34396|Alexander34396]] Перед алгоритмом добавлено описание идеи алгоритма и пояснения к формулам.&lt;br /&gt;
&lt;br /&gt;
= 1.2.2 = &lt;br /&gt;
Новые определения&lt;br /&gt;
&lt;br /&gt;
: [[Участник:Alexander34396|Alexander34396]] Добавлены некоторые пояснения.Добавлена ссылка на статью - вращения Гивенса.&lt;br /&gt;
&lt;br /&gt;
Затем я остановился, и у меня главные вопрос. Возможно ли сделать статью такой, чтобы для ее прочтения не требовалось обращаться к куче дополнительных источников? Вот я человек со стороны, хотя и заканчивал мехмат. Я могу разобраться со всем написанным здесь, но для этого мне придется гуглить кучу материалов. Но, насколько я понимаю, цель таких статей - быть более полными.&lt;br /&gt;
&lt;br /&gt;
: [[Участник:Alexander34396|Alexander34396]]  На мой взгляд, формат статей algo-wiki не подразумевает подробных объяснений и выводов формул, поэтому я добавил только некоторые пояснения, которые делают повествование более последовательным и несколько более понятным. При этом для полного понимания описанного метода для человека со стороны всё равно придётся обращаться к сторонним источникам.&lt;br /&gt;
&lt;br /&gt;
Можете или добавить объяснений или возразить мне. В любом случае, пока с прочтением остановился, жду ответа или исправление (а лучше и того, и другого)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= 2.4 = &lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 14:24, 17 ноября 2016 (MSK) Необходимо переработать&lt;br /&gt;
Требования были такие: &lt;br /&gt;
- Реализация: полностью собственная или обращение к библиотечной функции (Intel MKL, PETSc, FFTW, ScaLAPACK). В любом случае, текст исследуемой программы должен быть представлен в отчете. &lt;br /&gt;
&lt;br /&gt;
- Компьютерная платформа может быть любой (Ломоносов, BlueGene или что-то иное). Описание компьютерной платформы должно быть в отчете. &lt;br /&gt;
&lt;br /&gt;
- Должен быть представлен график сильной масштабируемости (зависимости производительности от числа процессов; если при этом&lt;br /&gt;
ещё и зависимость от размера задачи - это только в плюс). График должен выглядеть пристойно и понятно, оси и единицы измерения должны быть подписаны. К графику обязательно должны быть словесные пояснения! Требовалось подобрать такие размеры задачи и числа процессоров, чтобы отразить на графике характерные точки, описывающие свойства алгоритма и программы.&lt;/div&gt;</summary>
		<author><name>Dan</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:%D0%AE%D0%BB%D0%B8%D1%8F_%D0%96%D0%BE%D1%81%D0%B0%D0%BD&amp;diff=17890</id>
		<title>Обсуждение участника:Юлия Жосан</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:%D0%AE%D0%BB%D0%B8%D1%8F_%D0%96%D0%BE%D1%81%D0%B0%D0%BD&amp;diff=17890"/>
		<updated>2016-11-17T11:23:33Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Пункт 1.10 =&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 14:03, 17 ноября 2016 (MSK) Отсутствует оценка вычислительной мощности&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 2.4 =&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 14:03, 17 ноября 2016 (MSK) отсутствует исследование масштабируемости&lt;br /&gt;
&lt;br /&gt;
Требования были такие: &lt;br /&gt;
- Реализация: полностью собственная или обращение к библиотечной функции (Intel MKL, PETSc, FFTW, ScaLAPACK). В любом случае, текст исследуемой программы должен быть представлен в отчете. &lt;br /&gt;
- Компьютерная платформа может быть любой (Ломоносов, BlueGene или что-то иное). Описание компьютерной платформы должно быть в отчете. &lt;br /&gt;
- Должен быть представлен график сильной масштабируемости (зависимости производительности от числа процессов; если при этом&lt;br /&gt;
ещё и зависимость от размера задачи - это только в плюс). График должен выглядеть пристойно и понятно, оси и единицы измерения должны быть подписаны. К графику обязательно должны быть словесные пояснения! Требовалось подобрать такие размеры задачи и числа процессоров, чтобы отразить на графике характерные точки, описывающие свойства алгоритма и программы.&lt;/div&gt;</summary>
		<author><name>Dan</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:Janyell&amp;diff=17887</id>
		<title>Обсуждение участника:Janyell</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:Janyell&amp;diff=17887"/>
		<updated>2016-11-17T11:19:40Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Добрый день. Подключаюсь к проверке. Статья мне в целом понравилась, и тем больше от этого хочется добавить замечаний, чтобы довести ее до того вида, чтобы она могла остаться на Алговики.&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.1 = &lt;br /&gt;
Разреженная матрица, будучи множеством чисел, не имеющим регулярности, &#039;&#039;&#039;не может быть представлена в памяти машины тем же простым способом, что и полная матрица&#039;&#039;&#039;. Поэтому возникает необходимость дополнительно хранить индексную информацию, указывающую расположение каждого элемента в регулярном массиве.&lt;br /&gt;
&lt;br /&gt;
Что означает фраза, выделенная жирным? Или как-то переформулируйте утверждение, оно не понятно&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Однако многие схемы хранения допускают определенную долю нулей, и алгоритм обрабатывает их, как если бы они не были нулями.&#039;&#039;&#039;&lt;br /&gt;
Тоже непонятно&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.1.1.1 = &lt;br /&gt;
Поставьте определение ленточной матрицы в начало. Потому что, начиная читать первую фразу, сначала задаешься вопросом, что это такое&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.1.1.2 = &lt;br /&gt;
&#039;&#039;&#039;Кроме того, схема является статической, потому что включение нового элемента, лежащего вне оболочки, требует изменения всей структуры (если только не используются записи переменной длины).&#039;&#039;&#039;&lt;br /&gt;
Также нужны пояснения&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.1.2 = &lt;br /&gt;
&#039;&#039;&#039;Достоинство этих процедур, с вычислительной точки зрения, состоит в том, что единственная требуемая матрич­ная операция — это повторное умножение матрицы на последо­вательность заполненных векторов; сама матрица не меняется.&#039;&#039;&#039;&lt;br /&gt;
Опять непонятно&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.3 = &lt;br /&gt;
Почему вычислительное ядро только последовательной версии?&lt;br /&gt;
Вычислительное ядро (computational kernel) алгоритма - это часть алгоритма, на которую приходится основное время его работы.&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.4 = &lt;br /&gt;
Наверное, вопрос в том, что алгоритм делает помимо запуска вычислительных ядер?&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.5 = &lt;br /&gt;
Как была выбрана форма хранения матрицы? Это нужно прокомментировать&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.7 = &lt;br /&gt;
Правильно я понимаю, что на рисунке изображено вычисление всего произведения матрицы на вектор? Аналогичные блоки для разных строк. А разве не должен быть рисунок, изображающий ядро (то есть произведение одной строки на вектор)? &lt;br /&gt;
(я не уверен, поэтому спрашиваю. Возможно, это как-то надо лучше подписать)&lt;br /&gt;
&lt;br /&gt;
__&lt;br /&gt;
&lt;br /&gt;
Нам показалось верным отобразить на рисунке именно параллельную версию, на которой будет видно как и произведение одной строки на вектор, так и вычисление всех элементов. Как следует из определения [[глоссарий#Граф алгоритма|графа алгоритма]], он должен давать удобное представление не только ядра, но и позволять рассмотреть алгоритм с параллельной точки зрения.  Внесли небольшое пояснение для рисунка.&lt;br /&gt;
&lt;br /&gt;
= Пункт 2.4 = &lt;br /&gt;
Пока пустой?&lt;br /&gt;
&lt;br /&gt;
__&lt;br /&gt;
&lt;br /&gt;
Поправили&lt;/div&gt;</summary>
		<author><name>Dan</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%D1%86%D1%8B:Trrufina&amp;diff=17886</id>
		<title>Обсуждение участницы:Trrufina</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%D1%86%D1%8B:Trrufina&amp;diff=17886"/>
		<updated>2016-11-17T11:18:35Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Хорошая работа. Один маленький вопрос&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.2 =&lt;br /&gt;
Наиболее удобный CSR. Почему?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
И, конечно, хорошо бы действительно пересчитать на однородном кластере, сделать соответствующие диаграммы, приложить код (на algowiki есть git-репозиторий).&lt;br /&gt;
Обратитесь к организаторам, может быть, все это возможно устроить?&lt;/div&gt;</summary>
		<author><name>Dan</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:Lexaloris&amp;diff=17885</id>
		<title>Обсуждение участника:Lexaloris</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:Lexaloris&amp;diff=17885"/>
		<updated>2016-11-17T11:17:13Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основной вопрос. Ядро это все-таки умножение матрицы или строки матрицы? Соответственно под это нужно подстраивать и остальной текст, потому что можно понять и так, и так.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 2.4 =&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 14:17, 17 ноября 2016 (MSK) необходимо доработать:&lt;br /&gt;
&lt;br /&gt;
Требования были такие: &lt;br /&gt;
- Реализация: полностью собственная или обращение к библиотечной функции (Intel MKL, PETSc, FFTW, ScaLAPACK). В любом случае, текст исследуемой программы должен быть представлен в отчете. &lt;br /&gt;
- Компьютерная платформа может быть любой (Ломоносов, BlueGene или что-то иное). Описание компьютерной платформы должно быть в отчете. &lt;br /&gt;
- Должен быть представлен график сильной масштабируемости (зависимости производительности от числа процессов; если при этом&lt;br /&gt;
ещё и зависимость от размера задачи - это только в плюс). График должен выглядеть пристойно и понятно, оси и единицы измерения должны быть подписаны. К графику обязательно должны быть словесные пояснения! Требовалось подобрать такие размеры задачи и числа процессоров, чтобы отразить на графике характерные точки, описывающие свойства алгоритма и программы.&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:Lexaloris/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B6%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%BD%D0%B0_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80&amp;diff=17884</id>
		<title>Участник:Lexaloris/Умножение разреженной матрицы на вектор</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%D0%BA:Lexaloris/%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B6%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%BD%D0%B0_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80&amp;diff=17884"/>
		<updated>2016-11-17T11:16:34Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Умножение разреженной матрицы на вектор&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(k)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;k + m&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Авторы страницы:&#039;&#039;&#039; [[Участник:Lexaloris|A.Д. Новоселов]] и [[Участник:kochet|П.А. Кочетков]]&lt;br /&gt;
&lt;br /&gt;
Кочетков Павел ответственен за программную реализацию алгоритма, Новоселов Алексей ответственен за оформление статьи. &lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&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;. Эта&lt;br /&gt;
схема предъявляет минимальные требования к памяти и в то же время оказывается очень удобной для умножения разреженной матрицы на вектор.&lt;br /&gt;
Например, рассмотрим формат хранения разряженной матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
[[File:RRCOMatrix.png]]&lt;br /&gt;
&lt;br /&gt;
Значения нену­левых элементов матрицы и соответствующие столбцовые индексы хранятся в этой схеме по строкам в двух массивах &amp;lt;math&amp;gt;AN&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JA&amp;lt;/math&amp;gt; соответственно. Используется также массив указателей &amp;lt;math&amp;gt;IA&amp;lt;/math&amp;gt;, отмечающих позиции массивов &amp;lt;math&amp;gt;AN&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;JA&amp;lt;/math&amp;gt;, с которых начинается описание очередной строки. Дополнительная компо­нента в &amp;lt;math&amp;gt;IA&amp;lt;/math&amp;gt; содержит указатель первой свободной позиции в &amp;lt;math&amp;gt;JA&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;AN&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; представляется в виде:&lt;br /&gt;
&lt;br /&gt;
   IA = [ 1 4 4 6 ]&lt;br /&gt;
   JA = [ 3 4 8 6 8 ]&lt;br /&gt;
   AN = [ 1 3 5 7 1 ]&lt;br /&gt;
&lt;br /&gt;
Данный способ представления называют &#039;&#039;полным&#039;&#039;, поскольку представлена вся матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;, и &#039;&#039;упорядоченным&#039;&#039;, поскольку эле­менты каждой строки хранятся в соответствии с возрастанием столбцовых индексов. Таким образом, это строчное представление, полное и упорядоченное, или сокращенно &#039;&#039;&#039;(RR (С) О)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Неупорядоченное представление ====&lt;br /&gt;
&lt;br /&gt;
Представления разреженных матриц необязательно должны быть упорядочены в том смысле, что, хотя упорядоченность строк поддерживается, внутри каждой строки элементы могут храниться в произвольном порядке. Для матрицы А нашего примера вполне можно было бы использовать и строчное представление, полное, но &#039;&#039;неупорядоченное&#039;&#039; &#039;&#039;&#039;(RR (С) U )&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Неупорядоченное представление &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
   IA = [ 1 4 4 6 ]&lt;br /&gt;
   JA = [ 8 3 4 8 6 ]&lt;br /&gt;
   AN = [ 5 1 3 1 7 ]&lt;br /&gt;
&lt;br /&gt;
Неупорядоченные представления могут быть очень удобны. Результаты большинства матричных операций получаются не­ упорядоченными, и упорядочение их стоило бы больших затрат машинного времени. В то же время, за немногими исключениями, алгоритмы для разреженных матриц не требуют, чтобы представления были упорядоченными.&lt;br /&gt;
&lt;br /&gt;
=== Умножение разреженной матрицы на вектор ===&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; — число строк матрицы. &lt;br /&gt;
Для каждой ее строки &amp;lt;math&amp;gt;I&amp;lt;/math&amp;gt; матрицы мы находим с помощью &amp;lt;math&amp;gt;IA&amp;lt;/math&amp;gt; значения первой &amp;lt;math&amp;gt;IAA&amp;lt;/math&amp;gt; и последней &amp;lt;math&amp;gt;IAB&amp;lt;/math&amp;gt; позиций, занимаемых элементами строки &amp;lt;math&amp;gt;I&amp;lt;/math&amp;gt; в массивах &amp;lt;math&amp;gt;JA&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;AN&amp;lt;/math&amp;gt;. Затем, чтобы вычислить скалярное произведение строки &amp;lt;math&amp;gt;I&amp;lt;/math&amp;gt; и вектора &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;, мы просто просматриваем &amp;lt;math&amp;gt;JA&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;AN&amp;lt;/math&amp;gt; на отрезке от &amp;lt;math&amp;gt;IAA&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;IAB&amp;lt;/math&amp;gt;:&lt;br /&gt;
каждое значение, хранимое в &amp;lt;math&amp;gt;JA&amp;lt;/math&amp;gt;, есть столбцовый индекс и используется для извлечения из массива &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; элемента, который должен быть умножен на соответствующее число из &amp;lt;math&amp;gt;AN&amp;lt;/math&amp;gt;. Результат каж­дого умножения прибавляется к &amp;lt;math&amp;gt;C(I)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;IA, JA, AN&amp;lt;/math&amp;gt; - заданная матрица в форме &#039;&#039;&#039;(RR (С) U)&#039;&#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; - заданный заполненный вектор;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; - число строк матрицы.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039; &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; вектор-произведение размерности &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Формулы метода:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; IAA_{i} = IA(i), \quad i \in [1, N], \\&lt;br /&gt;
&amp;amp; IAB_{i} = IA(i + 1) - 1, \quad i \in [1, N], \\&lt;br /&gt;
&amp;amp; c_{i} = \sum\limits_{j = IAA_{i}}^{IAB_{i}} AN(j)B(JA(j)), \quad i \in [1, N] \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вычислительным ядром, т.е. той частью алгоритма, на которую приходится основное время его работы, является вычисление значения &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го элемента &amp;lt;math&amp;gt;c_{i}&amp;lt;/math&amp;gt; вектора-произведения, т.е произведения строки &amp;lt;math&amp;gt;I&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и вектора &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; по формуле:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; c_{i} = \sum\limits_{j = IAA_{i}}^{IAB_{i}} AN(j)B(JA(j)), \quad i \in [1, N] \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Основу алгоритма составляет вычисление значения &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го элемента &amp;lt;math&amp;gt;c_{i}&amp;lt;/math&amp;gt; вектора-произведения:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; c_{i} = \sum\limits_{j = IAA_{i}}^{IAB_{i}} AN(j)B(JA(j)), \quad i \in [1, N] \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&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;math&amp;gt;i&amp;lt;/math&amp;gt; от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; по нарастанию выполняются:&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt; c_{i} = 0; IAA = IA(i); IAB = IA(i + 1 ) - 1 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После этого, если &amp;lt;math&amp;gt;(IAB \le IAA)&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
2. Для всех &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; от &amp;lt;math&amp;gt;IAA&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;IAB&amp;lt;/math&amp;gt; выполняется: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;c_{i} = \sum\limits_{j = IAA_{i}}^{IAB_{i}} AN(j)B(JA(j))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Псевдокод алгоритма: &lt;br /&gt;
&lt;br /&gt;
    FOR I = 1, N                          (1)&lt;br /&gt;
       U = 0.                             (2) &lt;br /&gt;
       IAA = IA(I)                        (3) &lt;br /&gt;
       IAB = IA(I + 1 ) - 1               (4)&lt;br /&gt;
       IF NOT(IAB.LT.IAA)                 (5)&lt;br /&gt;
           FOR J = IAA, IAB               (6)&lt;br /&gt;
           C(I) = U + AN(J)*B(JA(J))      (7)&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Для всего алгоритма потребуется выполнить &amp;lt;math&amp;gt;O(k)&amp;lt;/math&amp;gt; операций, как в строке стр.7 псевдокода алгоритма ([[#Схема реализации последовательного алгоритма|п.1.5]]), где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; - число ненулевых эле­ментов матрицы.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
На рисунке 1 изображен информационный граф алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:InfoGrafMatrixRRCUandVextor.jpg|thumb|center|1200px|Рисунок 1. Информационный граф алгоритма.]]&lt;br /&gt;
 &lt;br /&gt;
По оси &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; для отдельной строки &amp;lt;math&amp;gt;I&amp;lt;/math&amp;gt; матрицы отложены в пределах первой &amp;lt;math&amp;gt;IAA&amp;lt;/math&amp;gt; и последней &amp;lt;math&amp;gt;IAB&amp;lt;/math&amp;gt; позиций ненулевых элементов значения &amp;lt;math&amp;gt;AN&amp;lt;/math&amp;gt; и соответствуюие им по столбцовомым индексам, хранимимым в &amp;lt;math&amp;gt;JA&amp;lt;/math&amp;gt;, значения &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; элементов. &lt;br /&gt;
Пары этих значений обозначены желтыми квадратиками &amp;lt;math&amp;gt;(in)&amp;lt;/math&amp;gt;. Значения in попарно скалярно перемножаются (зеленый кружочек) и суммируются (синий кружочек) в результат значения элемента вектора-произведения &amp;lt;math&amp;gt;c_{i}&amp;lt;/math&amp;gt;, т.е &amp;lt;math&amp;gt;out&amp;lt;/math&amp;gt;(красный квадратик) с строковым индексом, соответствующем номеру строки матрицы.&lt;br /&gt;
&lt;br /&gt;
По оси &amp;lt;math&amp;gt;Y&amp;lt;/math&amp;gt; отложена схема вычисление значения каждого элемента вектора-произведения для каждой строки матрицы.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм обладает возможностью выполняться параллельно, что позволяет значительно ускорить вычисления.&lt;br /&gt;
Вычисление значения каждого элемента вектора-произведения для каждой строки матрицы и элемента вектора &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно проводить на отдельных процессорах. &lt;br /&gt;
Максимальная эффективность вычислений достигается при наличии не менее, чем &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; процессоров, т.е отдельный процессор на вычисление значения каждого элемента вектора-произведения. На процессоре выполняется &amp;lt;math&amp;gt;k(i)&amp;lt;/math&amp;gt; последовательных операций умножения и сложения. Поэтому число ярусов для &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ого процессора равно &amp;lt;math&amp;gt;k(i)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для параллельного выполнения алгоритма требуется:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; ярусов умножений и сложений,&lt;br /&gt;
* в каждом из ярусов &amp;lt;math&amp;gt;k &amp;lt;&amp;lt; m&amp;lt;/math&amp;gt; операций.&lt;br /&gt;
&lt;br /&gt;
При классификации по высоте ЯПФ, алгоритм имеет линейную сложность. При классификации по высоте ЯПФ также линейную.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;IA, JA, AN&amp;lt;/math&amp;gt; - заданная матрица в форме &#039;&#039;&#039;(RR (С) U)&#039;&#039;&#039; c &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; ненулевыми элементами и &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; строками, &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; столбцами;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; - заданный заполненный вектор c &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; элементами;&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;k + m&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; вектор-произведение размерности &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;N&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;
* SparseLib++[http://math.nist.gov/sparselib++/] &lt;br /&gt;
* cuSPARSE [http://docs.nvidia.com/cuda/cusparse/]&lt;br /&gt;
* uBLAS [http://www.boost.org/doc/libs/1_62_0/libs/numeric/ublas/doc/]&lt;br /&gt;
* Intel MKL [https://software.intel.com/en-us/intel-mkl]&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&lt;br /&gt;
* [1] С. Писсанецки. Технология разреженных матриц. Изд. Мир, 1988.&lt;br /&gt;
* [2] В. В. Воеводин, Вл.В. Воеводин. Параллельные вычисления. – СПб.: БХВ - Петербург, 2002.&lt;/div&gt;</summary>
		<author><name>Dan</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:Lvs&amp;diff=17883</id>
		<title>Обсуждение участника:Lvs</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:Lvs&amp;diff=17883"/>
		<updated>2016-11-17T11:16:17Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Пункт 1.2 =&lt;br /&gt;
Это определение пространства Крылова?&lt;br /&gt;
Не совсем понятно описание алгоритма, если не знаешь, о чем речь&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.3 =&lt;br /&gt;
Он достаточно длинный. Посмотрите описания готовых алгоритмов на алговики. Псевдокод здесь не читается, ядро должно лучше восприниматься&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.4 =&lt;br /&gt;
Если макроструктура это указанные 3 пункта, то нужно пояснить, почему именно пункт 1 является ядром. Он самый ресурсоемкий?&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.7 =&lt;br /&gt;
Почему это основной ресурс. Это основная операция в алгоритме? Требуются пояснения&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 2.4 =&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 14:16, 17 ноября 2016 (MSK) необходимо доработать:&lt;br /&gt;
&lt;br /&gt;
Требования были такие: &lt;br /&gt;
- Реализация: полностью собственная или обращение к библиотечной функции (Intel MKL, PETSc, FFTW, ScaLAPACK). В любом случае, текст исследуемой программы должен быть представлен в отчете. &lt;br /&gt;
- Компьютерная платформа может быть любой (Ломоносов, BlueGene или что-то иное). Описание компьютерной платформы должно быть в отчете. &lt;br /&gt;
- Должен быть представлен график сильной масштабируемости (зависимости производительности от числа процессов; если при этом&lt;br /&gt;
ещё и зависимость от размера задачи - это только в плюс). График должен выглядеть пристойно и понятно, оси и единицы измерения должны быть подписаны. К графику обязательно должны быть словесные пояснения! Требовалось подобрать такие размеры задачи и числа процессоров, чтобы отразить на графике характерные точки, описывающие свойства алгоритма и программы.&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:Lvs/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES&amp;diff=17882</id>
		<title>Участник:Lvs/Итерационный метод решения системы линейных алгебраических уравнений GMRES</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%D0%BA:Lvs/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES&amp;diff=17882"/>
		<updated>2016-11-17T11:15:14Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Итерационный метод решения системы линейных алгебраических уравнений GMRES (или обобщенный метод минимальных невязок) используется для решения систем линейных алгебраических уравнений с заданной точностью приближения. Метод основан на процессе Арнольди, посредст­вом которого матрица СЛАУ приводится к (верхней) хессенберговой форме.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Дана система линейных алгебраических уравнений &amp;lt;math&amp;gt;Ax = b&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; - квадратная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляется последовательность приближённых решений уравнения &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt;, которая сходится к точному решению уравнения &amp;lt;math&amp;gt;x^*&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Подпространство Крылова размерности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;, порожденное вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; и матрицей &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; – линейное пространство&lt;br /&gt;
&amp;lt;math&amp;gt;K_m(A, v)&amp;lt;/math&amp;gt;, являющееся линейной оболочкой векторов &amp;lt;math&amp;gt;b, Ab, A^2b, ..., A^{m-1}b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Приближённое решение считается по формуле &amp;lt;math&amp;gt; x_m = Q_my_m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_m&amp;lt;/math&amp;gt; - матрица размера &amp;lt;math&amp;gt;n \times m&amp;lt;/math&amp;gt;, составленная из векторов ортонормированного базиса пространства &amp;lt;math&amp;gt;K_m(A, v)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;y_m \in \mathbb{R}^m&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итоговым считается решение, минимизирующее норму невязки (&amp;lt;math&amp;gt;||r||_2 = ||b - Ax_m||_2&amp;lt;/math&amp;gt;) с заданной точностью.&lt;br /&gt;
&lt;br /&gt;
Для вычисления векторов ортонормированного базиса используется алгоритм Арнольди:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
q[1] = b/||b||&lt;br /&gt;
for j = 1, ..., n-1 do&lt;br /&gt;
    z = Aq[j]; //очередной вектор&lt;br /&gt;
    for i = 1,..., j do&lt;br /&gt;
        h[i][j] = (z, q[i]);&lt;br /&gt;
        z = z − h[i][j]q[i];&lt;br /&gt;
    end i&lt;br /&gt;
    h[j+1][j] = ||z||;&lt;br /&gt;
    if (h[j+1][j] == 0) break;&lt;br /&gt;
    q[j+1] = z/h[j+1][j];&lt;br /&gt;
end j&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Сложность алгоритма &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На каждом шаге алгоритма получаются векторы &amp;lt;math&amp;gt;q_1, q_2, ..., q_m&amp;lt;/math&amp;gt;, являющиеся ортонормированным базисом Крыловского пространства &amp;lt;math&amp;gt;K_m(A, b)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Значения &amp;lt;math&amp;gt;h_{i,j}&amp;lt;/math&amp;gt; образуют верхнюю матрицу Хессенберга (обозначим как &amp;lt;math&amp;gt;H_m&amp;lt;/math&amp;gt;, размерность &amp;lt;math&amp;gt;m+1 \times m&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_k = \begin{bmatrix}h_{11} &amp;amp; h_{12} &amp;amp; h_{13} &amp;amp;... &amp;amp; h_{1m-1} &amp;amp; h_{1m} \\ h_{21} &amp;amp; h_{22} &amp;amp; h_{23} &amp;amp; ... &amp;amp; h_{2m-1} &amp;amp; h_{2m} \\ 0 &amp;amp; h_{32} &amp;amp; h_{33} &amp;amp;...&amp;amp; h_{3m-1} &amp;amp; h_{3m} \\ ... &amp;amp; ... &amp;amp; ... &amp;amp; ... &amp;amp; ... &amp;amp; ... \\ 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; ... &amp;amp; h_{m m-1} &amp;amp; h_{mm} \\0 &amp;amp; 0 &amp;amp; 0 &amp;amp; ... &amp;amp; 0 &amp;amp; h_{m+1 m}\end{bmatrix}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вектор невязки задан уравнением &amp;lt;math&amp;gt;r_m = H_my_m - ||b - Ax_0||e_1&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt; - вектор начального приближения. Минимизация второй нормы вектора невязки представляет из себя решение линейной задачи минимальных квадратов размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Приближённое решение вычисляется по формуле &amp;lt;math&amp;gt; x_m = Q_my_m&amp;lt;/math&amp;gt; после нахождения соответствующего значения минимизирующего вторую невязку вектора. Сложность вычислений &amp;lt;math&amp;gt;O(nm)&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;
&amp;lt;source&amp;gt;&lt;br /&gt;
    Вычислить ортонормированный базис размера m&lt;br /&gt;
    Вычислить минимальное приближение&lt;br /&gt;
    if (приближение &amp;lt; заданная точность)&lt;br /&gt;
        Вычислить результат&lt;br /&gt;
        return;&lt;br /&gt;
    else&lt;br /&gt;
        Повторить для m = m+1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность вычислений собственных векторов на каждом шаге - &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, но может уменьшиться до &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; при более разреженной матрице.&lt;br /&gt;
&lt;br /&gt;
Сложность решения задачи минимальных квадратов &amp;lt;math&amp;gt;O(m^2)&amp;lt;/math&amp;gt;, но при последовательном выполнении алгоритма можно понизить сложность до &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;gt; путём использования подсчитанных на прошлых итерациях значений.&lt;br /&gt;
&lt;br /&gt;
Сложность вычисления решения &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;, поэтому его целесообразно вычислять только в конце.&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
Основной ресурс параллелизма - умножение матрицы на вектор. Для этой операции информационный граф представлен на рисунке.&lt;br /&gt;
&lt;br /&gt;
[[file:GraphLvs2FM.jpg|thumb|center|700px|Рис.1. Информационный граф умножения матрицы на вектор]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
# Параллельное умножение матрицы на вектор выполняется в &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; ярусов умножений и сложений.&lt;br /&gt;
# Шаги алгоритма Арнольди выполняются строго последовательно, однако последующее нахождение невязки можно выполнять параллельно с запуском следующего шага алгоритма.&lt;br /&gt;
# Сложность решения задачи минимальных квадратов зависит от используемого алгоритма. В отличие от последовательного метода данные, полученные на прошлых шагах здесь использовать нельзя.&lt;br /&gt;
# Вычисление результата выполняется один раз, его можно выполнить параллельно в &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; ярусов умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; Матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;, вектор &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;, точность &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Объём: &amp;lt;math&amp;gt;n^2 + n + 1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Вектор &amp;lt;math&amp;gt;x_m&amp;lt;/math&amp;gt;. Объём: &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Теоретически на каждой итерации алгоритма сложность вычислений составляет &amp;lt;math&amp;gt;n + X&amp;lt;/math&amp;gt; операций умножения, где &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - сложность алгоритма для решения задачи минимальных квадратов. Таким образом в худшем случае сложность будет примерно равна &amp;lt;math&amp;gt;n^2 + X*n + n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Несмотря на то, что в теории итерации алгоритма можно выполнять параллельно после выполнения алгоритма Арнольди, на практике необходимая точность может быть достигнута раньше чем на n-й итерации, что потребует какого-нибудь способа прервать последующие итерации. Для избегания лишних вычисление возможно оптимально оставить эту часть последовательной.&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Реализации алгоритма GMRES присутствуют во многих программных продуктах как части стандартных библиотек, например Matlab или DEFORM3D. Также существую отдельные библиотеки, например MGMRES для языка С++.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Тыртышников Е. Е. Методы численного анализа — М., Академия, 2007.&lt;br /&gt;
&lt;br /&gt;
[2] М. Дана, А. Г. Зыков, Х. Д. Икрамов Метод минимальных невязок для специального класса линейных систем с нормальными матрицами коэффициентов - Ж. вычисл. матем. и матем. физ., 2005, том 45, номер 11&lt;/div&gt;</summary>
		<author><name>Dan</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:Obirvalger&amp;diff=17881</id>
		<title>Обсуждение участника:Obirvalger</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:Obirvalger&amp;diff=17881"/>
		<updated>2016-11-17T11:14:56Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Пункт 2.4 =&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 14:14, 17 ноября 2016 (MSK) необходимо переработать:&lt;br /&gt;
&lt;br /&gt;
Требования были такие: &lt;br /&gt;
- Реализация: полностью собственная или обращение к библиотечной функции (Intel MKL, PETSc, FFTW, ScaLAPACK). В любом случае, текст исследуемой программы должен быть представлен в отчете. &lt;br /&gt;
- Компьютерная платформа может быть любой (Ломоносов, BlueGene или что-то иное). Описание компьютерной платформы должно быть в отчете. &lt;br /&gt;
- Должен быть представлен график сильной масштабируемости (зависимости производительности от числа процессов; если при этом&lt;br /&gt;
ещё и зависимость от размера задачи - это только в плюс). График должен выглядеть пристойно и понятно, оси и единицы измерения должны быть подписаны. К графику обязательно должны быть словесные пояснения! Требовалось подобрать такие размеры задачи и числа процессоров, чтобы отразить на графике характерные точки, описывающие свойства алгоритма и программы.&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:Obirvalger/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D0%B2%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%BE%D1%80%D0%B4%D0%B8%D0%BD%D0%B0%D1%82%D0%BD%D0%BE%D0%B9_%D0%B1%D0%B8%D1%81%D0%B5%D0%BA%D1%86%D0%B8%D0%B8&amp;diff=17880</id>
		<title>Участник:Obirvalger/Метод рекурсивной координатной бисекции</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%D0%BA:Obirvalger/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D0%B2%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%BE%D1%80%D0%B4%D0%B8%D0%BD%D0%B0%D1%82%D0%BD%D0%BE%D0%B9_%D0%B1%D0%B8%D1%81%D0%B5%D0%BA%D1%86%D0%B8%D0%B8&amp;diff=17880"/>
		<updated>2016-11-17T11:14:31Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Рекурсивная координатная бисекция&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n \log_2{n} \log_2{k})&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;\log_2{k}&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;N|V| + |G|&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы: [[Участник:Obirvalger|Гордеев Михаил]] (разделы 1.4, 1.6, 1.8, 1.10), [[Участник:KolmakovEA|Колмаков Евгений]] (разделы 1.1, 1.2, 1.3, 1.5, 1.7, 1.9, 2.7).&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;&#039;&#039; является одним из методов, применяемых для декомпозиции графов &amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2012. – 328 с., илл. – (Серия «Суперкомпьютерное образование»), ISBN 978-5-211-06382-2 URL: http://lira.imamod.ru/ITTPMOPS/&amp;lt;/ref&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;
Метод рекурсивной координатной бисекции является частным случаем более общего &#039;&#039;&#039;метода рекурсивной бисекции&#039;&#039;&#039;. В этом методе сетка последовательно за &amp;lt;math&amp;gt;k-1&amp;lt;/math&amp;gt; шаг делится на &amp;lt;math&amp;gt;k&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;
* отсортированное множество разбивается на две части, то есть указывается индекс &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; такой, что в первую часть попадают вершины с номерами меньшими либо равными &amp;lt;math&amp;gt;i&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;
Исходные данные: граф &amp;lt;math&amp;gt;G = (V, E) &amp;lt;/math&amp;gt;, вложенный в &amp;lt;math&amp;gt;\mathbb{R}^N&amp;lt;/math&amp;gt; (то есть каждая вершина этого графа - это точка в &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; мерном пространстве), и число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; доменов, на которое нужно разбить граф.&lt;br /&gt;
Под &#039;&#039;декомпозицией&#039;&#039; графа на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; доменов понимается разбиение множества вершин &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; подмножеств &amp;lt;math&amp;gt;V_1, \dots, V_k&amp;lt;/math&amp;gt; таких, что &lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;V = \bigcup_{i = 1}^k V_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;V_i \cap V_j = \varnothing&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;i \neq j&amp;lt;/math&amp;gt;.&amp;lt;/center&amp;gt; &lt;br /&gt;
&lt;br /&gt;
С каждым доменом можно связать порождённый им подграф &amp;lt;math&amp;gt;G(V_i) = (V_i, E_i)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;E_i \subseteq E&amp;lt;/math&amp;gt; - множество рёбер, оба конца которых принадлежат домену.&lt;br /&gt;
&lt;br /&gt;
Задача заключается в нахождении декомпозиции &amp;lt;math&amp;gt;V_1, \dots, V_k&amp;lt;/math&amp;gt;, доставляющей минимум некоторого функционала (см. [[#Критерии декомпозиции| соответствующий пункт]]), например, числа разрезанных рёбер &amp;lt;math&amp;gt;E_{\mbox{cut}} = |\{(u, v) \in E \mid u \in V_i, v \in V_j, i \neq j\}| = |E| - \sum_{i = 1}^k |E_i|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дадим формальное описание алгоритма. Как уже упоминалось, метод основан на алгоритме рекурсивной бисекции, поэтому представляет собой рекурсивную процедуру, на вход которой поступает граф  &amp;lt;math&amp;gt;G = (V, E) &amp;lt;/math&amp;gt; и число доменов &amp;lt;math&amp;gt;k&amp;lt;/math&amp;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;math&amp;gt;m^* \in \{1, \dots, N\}&amp;lt;/math&amp;gt;;&lt;br /&gt;
** в случае максимизации протяженности: для каждой оси &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; вычисляется величина &amp;lt;math&amp;gt;l_m = \max_{v \in V} v_m - \min_{v \in V} v_m&amp;lt;/math&amp;gt;, и выбирается ось &amp;lt;math&amp;gt;m^* = \arg\max_{m \in \{1, \dots, N\}} l_m&amp;lt;/math&amp;gt;;&lt;br /&gt;
** в случае минимизации числа разрезанных ребер: вершины упорядочиваются вдоль каждой из осей, для каждой оси вычисляется величина &amp;lt;math&amp;gt;E^m_{\mbox{cut}}&amp;lt;/math&amp;gt;, равная числу разрезанных ребер при разбиении вдоль данной оси, и выбирается ось &amp;lt;math&amp;gt;m^* = \arg\max_{m \in \{1, \dots, N\}} E^m_{\mbox{cut}}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* множество вершин сортируется по возрастанию координаты с номером &amp;lt;math&amp;gt;m^*&amp;lt;/math&amp;gt;;&lt;br /&gt;
* отсортированный массив вершин делится на две (непрерывные) части в соответствии с желаемым числом вершин в каждой из частей; &lt;br /&gt;
**как правило, выбирается индекс  &amp;lt;math&amp;gt;i = \lfloor\frac{k+1}{2k}\rfloor \cdot |V|&amp;lt;/math&amp;gt;, соответствующий примерно равному разделению текущего графа на части;&lt;br /&gt;
* первая часть состоит из вершин &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; с индексами &amp;lt;math&amp;gt;j \leqslant i&amp;lt;/math&amp;gt;, вторая - с индексами &amp;lt;math&amp;gt;j &amp;gt; i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро алгоритма составляют сортировки массива вершин сетки по выбранной координате при каждом из &amp;lt;math&amp;gt;k - 1&amp;lt;/math&amp;gt; вызовов процедуры бисекции. &lt;br /&gt;
&lt;br /&gt;
Также, в зависимости от критерия выбора координатной оси, требуются дополнительные вычисления:&lt;br /&gt;
*В случае максимизации протяженности при каждом вызове требуется вычисление величины &amp;lt;math&amp;gt;l_m&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В случае минимизации числа разрезанных ребер при каждом вызове требуется сортировка по каждой из координат (таким образом, при каждом разбиении осуществляется &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; сортировок).&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Как записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть метода составляют множественные (всего &amp;lt;math&amp;gt;k-1&amp;lt;/math&amp;gt;) сортировки (функция argsort в коде в [[#Схема реализации последовательного алгоритма |следующем разделе]]).&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Опишем последовательную реализацию метода рекурсивной координатной бисекции, где выбор оси производится исходя из условия максимизации протяженности вдоль этой оси. Ниже представлен код данного алгоритма на языке Python 3.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Переменная для хранения результата работы алгоритма&lt;br /&gt;
partition = []&lt;br /&gt;
&lt;br /&gt;
# V - numpy.ndarray размера |V| x N, k - число доменов&lt;br /&gt;
def recursive_bisection(V, k):&lt;br /&gt;
&lt;br /&gt;
    global partition&lt;br /&gt;
&lt;br /&gt;
    # Если текущая часть графа есть домен, добавляем ее к результату разбиения&lt;br /&gt;
    if (k &amp;lt;= 1):&lt;br /&gt;
        partition.append(V)&lt;br /&gt;
        return &lt;br /&gt;
&lt;br /&gt;
    # Вычисляем количество доменов в каждой из частей&lt;br /&gt;
    k1 = (k + 1) / 2&lt;br /&gt;
    k2 = k - k1&lt;br /&gt;
    &lt;br /&gt;
    # Производим разбиение  &lt;br /&gt;
    V1, V2 = bisect(V, k)&lt;br /&gt;
&lt;br /&gt;
    # Рекурсивно разбиваем каждую из частей&lt;br /&gt;
    recursive_bisect(V1, k1) &lt;br /&gt;
    recursive_bisect(V2, k2)&lt;br /&gt;
    &lt;br /&gt;
def bisect(V, k):&lt;br /&gt;
    # Вычисляем координату с наибольшей протяженностью&lt;br /&gt;
    t = V.max(axis=0) - V.min(axis=0)&lt;br /&gt;
    m = t.argmax()&lt;br /&gt;
    &lt;br /&gt;
    # Сортируем вершины по координате с номером m&lt;br /&gt;
    V_sorted = V[V[:, m].argsort()]&lt;br /&gt;
&lt;br /&gt;
    # Вычисляем индекс для разбиения в соответствии с числом доменов&lt;br /&gt;
    ind = (k + 1) * V.shape[0] // (2 * k)&lt;br /&gt;
&lt;br /&gt;
    return V_sorted[:ind, :], V_sorted[ind:, :]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведённый код предназначен для более подробного описания основных шагов в алгоритме, представляет собой лишь схему и не является максимально эффективным. Это сделано для того, чтобы код был более наглядным. В более эффективной реализации, например, вместо создания массивов в процедуре bisect можно везде оперировать только индексами.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Обозначим через &amp;lt;math&amp;gt;D_k(n)&amp;lt;/math&amp;gt; сложность алгоритма рекурсивной координатной бисекции для декомпозиции графа с &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; вершинами на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; доменов.&lt;br /&gt;
&lt;br /&gt;
Определим величину &amp;lt;math&amp;gt;D(n) = D_n(n)&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;D(n)&amp;lt;/math&amp;gt; имеет место следующее рекуррентное равенство:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{l}&lt;br /&gt;
D(n) = S(n) + 2D(\frac{n}{2}) \\&lt;br /&gt;
D(1) = S(1) = 0. \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;S(n)&amp;lt;/math&amp;gt; - это сложность алгоритма сортировки массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;S(n) = O(n\log_2{n})&amp;lt;/math&amp;gt; (например, для сортировки слиянием), тогда по теореме о рекуррентных соотношениях &amp;lt;ref&amp;gt;https://ru.wikipedia.org/wiki/Основная_теорема_о_рекуррентных_соотношениях&amp;lt;/ref&amp;gt; для произвольного положительного &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; имеет место оценка &amp;lt;math&amp;gt;D(n) \lesssim n^{1+\varepsilon}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Величину &amp;lt;math&amp;gt;D_k(n)&amp;lt;/math&amp;gt; можно явно посчитать по формуле &amp;lt;math&amp;gt;\sum\limits_{i=0}^{\lceil\log_2{k}\rceil}2^i S(\frac{n}{2^i})&amp;lt;/math&amp;gt;. Если использовать сортировку со сложностью &amp;lt;math&amp;gt;S(n) = O(n\log_2{n})&amp;lt;/math&amp;gt;, то &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;D_k(n) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;O(\sum\limits_{i=0}^{\lceil\log_2{k}\rceil}2^i \frac{n}{2^i} \log_2{\frac{n}{2^i}}) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;O(n\log_2(\prod\limits_{i=0}^{\lceil\log_2{k}\rceil}\frac{n}{2^i})) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;O(n\log_2{\frac{n^{\log_2{k}}}{2^\frac{\log_2{k}(\log_2{k}+1))}{2}}}) =&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; O(n(\log_2{n}\log_2{k} - \frac{\log^2_2{k}}{2})) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;O(n\log_2{n}\log_2{k})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Под операцией в данном пункте будем понимать макрооперацию сортировки. Передача данных происходит после разбиения множества вершин на две части.&lt;br /&gt;
Таким образом, информационный граф представляет из себя бинарное дерево с &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; листьями. На рисунке ниже приведена часть информационного графа для &amp;lt;math&amp;gt;k = 16&amp;lt;/math&amp;gt;. Зависимость от числа вершин &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; учитывается в самих узлах дерева. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Файл:Tree_sort.svg|thumb|center|800px|Рисунок 1. Граф алгоритма.]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Высота ярусно-параллельной формы - &amp;lt;math&amp;gt;\log_2{k}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ширина ярусно-параллельной формы - &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если рассматривать более мелкие операции, используемые в процессе сортировки, то глобально информационный граф будет выглядеть также, однако каждый&lt;br /&gt;
узел будет заменён на информационный граф используемого алгоритма сортировки (или &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; таких графов, если используется критерий минимизации числа разрезов).&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Данный алгоритм обладает координатным параллелизмом.&lt;br /&gt;
Для декомпозиции графа с &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; вершинами на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; доменов методом рекурсивной координатной бисекции в параллельном варианте требуется последовательно выполнить &amp;lt;math&amp;gt;\lceil\log_2{k}\rceil&amp;lt;/math&amp;gt; ярусов. На &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе будет выполнятся &amp;lt;math&amp;gt;2^i&amp;lt;/math&amp;gt; операций сортировки. &lt;br /&gt;
Рассмотрим два случая распараллеливания нашего алгоритма:&lt;br /&gt;
* Параллельное выполнение операций на каждом ярусе с использованием последовательного алгоритма сортировки со сложностью &amp;lt;math&amp;gt;O(n\log_2{n})&amp;lt;/math&amp;gt;. &lt;br /&gt;
# На первом шаге один процессор производит сортировку всех вершин, разделяет граф на два подграфа и передает однин из подрафов новому процессору.&lt;br /&gt;
# На &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом шаге каждый из уже получивший свой граф процессор производит сортировку всех вершин, разделяет граф на два подграфа и передает однин из подрафов новому процессору.&lt;br /&gt;
&lt;br /&gt;
Тогда сложность нашего алгоритма равна:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;D_k(n) = O(\sum\limits_{i=0}^{\lceil\log_2{k}\rceil}\frac{n}{2^i} \log_2{\frac{n}{2^i}}) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;n\sum\limits_{i=0}^{\lceil\log_2{k}\rceil}(\frac{\log_2{n}}{2^i} - \frac{i}{2^i}) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;O(n\log_2{n}) - O(n) = O(n\log_2{n})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Параллельное выполнение операций на каждом ярусе с использованием параллельного алгоритма сортировки со сложностью &amp;lt;math&amp;gt;O(\log_2^2{n})&amp;lt;/math&amp;gt;&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Batcher_odd–even_mergesort&amp;lt;/ref&amp;gt;.&lt;br /&gt;
На каждом шаге производится параллельная сортировка вершин и разбиение графа на два подграфа.&lt;br /&gt;
В этом случае &lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt; &lt;br /&gt;
&amp;lt;math&amp;gt;D_k(n) = \sum\limits_{i=0}^{\lceil\log_2{k}\rceil}\log^2_2\frac{n}{2^i} = O(\log^2_2{n}\log_2{k}) = O(\log^3_2{n})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Известно &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Sorting_algorithm&amp;lt;/ref&amp;gt;, что оптимальная параллельная сортировка имеет сложность &amp;lt;math&amp;gt;O(\log_2{n})&amp;lt;/math&amp;gt;. В этом случае  &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;D_k(n) = \sum\limits_{i=0}^{\lceil\log_2{k}\rceil}\log_2\frac{n}{2^i} = O(\log_2{n}\log_2{k})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; граф &amp;lt;math&amp;gt;G = (V, E) &amp;lt;/math&amp;gt;, вложенный в &amp;lt;math&amp;gt;\mathbb{R}^N&amp;lt;/math&amp;gt;, и число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; частей (доменов), на которое нужно разбить граф. Таким образом, помимо матрицы смежности (или любого другого представления графа) для каждой вершины &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; задан набор её координат &amp;lt;math&amp;gt;v = (v_1, \dots, v_N) \in \mathbb{R}^N&amp;lt;/math&amp;gt;, поэтому &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; задаётся массивом &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерных векторов или матрицей размера &amp;lt;math&amp;gt;|V| \times N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;N|V| + |G|&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|G|&amp;lt;/math&amp;gt; - объём данных, представляющих граф &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, который в общем случае зависит от выбранного представления.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; доменов графа &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, задающих его декомпозицию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - для каждого домена достаточно хранить соответствующие вершинам из этого домена индексы строк в матрице, представляющей множество вершин.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов является &#039;&#039;линейным&#039;&#039; (отношение &amp;lt;math&amp;gt;O(n\log{n})&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;O(\log{n}))&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;
Ниже приведен пример реализации последовательного алгоритма на языке C++. Следует отметить, что исходный массив вершин не изменяется, вся работа осуществляется с индексами.&lt;br /&gt;
&amp;lt;source lang = &amp;quot;c++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;algorithm&amp;gt;&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;vector&amp;gt;&lt;br /&gt;
&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;vector&amp;lt;double&amp;gt; &amp;gt; points_matrix;&lt;br /&gt;
vector&amp;lt;vector&amp;lt;int&amp;gt; &amp;gt; graph_partition;&lt;br /&gt;
&lt;br /&gt;
double span(vector&amp;lt;double&amp;gt; &amp;amp;x, vector&amp;lt;int&amp;gt; &amp;amp;idx)&lt;br /&gt;
{ &lt;br /&gt;
    double max_value = x[idx[0]];&lt;br /&gt;
    double min_value = x[idx[0]];&lt;br /&gt;
    &lt;br /&gt;
    for (size_t i = 1; i &amp;lt; idx.size(); i++) {&lt;br /&gt;
        max_value = (x[idx[i]] &amp;gt; max_value) ? x[idx[i]] : max_value;&lt;br /&gt;
        min_value = (x[idx[i]] &amp;lt; min_value) ? x[idx[i]] : min_value; &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return max_value;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
vector&amp;lt;int&amp;gt; bisect(vector&amp;lt;int&amp;gt; &amp;amp;idx)&lt;br /&gt;
{&lt;br /&gt;
    double max_span = 0;&lt;br /&gt;
    double max_ind = 0;&lt;br /&gt;
    &lt;br /&gt;
    // finding coordinate with maximal span&lt;br /&gt;
    for (size_t i = 0; i &amp;lt; points_matrix.size(); i++) {&lt;br /&gt;
        double cur_span = span(points_matrix[i], idx);&lt;br /&gt;
        if (cur_span &amp;gt; max_span) {&lt;br /&gt;
            max_span = cur_span;&lt;br /&gt;
            max_ind = i;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // sorting vertices along this coordinate&lt;br /&gt;
    vector&amp;lt;int&amp;gt; sorted_idx = idx;&lt;br /&gt;
    &lt;br /&gt;
    sort(sorted_idx.begin(), sorted_idx.end(), &lt;br /&gt;
            [&amp;amp;](const int&amp;amp; a, const int&amp;amp; b) {&lt;br /&gt;
                return points_matrix[max_ind][idx[a]] &amp;lt; points_matrix[max_ind][idx[b]];&lt;br /&gt;
            });&lt;br /&gt;
    &lt;br /&gt;
    return sorted_idx;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void recursive_bisection(vector&amp;lt;int&amp;gt; &amp;amp;idx, int k)&lt;br /&gt;
{&lt;br /&gt;
    // adding current domain to partition&lt;br /&gt;
    if (k &amp;lt; 2) {&lt;br /&gt;
        graph_partition.push_back(idx);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    int k1 = (k + 1) / 2;&lt;br /&gt;
    int k2 = k - k1;&lt;br /&gt;
    &lt;br /&gt;
    // bisecting current graph&lt;br /&gt;
    vector&amp;lt;int&amp;gt; sorted_idx1 = bisect(idx);&lt;br /&gt;
    vector&amp;lt;int&amp;gt; sorted_idx2(make_move_iterator(sorted_idx1.begin() + k1 * sorted_idx1.size() / k),&lt;br /&gt;
                    make_move_iterator(sorted_idx1.end()));&lt;br /&gt;
    sorted_idx1.erase(sorted_idx1.begin() + k1 * sorted_idx1.size() / k, sorted_idx1.end());&lt;br /&gt;
    &lt;br /&gt;
    recursive_bisection(sorted_idx1, k1);&lt;br /&gt;
    recursive_bisection(sorted_idx2, k2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    // example: 2x4-mesh &lt;br /&gt;
    points_matrix = {{0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}, {0.0, 1.0, 2.0, 3.0, 0.0, 1.0, 2.0, 3.0}};&lt;br /&gt;
    vector&amp;lt;int&amp;gt; idx = {0, 1, 2, 3, 4, 5, 6, 7};&lt;br /&gt;
    int k = 4;&lt;br /&gt;
&lt;br /&gt;
    recursive_bisection(idx, k);&lt;br /&gt;
    &lt;br /&gt;
    for(size_t i = 0; i &amp;lt; graph_partition.size(); ++i) {&lt;br /&gt;
        for(size_t j = 0; j &amp;lt; graph_partition[i].size(); ++j)&lt;br /&gt;
            cout &amp;lt;&amp;lt; graph_partition[i][j] &amp;lt;&amp;lt; &amp;quot; &amp;quot;;&lt;br /&gt;
        cout &amp;lt;&amp;lt; endl;&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;
В статье &amp;lt;ref&amp;gt;http://glaros.dtc.umn.edu/gkhome/node/112&amp;lt;/ref&amp;gt; приводятся результаты работы алгоритма декомпозиции графов из пакета ParMETIS. В таблице ниже приведено время работы алгоритма в зависимости от числа вершин в графе и используемого числа процессоров. Рассмотравились следующие графы:&lt;br /&gt;
граф mrng2 с 1 миллионом вершин, mrng3 с 4 миллионами и граф mrgn4 с 7.5 миллионами вершин.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Время выполнения разбиения графа с использованием Parmetis&lt;br /&gt;
|-&lt;br /&gt;
! Graph&lt;br /&gt;
! 8 processors&lt;br /&gt;
! 16 processors&lt;br /&gt;
! 32 processors&lt;br /&gt;
! 64 processors&lt;br /&gt;
! 128 processors&lt;br /&gt;
|-&lt;br /&gt;
| mrng2&lt;br /&gt;
| 5.4&lt;br /&gt;
| 3.1&lt;br /&gt;
| 2.1&lt;br /&gt;
| 1.5&lt;br /&gt;
| 1.7&lt;br /&gt;
|-&lt;br /&gt;
| mrng3&lt;br /&gt;
| 15.8&lt;br /&gt;
| 8.8&lt;br /&gt;
| 4.8&lt;br /&gt;
| 3.0&lt;br /&gt;
| 2.7&lt;br /&gt;
|-&lt;br /&gt;
| mrng4&lt;br /&gt;
| 38.6&lt;br /&gt;
| 16.2&lt;br /&gt;
| 8.8&lt;br /&gt;
| 5.0&lt;br /&gt;
| 3.6&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Описанный алгоритм реализован во многих пакетах декомпозиции графов, включающих в себя и другие версии алгоритма бисекции.&lt;br /&gt;
&lt;br /&gt;
Последовательная версия алгоритма реализована в пакетах Chaco, JOSTLE, [http://glaros.dtc.umn.edu/gkhome/metis/metis/overview METIS], [https://www.labri.fr/perso/pelegrin/scotch/ SCOTCH]. &lt;br /&gt;
&lt;br /&gt;
Параллельная версия реализована в пакетах JOSTLE, [http://glaros.dtc.umn.edu/gkhome/metis/parmetis/overview ParMETIS], [https://www.labri.fr/perso/pelegrin/scotch/ PT-SCOTCH].&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что пакеты METIS и ParMETIS распространяются свободно.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&lt;br /&gt;
[[en:Recursive coordinate bisection method]]&lt;/div&gt;</summary>
		<author><name>Dan</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:%D0%9C%D0%B0%D0%BA%D0%B0%D1%80%D0%BE%D0%B2%D0%B0_%D0%90%D0%BB%D1%91%D0%BD%D0%B0&amp;diff=17878</id>
		<title>Обсуждение участника:Макарова Алёна</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:%D0%9C%D0%B0%D0%BA%D0%B0%D1%80%D0%BE%D0%B2%D0%B0_%D0%90%D0%BB%D1%91%D0%BD%D0%B0&amp;diff=17878"/>
		<updated>2016-11-17T11:13:56Z</updated>

		<summary type="html">&lt;p&gt;Dan: /* Пункт 1.7 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Пункт 2.4 =&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 14:13, 17 ноября 2016 (MSK) необходимо доработать:&lt;br /&gt;
&lt;br /&gt;
Требования были такие: &lt;br /&gt;
- Реализация: полностью собственная или обращение к библиотечной функции (Intel MKL, PETSc, FFTW, ScaLAPACK). В любом случае, текст исследуемой программы должен быть представлен в отчете. &lt;br /&gt;
- Компьютерная платформа может быть любой (Ломоносов, BlueGene или что-то иное). Описание компьютерной платформы должно быть в отчете. &lt;br /&gt;
- Должен быть представлен график сильной масштабируемости (зависимости производительности от числа процессов; если при этом&lt;br /&gt;
ещё и зависимость от размера задачи - это только в плюс). График должен выглядеть пристойно и понятно, оси и единицы измерения должны быть подписаны. К графику обязательно должны быть словесные пояснения! Требовалось подобрать такие размеры задачи и числа процессоров, чтобы отразить на графике характерные точки, описывающие свойства алгоритма и программы.&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:%D0%9C%D0%B0%D0%BA%D0%B0%D1%80%D0%BE%D0%B2%D0%B0_%D0%90%D0%BB%D1%91%D0%BD%D0%B0/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES_(%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D0%BD%D0%B5%D0%B2%D1%8F%D0%B7%D0%BE%D0%BA)&amp;diff=17877</id>
		<title>Участник:Макарова Алёна/Итерационный метод решения системы линейных алгебраических уравнений GMRES (обобщенный метод минимальных невязок)</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%D0%BA:%D0%9C%D0%B0%D0%BA%D0%B0%D1%80%D0%BE%D0%B2%D0%B0_%D0%90%D0%BB%D1%91%D0%BD%D0%B0/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES_(%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D0%BD%D0%B5%D0%B2%D1%8F%D0%B7%D0%BE%D0%BA)&amp;diff=17877"/>
		<updated>2016-11-17T11:13:41Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Обобщенный метод минимальных невязок&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(nm^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n(n + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&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;
Впервые метод минимальных невязок был описан в книге Марчука и Кузнецова &amp;quot;Итерационные методы и квадратичные функционалы&amp;quot; &amp;lt;ref&amp;gt; Г.И. Марчук, Ю.А. Кузнецов, Итерационные методы и квадратичные функционалы, Методы вычислительной математики, Новосибирск, 1975, с. 4-143.&amp;lt;/ref&amp;gt; и представлял собой геометрическую реализацию метода минимальных невязок.&lt;br /&gt;
&lt;br /&gt;
Алгебраическая реализация метода минимальных невязок была предложена Саадом и Шульцем в 1986 году &amp;lt;ref&amp;gt;Y.Saad, M.H. Schultz, GMRES: A generalized minimal residual algorithm for solving nonsymmetric linear systems, SIAM J. Scientific and Stat. Comp. 7: 856-869 (1986). &amp;lt;/ref&amp;gt;. С их подачи за методом закрепилась аббревиатура GMRES (обобщенный метод минимальных невязок).&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для решения системы &amp;lt;math&amp;gt;Ax = b&amp;lt;/math&amp;gt; с невырожденной матрицей &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;, выбирается начальное приближение &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt;, затем решается редуцированная система &amp;lt;math&amp;gt;Au = r_0&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;r_0 = b - Ax_0, x = x_0 + u&amp;lt;/math&amp;gt;. Подпространства Крылова строятся для редуцированной системы (в предположении, что &amp;lt;math&amp;gt;r_0 \neq 0&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;x_i = x_0 + y&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; y \in \mathcal{K}_i &amp;lt;/math&amp;gt;. Невязка имеет вид &amp;lt;math&amp;gt;r_i = r_0 - Ay&amp;lt;/math&amp;gt;, а её длина минимальна, в силу теоремы Пифагора, в том и только том случае, когда &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
r_i \perp A\mathcal{K}_i &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, для реализации &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го шага требуется опустить перпендикуляр из вектора &amp;lt;math&amp;gt;r_0&amp;lt;/math&amp;gt; на подпространство &amp;lt;math&amp;gt;A\mathcal{K}_i&amp;lt;/math&amp;gt;. Проще всего это сделать, если в данном подпространстве уже найден ортогональный базис. &amp;lt;ref&amp;gt; Тыртышников Е. Е. Методы численного анализа — М., Академия, 2007.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Геометрическая реализация ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Геометрическая реализация&#039;&#039; метода минимальных невязок заключается в построении последовательности векторов &amp;lt;math&amp;gt;q_1, q_2,...&amp;lt;/math&amp;gt; таким образом, что &amp;lt;math&amp;gt;q_1, q_2,.., q_i&amp;lt;/math&amp;gt; дают базис в подпространстве Крылова &amp;lt;math&amp;gt;\mathcal{K}_i&amp;lt;/math&amp;gt; и при этом вектора &amp;lt;math&amp;gt;p_1 = Aq_1, ..., p_i = Aq_i&amp;lt;/math&amp;gt; образуют ортогональный базис в подпространстве &amp;lt;math&amp;gt;A\mathcal{K}_i&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;q_{i+1} \notin \mathcal{K}_i&amp;lt;/math&amp;gt; должен обладать следующими свойствами:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
q_{i+1} \in \mathcal{K}_{i+1}, p_{i+1} = Aq_{i+1} \perp A\mathcal{K}_i&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Его можно получить с помощью процесса ортогонализации, применённого к вектору &amp;lt;math&amp;gt;p = Aq&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q = Aq_i&amp;lt;/math&amp;gt;. В геометрической реализации необходимо хранить две системы векторов: &amp;lt;math&amp;gt;q_1, ..., q_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_1, ..., p_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Алгебраическая реализация ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Алгебраическая реализация&#039;&#039; метода минимальных невязок использует лишь одну систему векторов, образующих ортогональные базисы в подпространствах &amp;lt;math&amp;gt;\mathcal{K}_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_1 = r_0/||r_0||_2&amp;lt;/math&amp;gt;. Чтобы получить ортонормированный базис  &amp;lt;math&amp;gt;q_1, ..., q_{i+1}&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;\mathcal{K}_{i+1} = \mathcal{K}_{i+1}(r_0, A)&amp;lt;/math&amp;gt;, проводим ортогонализацию вектора &amp;lt;math&amp;gt;Aq_i&amp;lt;/math&amp;gt; к векторам &amp;lt;math&amp;gt;q_1, ..., q_i&amp;lt;/math&amp;gt;. Если &amp;lt;math&amp;gt;Q_i \equiv [q_1, ..., q_i] \in \mathbb{C}^{n*i}&amp;lt;/math&amp;gt;, то получим&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AQ_i = Q_{i+1}\hat{H_i}, \hat{H_i}= \begin{bmatrix} H_i \\ 0 ... 0 &amp;amp; h_{i+1 i} \end{bmatrix},&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;H_i&amp;lt;/math&amp;gt; - верхняя хессенбергова матрица порядка &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим &amp;lt;math&amp;gt;QR&amp;lt;/math&amp;gt;-разложение прямоугольной матрицы &amp;lt;math&amp;gt;\hat{H_i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\hat{H_i} = U_iR_i, R_i \in \mathbb{C}^{i*i}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Тогда минимум невязки &amp;lt;math&amp;gt;||r_0 - AQ_iy||_2&amp;lt;/math&amp;gt; по всем &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; будет достигаться в том случае, если &amp;lt;math&amp;gt;y = y_i&amp;lt;/math&amp;gt; удовлетворяет уравнению&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
R_iy_i = z_i \equiv ||r_0||_2U^T_ie_1, e_1 = \begin{bmatrix} 1 0 ... 0 \end{bmatrix}^T,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;R_i&amp;lt;/math&amp;gt; невырожденная, следовательно,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
x_i = x_0 + Q_iy_i = x_0 + Q_iR_i^{-1}z_i&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Сходимость метода ====&lt;br /&gt;
&lt;br /&gt;
Метод минимизации невязок на подпространствах Крылова за конечное число итераций приводит к точному решению и по этой причине является прямым методом. Но чаще его рассматривают как итерационный метод - с типичными для итерационных методов оценками сходимости. Идея заключается в том, что спустя некоторое количество итераций, полученное приближение уже является хорошей оценкой ответа.&lt;br /&gt;
&lt;br /&gt;
Но об этом не верно говорить в общем. Согласно теореме (Greenbaum, Pták and Strakoš), для каждой монотонной последовательности &amp;lt;math&amp;gt; a_1,..., a_{m-1}, a_m = 0 &amp;lt;/math&amp;gt;, найдётся матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; такая что &amp;lt;math&amp;gt;||r_n|| = a_n&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;r_n&amp;lt;/math&amp;gt; невязка, определенная ранее.&lt;br /&gt;
&lt;br /&gt;
На практике для матрицы порядка  &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; число шагов может оказаться равным &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, а норма невязки может оставаться равной норме начальной невязки на всех шагах, кроме последнего. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Пример&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{bmatrix} 0 1 &amp;amp; ... \\ 0 0 1 &amp;amp; ... \\...\\... &amp;amp; 01 \\1 &amp;amp; ... \end{bmatrix} \begin{bmatrix} 1 \\ 0 \\...\\ 0 \\ 0 \end{bmatrix} = \begin{bmatrix} 0 \\ 0 \\...\\ 0 \\ 1 \end{bmatrix}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; x_0 = 0 &amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt; r_0 = b&amp;lt;/math&amp;gt;. Подпространства Крылова получаются такие:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\mathcal{K}_i = span \{ e_n, e_{n-1}, ..., e_{n-i+1}\}, i \le i \le n &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Точное решение системы имеет вид &amp;lt;math&amp;gt;x = e_1&amp;lt;/math&amp;gt;, а на итерациях получаются следующие векторы:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
x_0 = x_1 = ... = x_{n-1} = 0, x_n = e_1&lt;br /&gt;
&lt;br /&gt;
&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;math&amp;gt;A&amp;lt;/math&amp;gt; положительно определена, то&lt;br /&gt;
:&amp;lt;math&amp;gt; &lt;br /&gt;
\|r_n\| \leq \left( 1-\frac{\lambda_{\mathrm{min}}^2(1/2(A^T + A))}{ \lambda_{\mathrm{max}}(A^T A)} \right)^{n/2} \|r_0\|, &lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_{\mathrm{min}}(M)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_{\mathrm{max}}(M)&amp;lt;/math&amp;gt; обозначают наибольшее и наименьшее собственное значение матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, соответственно. &amp;lt;ref&amp;gt;Eisenstat, Elman &amp;amp; Schultz, Thm 3.3. NB all results for GCR also hold for GMRES, cf. Saad &amp;amp; Schultz&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Сходимость для симметричной матрицы =====&lt;br /&gt;
Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; является симметрично и положительно определена, тогда&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
\|r_n\| \leq \left( \frac{\kappa_2(A)^2-1}{\kappa_2(A)^2} \right)^{n/2} \|r_0\|&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;\kappa_2(A)&amp;lt;/math&amp;gt; число обусловленности матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; в Евклидовой норме.&lt;br /&gt;
&lt;br /&gt;
Если не требовать положительной определённости&lt;br /&gt;
:&amp;lt;math&amp;gt; &lt;br /&gt;
\|r_n\| \le \inf_{p \in P_n} \|p(A)\| \le \kappa_2(V) \inf_{p \in P_n} \max_{\lambda \in \sigma(A)} |p(\lambda)| \|r_0\|, \, &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;P_n&amp;lt;/math&amp;gt; обозначает множество полиномов степени не выше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p(0) = 1&amp;lt;/math&amp;gt;, матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; появляется из спектрального разложения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sigma(A)&amp;lt;/math&amp;gt; - спектр матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Грубо говоря, это означает, что быстрая сходимость имеет место, когда собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; невелики и &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не сильно отклоняется от нормальной матрицы.&amp;lt;ref&amp;gt;Trefethen &amp;amp; Bau, Thm 35.2&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти неравенства связаны с невязкой вместо фактической ошибки, т.е. расстоянием между текущей итерацией и точным решением.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Самой трудоёмкой процедурой в методе является &amp;lt;math&amp;gt;QR&amp;lt;/math&amp;gt;-разложение &amp;lt;math&amp;gt;\hat{H_i}&amp;lt;/math&amp;gt;. В общем случае требуется &amp;lt;math&amp;gt;\mathcal{O}(i^3)&amp;lt;/math&amp;gt; арифметических операций, однако то, что &amp;lt;math&amp;gt;\hat{H_i}&amp;lt;/math&amp;gt; является хессенберговой матрицей, позволяет сократить требуемый объём до &amp;lt;math&amp;gt;\mathcal{O}(i^2)&amp;lt;/math&amp;gt; действий.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм начинается с выбора начального приближения &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt;.&lt;br /&gt;
Далее для &amp;lt;math&amp;gt;i = 1,2 ..&amp;lt;/math&amp;gt;&lt;br /&gt;
: 1. Вычисляем матрицу &amp;lt;math&amp;gt;\hat{H_i}&amp;lt;/math&amp;gt;.&lt;br /&gt;
: 2. Находим её &amp;lt;math&amp;gt;QR&amp;lt;/math&amp;gt;-разложение: &amp;lt;math&amp;gt;\hat{H_i} = U_iR_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
: 3. Решаем систему &amp;lt;math&amp;gt;R_iy_i = U^T_ie_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
: 4. Находим приближение &amp;lt;math&amp;gt;x_i = x_0 + Q_iy_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм завершается, когда норма вектора невязки становится достаточно малой. При большом числе итераций вычислительные затраты и требуемая для хранения векторов &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; память могу оказаться чрезмерно большими. В таких случаях применяют алгоритм с перезапусками (restart): задают максимальную допустимую размерность &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; пространств Крылова &amp;lt;math&amp;gt;\mathcal{K}_i&amp;lt;/math&amp;gt;, и если точность не достигнута, берут полученное приближение в качестве нового начального приближения &amp;lt;math&amp;gt;x^0_{new} = x_K&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
* Инициализация начальных значений&lt;br /&gt;
&lt;br /&gt;
1. Выбрать начальное приближение &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt; и точность решения &amp;lt;math&amp;gt;\epsilon&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. Для &amp;lt;math&amp;gt; k = 1, 2, .. &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Вычисление невязки&lt;br /&gt;
&lt;br /&gt;
3. &amp;lt;math&amp;gt;r_0 = b - Ax_0&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\beta = ||r_0||&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_1 = r_0/\beta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
4. Цикл по &amp;lt;math&amp;gt; j = 1, 2, .. k &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Ортогонализация Арнольди&lt;br /&gt;
&lt;br /&gt;
5. Для каждого &amp;lt;math&amp;gt; i = 1, 2, .. j &amp;lt;/math&amp;gt; вычислим:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij} = (Aq_j, q_i)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Построим вектор: &amp;lt;math&amp;gt;z_{j+1} = Aq_j - \sum_{i = 1}^j h_{ij}q_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
7. Вычислим его норму &amp;lt;math&amp;gt;h_{j+1,j} = ||z_{j+1}||_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
8. Если &amp;lt;math&amp;gt;h_{j+1,j}&amp;lt;/math&amp;gt; = 0, то останавливаемся.&lt;br /&gt;
&lt;br /&gt;
9. Построим очередной вектор базиса &amp;lt;math&amp;gt;q_{j+1} = z_{j+1}/h_{j+1,j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
10. Конец цикла по &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
11. Процесс требует хранения всех предыдущих элементов базиса:&amp;lt;math&amp;gt;q_1, .. q_k&amp;lt;/math&amp;gt;. Будем хранить их в виде матриц &amp;lt;math&amp;gt;Q_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Задача наименьших квадратов&lt;br /&gt;
&lt;br /&gt;
12. Чтобы вычислить &amp;lt;math&amp;gt;x_k = x_0 + Q_ky_k&amp;lt;/math&amp;gt;, решаем задачу: &amp;lt;math&amp;gt; y_k = argmin ||r_0 - AP_ky_k||_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Проверка достижения требуемой точности приближения&lt;br /&gt;
&lt;br /&gt;
13. Если  &amp;lt;math&amp;gt;||b - Ax_k|| &amp;lt; \epsilon&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x_k = x_0 + Q_ky_k&amp;lt;/math&amp;gt; перейти к п.15&lt;br /&gt;
&lt;br /&gt;
14. &amp;lt;math&amp;gt;x_0 = x_k&amp;lt;/math&amp;gt;, перейти к п.2&lt;br /&gt;
&lt;br /&gt;
*Конец&lt;br /&gt;
&lt;br /&gt;
15. &amp;lt;math&amp;gt;x^* = x_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Будем предполагать, что матрица решаемой СЛАУ является разреженной.&lt;br /&gt;
Пусть несимметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; имеет симметричный портрет и число ненулевых элементов в нижнем(верхнем) треугольнике равно  &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При &amp;lt;math&amp;gt; m &amp;lt;&amp;lt; n &amp;lt;/math&amp;gt; можно говорить, что один GMRES-цикл имеет сложность &amp;lt;math&amp;gt;\mathcal{O}(nm^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Требования по памяти с учетом &amp;lt;math&amp;gt;1 &amp;lt; m &amp;lt;&amp;lt; n&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k &amp;lt;&amp;lt; n&amp;lt;/math&amp;gt; составляют &amp;lt;math&amp;gt;\mathcal{O}(mn)&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt; М.Ю. Баландин, Э.П.Шурина, Некоторые оценки эффективности параллельных алгоритмов решения СЛАУ на подпространствах Крылова, Вычислительные технологии, 1998, Т.3&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Основная и самая трудоёмкая операция в алгоритме - умножение матрицы на вектор. Для этой операции приводится граф вычисления операции.&lt;br /&gt;
&lt;br /&gt;
[[Файл:graf.png|thumb|center|1400px|Рисунок 2. Граф вычислений подзадачи умножения матрицы на вектор&amp;lt;ref&amp;gt; http://ssd.sscc.ru/sites/default/files/content/attach/449/shkorin_-_gmres.pdf&amp;lt;/ref&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В вычислительной схеме присутствуют два интенсивных в вычислительном плане этапа:&lt;br /&gt;
:1. Умножение матрицы СЛАУ на вектор (для нахождения невязок).&lt;br /&gt;
Для нахождения матрично-векторных произведений при вычислении невязок матрича должна быть подвергнута декомпозиции на строчные блоки.&lt;br /&gt;
:2. Нахождение скалярных произведений векторов (при построении ортонормального базиса подпространства Крылова).&lt;br /&gt;
Для наиболее эффективного вычисления скалярных проихведений и линейных комбинаций векоров базиса каждый из векторов &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; должен быть разбит на блоки равного размера по числу процессоров.&lt;br /&gt;
&lt;br /&gt;
Кроме того, на хранение векторов базиса приходится бОльшая часть затрат памяти.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные: &#039;&#039;&#039;&lt;br /&gt;
Обязательные параметры:&lt;br /&gt;
:&amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; - квадратная матрица &#039;&#039;(n x n)&#039;&#039;.&lt;br /&gt;
:&amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; - вектор правой части &#039;&#039;(n x 1)&#039;&#039;.&lt;br /&gt;
Вариативно:&lt;br /&gt;
:&amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt; - начальное приближение (может не передаваться и быть всегда нулевым).&lt;br /&gt;
:&amp;lt;math&amp;gt;\epsilon&amp;lt;/math&amp;gt; - погрешность (может не передаваться и быть заданным по умолчанию, обычно равна 1e-6).&lt;br /&gt;
:Максимальное число итераций.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;math&amp;gt;x^*&amp;lt;/math&amp;gt; - решение системы &amp;lt;math&amp;gt;Ax = b&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
:1. Рассматриваемый алгоритм предназначен для решения невырожденных линейных систем большой размерности. При этом симметрия и положительная определенность матрицы не предполагается.&lt;br /&gt;
&lt;br /&gt;
:2. Для систем с разряженной матрицей алгоритм требует гораздо меньшей вычислительной мощности.&lt;br /&gt;
&lt;br /&gt;
:3. Особенностью метода является то, что с целью экономии памяти выбирается некоторая размерность Крылова &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;, и после того как &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; базисных векторов построены, решение уточняется.&lt;br /&gt;
&lt;br /&gt;
:4. Одной из важных практических особенностей метода является  то, что на первых итерациях метод сходится гораздо быстрее, чем асимптотически. Для ускорения сходимости метода минимальных невязок целесообразно время о времени использовать один шаг двух-шагового метода минимальных невязок.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Реализация GMRES с преобуславливанием на python, доступная в пакете scipy (scipy.sparse.linal)&amp;lt;ref&amp;gt; https://github.com/scipy/scipy/blob/v0.14.0/scipy/sparse/linalg/isolve/iterative.py.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def gmres(A, b, x0=None, tol=1e-5, restart=None, maxiter=None, xtype=None, M=None, callback=None, restrt=None):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Use Generalized Minimal RESidual iteration to solve A x = b.&lt;br /&gt;
    Parameters&lt;br /&gt;
    ----------&lt;br /&gt;
    A : {sparse matrix, dense matrix, LinearOperator}&lt;br /&gt;
        The real or complex N-by-N matrix of the linear system.&lt;br /&gt;
    b : {array, matrix}&lt;br /&gt;
        Right hand side of the linear system. Has shape (N,) or (N,1).&lt;br /&gt;
    Returns&lt;br /&gt;
    -------&lt;br /&gt;
    x : {array, matrix}&lt;br /&gt;
        The converged solution.&lt;br /&gt;
    info : int&lt;br /&gt;
        Provides convergence information:&lt;br /&gt;
          * 0  : successful exit&lt;br /&gt;
          * &amp;gt;0 : convergence to tolerance not achieved, number of iterations&lt;br /&gt;
          * &amp;lt;0 : illegal input or breakdown&lt;br /&gt;
    Other parameters&lt;br /&gt;
    ----------------&lt;br /&gt;
    x0 : {array, matrix}&lt;br /&gt;
        Starting guess for the solution (a vector of zeros by default).&lt;br /&gt;
    tol : float&lt;br /&gt;
        Tolerance to achieve. The algorithm terminates when either the relative&lt;br /&gt;
        or the absolute residual is below `tol`.&lt;br /&gt;
    restart : int, optional&lt;br /&gt;
        Number of iterations between restarts. Larger values increase&lt;br /&gt;
        iteration cost, but may be necessary for convergence.&lt;br /&gt;
        Default is 20.&lt;br /&gt;
    maxiter : int, optional&lt;br /&gt;
        Maximum number of iterations (restart cycles).  Iteration will stop&lt;br /&gt;
        after maxiter steps even if the specified tolerance has not been&lt;br /&gt;
        achieved.&lt;br /&gt;
    xtype : {&#039;f&#039;,&#039;d&#039;,&#039;F&#039;,&#039;D&#039;}&lt;br /&gt;
        This parameter is DEPRECATED --- avoid using it.&lt;br /&gt;
        The type of the result.  If None, then it will be determined from&lt;br /&gt;
        A.dtype.char and b.  If A does not have a typecode method then it&lt;br /&gt;
        will compute A.matvec(x0) to get a typecode.   To save the extra&lt;br /&gt;
        computation when A does not have a typecode attribute use xtype=0&lt;br /&gt;
        for the same type as b or use xtype=&#039;f&#039;,&#039;d&#039;,&#039;F&#039;,or &#039;D&#039;.&lt;br /&gt;
        This parameter has been superseded by LinearOperator.&lt;br /&gt;
    M : {sparse matrix, dense matrix, LinearOperator}&lt;br /&gt;
        Inverse of the preconditioner of A.  M should approximate the&lt;br /&gt;
        inverse of A and be easy to solve for (see Notes).  Effective&lt;br /&gt;
        preconditioning dramatically improves the rate of convergence,&lt;br /&gt;
        which implies that fewer iterations are needed to reach a given&lt;br /&gt;
        error tolerance.  By default, no preconditioner is used.&lt;br /&gt;
    callback : function&lt;br /&gt;
        User-supplied function to call after each iteration.  It is called&lt;br /&gt;
        as callback(rk), where rk is the current residual vector.&lt;br /&gt;
    restrt : int, optional&lt;br /&gt;
        DEPRECATED - use `restart` instead.&lt;br /&gt;
    See Also&lt;br /&gt;
    --------&lt;br /&gt;
    LinearOperator&lt;br /&gt;
    Notes&lt;br /&gt;
    -----&lt;br /&gt;
    A preconditioner, P, is chosen such that P is close to A but easy to solve&lt;br /&gt;
    for. The preconditioner parameter required by this routine is&lt;br /&gt;
    ``M = P^-1``. The inverse should preferably not be calculated&lt;br /&gt;
    explicitly.  Rather, use the following template to produce M::&lt;br /&gt;
      # Construct a linear operator that computes P^-1 * x.&lt;br /&gt;
      import scipy.sparse.linalg as spla&lt;br /&gt;
      M_x = lambda x: spla.spsolve(P, x)&lt;br /&gt;
      M = spla.LinearOperator((n, n), M_x)&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # Change &#039;restrt&#039; keyword to &#039;restart&#039;&lt;br /&gt;
    if restrt is None:&lt;br /&gt;
        restrt = restart&lt;br /&gt;
    elif restart is not None:&lt;br /&gt;
        raise ValueError(&amp;quot;Cannot specify both restart and restrt keywords. &amp;quot;&lt;br /&gt;
                         &amp;quot;Preferably use &#039;restart&#039; only.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    A,M,x,b,postprocess = make_system(A,M,x0,b,xtype)&lt;br /&gt;
&lt;br /&gt;
    n = len(b)&lt;br /&gt;
    if maxiter is None:&lt;br /&gt;
        maxiter = n*10&lt;br /&gt;
&lt;br /&gt;
    if restrt is None:&lt;br /&gt;
        restrt = 20&lt;br /&gt;
    restrt = min(restrt, n)&lt;br /&gt;
&lt;br /&gt;
    matvec = A.matvec&lt;br /&gt;
    psolve = M.matvec&lt;br /&gt;
    ltr = _type_conv[x.dtype.char]&lt;br /&gt;
    revcom = getattr(_iterative, ltr + &#039;gmresrevcom&#039;)&lt;br /&gt;
    stoptest = getattr(_iterative, ltr + &#039;stoptest2&#039;)&lt;br /&gt;
&lt;br /&gt;
    resid = tol&lt;br /&gt;
    ndx1 = 1&lt;br /&gt;
    ndx2 = -1&lt;br /&gt;
    work = np.zeros((6+restrt)*n,dtype=x.dtype)&lt;br /&gt;
    work2 = np.zeros((restrt+1)*(2*restrt+2),dtype=x.dtype)&lt;br /&gt;
    ijob = 1&lt;br /&gt;
    info = 0&lt;br /&gt;
    ftflag = True&lt;br /&gt;
    bnrm2 = -1.0&lt;br /&gt;
    iter_ = maxiter&lt;br /&gt;
    old_ijob = ijob&lt;br /&gt;
    first_pass = True&lt;br /&gt;
    resid_ready = False&lt;br /&gt;
    iter_num = 1&lt;br /&gt;
    while True:&lt;br /&gt;
        olditer = iter_&lt;br /&gt;
        x, iter_, resid, info, ndx1, ndx2, sclr1, sclr2, ijob = \&lt;br /&gt;
           revcom(b, x, restrt, work, work2, iter_, resid, info, ndx1, ndx2, ijob)&lt;br /&gt;
        # if callback is not None and iter_ &amp;gt; olditer:&lt;br /&gt;
        #    callback(x)&lt;br /&gt;
        slice1 = slice(ndx1-1, ndx1-1+n)&lt;br /&gt;
        slice2 = slice(ndx2-1, ndx2-1+n)&lt;br /&gt;
        if (ijob == -1):  # gmres success, update last residual&lt;br /&gt;
            if resid_ready and callback is not None:&lt;br /&gt;
                callback(resid)&lt;br /&gt;
                resid_ready = False&lt;br /&gt;
&lt;br /&gt;
            break&lt;br /&gt;
        elif (ijob == 1):&lt;br /&gt;
            work[slice2] *= sclr2&lt;br /&gt;
            work[slice2] += sclr1*matvec(x)&lt;br /&gt;
        elif (ijob == 2):&lt;br /&gt;
            work[slice1] = psolve(work[slice2])&lt;br /&gt;
            if not first_pass and old_ijob == 3:&lt;br /&gt;
                resid_ready = True&lt;br /&gt;
&lt;br /&gt;
            first_pass = False&lt;br /&gt;
        elif (ijob == 3):&lt;br /&gt;
            work[slice2] *= sclr2&lt;br /&gt;
            work[slice2] += sclr1*matvec(work[slice1])&lt;br /&gt;
            if resid_ready and callback is not None:&lt;br /&gt;
                callback(resid)&lt;br /&gt;
                resid_ready = False&lt;br /&gt;
                iter_num = iter_num+1&lt;br /&gt;
&lt;br /&gt;
        elif (ijob == 4):&lt;br /&gt;
            if ftflag:&lt;br /&gt;
                info = -1&lt;br /&gt;
                ftflag = False&lt;br /&gt;
            bnrm2, resid, info = stoptest(work[slice1], b, bnrm2, tol, info)&lt;br /&gt;
&lt;br /&gt;
        old_ijob = ijob&lt;br /&gt;
        ijob = 2&lt;br /&gt;
&lt;br /&gt;
        if iter_num &amp;gt; maxiter:&lt;br /&gt;
            break&lt;br /&gt;
&lt;br /&gt;
    if info &amp;gt;= 0 and resid &amp;gt; tol:&lt;br /&gt;
        # info isn&#039;t set appropriately otherwise&lt;br /&gt;
        info = maxiter&lt;br /&gt;
&lt;br /&gt;
    return postprocess(x), info&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;lt;ref&amp;gt; С.А. Буренков, Организация и исследование эффективных вычислений для решения задач аэроакустики на кластерных архитектурах, Москва, 2014.&amp;lt;/ref&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;
Рассмотрим операции, которые выполняются неоднократно в процессе выполнения алгоритма: умножение матрицы на вектор, произведение векторов, расчет нормы вектора, нахождение взвешенной суммы векторов. Эти подзадачи можно разделить на 2 группы: операции между матрицей и вектором (например, умножение матрицы на вектор) и операции между двумя векторами (например, скалярное умножение, взвешенная сумма векторов и пр.). Подзадачи умножения константы на вектор и определение нормы вектора будем относить ко второй группе, так как их трудоемкость одного порядка. &lt;br /&gt;
&lt;br /&gt;
Особенности выполнения операций между матрицей и вектором определены способом распределения входных данных. На рис. 2 схематично изображен процесс параллельного умножения матрицы на вектор на трех процессорах. &lt;br /&gt;
&lt;br /&gt;
[[file:Matr_x_v.png|thumb|center|700px|Рисунок 2. Схема параллельного выполнения операции между матрицей и вектором]]&lt;br /&gt;
&lt;br /&gt;
Заштрихованные участки соответствуют данным, расположенным в памяти процессора исполнителя. Каждый исполнитель получает свою часть результата выполнения операции.&lt;br /&gt;
&lt;br /&gt;
По схожему принципу организовано параллельное выполнение операций между двумя векторами. Несмотря на то, что каждому процессу доступна полная информация о векторах, вычисления производятся лишь над участком, соответствующим процессу-исполнителю. На рис. 3 изображен пример параллельного выполнения операций между двумя векторами.&lt;br /&gt;
&lt;br /&gt;
[[file:V x v.png|thumb|center|700px|Рисунок 3. Схема параллельного выполнения операции между двумя векторами]]&lt;br /&gt;
&lt;br /&gt;
Таким образом, параллельное выполнение любой из выделенных подзадач привело к распределению вычислительной нагрузки между всеми исполнителями. &lt;br /&gt;
&lt;br /&gt;
==== Объединение результатов расчетов ====&lt;br /&gt;
&lt;br /&gt;
Результатом выполнения рассматриваемых операций является, чаще всего, вектор, части которого расположены на участвовавших в вычислениях процессорах. Для объединения результатов расчета и получения полного вектора на каждом процессоре вычислительной системы необходимо выполнить операцию сбора данных. В качестве обменных взаимодействий в модели с распределённой памятью могут выступать операции массовых коммуникационных обменов. С их помощью каждый процессор передаст свой вычисленный элемент вектора всем остальным процессорам (см. рис. 4).&lt;br /&gt;
[[file:Collect.png|thumb|center|700px|Рисунок 4. Принцип сбора результатов вычислений]]&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Алгоритм GMRES достаточно популярен и его реализацию можно найти во многих пакетах прикладных программ.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Пример: MATLAB&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;matlab&amp;quot;&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
Итерационный метод минимизации обобщенной невязки реализован в системе MATLAB. Для этого используется функция gmres:&lt;br /&gt;
&lt;br /&gt;
gmres (А, В. restart) — возвращает решение X СЛУ А*Х=В. А —квадратная матрица. Функция gmres начинает итерации от начальной оценки, представляющей собой вектор размера и, состоящий из нулей. Итерации производятся либо до сходимости к решению, либо до появления ошибки, либо до достижения максимального числа итераций. Сходимость достигается, когда относительный остаток norm(B-A*X)/norm(B) меньше или равен заданной погрешности (по умолчанию 1е-6). Максимальное число итераций — минимум из n:restart и 10. Функция gmres (...) имеет и ряд других форм записи, аналогичных описанным для функции bieg(...).  &lt;br /&gt;
&lt;br /&gt;
» gmres(A.B)&lt;br /&gt;
&lt;br /&gt;
GMRES(4) converged at Iteration 1(4) to a solution with relative residual le-016&lt;br /&gt;
&lt;br /&gt;
ans =&lt;br /&gt;
&lt;br /&gt;
1.0000&lt;br /&gt;
&lt;br /&gt;
2.0000&lt;br /&gt;
&lt;br /&gt;
3.0000&lt;br /&gt;
&lt;br /&gt;
4.0000&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Список пакетов, в которых присутствует реализация метод минимизации обобщенной невязки:&lt;br /&gt;
:1.&#039;&#039;&#039;ATLAS&#039;&#039;&#039; (Automatically Tuned Linear Algebra Software) – оптимизированная библиотека, включающая реализацию процедур BLAS и часть функциональности LAPACK; &lt;br /&gt;
:2.&#039;&#039;&#039;AZTEC&#039;&#039;&#039; – библиотека параллельных подпрограмм для решения больших систем линейных алгебраических уравнений с разреженными матрицами; &lt;br /&gt;
:3.&#039;&#039;&#039;BLAS&#039;&#039;&#039; (Basic Linear Algebra Subprograms) – библиотека высококачественных процедур, «строительными блоками» для которых являются вектора, матрицы или их части. Уровень 1 BLAS используется для выполнения операций вектор-вектор, уровень 2 :BLAS – для выполнения матрично-векторных операций, наконец, уровень 3 BLAS – для выполнения матрично-матричных операций. Поскольку программы BLAS являются эффективными, переносимыми и легко доступными, они используются как базовые компоненты для развития высококачественного программного обеспечения для задач линейной алгебры. Так были созданы широко известные пакеты LINPACK, EISPACK, которые затем были перекрыты пакетом LAPACK, получившим большое распространение. Перечисленные пакеты разработаны на языке Fortran; &lt;br /&gt;
:4.&#039;&#039;&#039;BLACS&#039;&#039;&#039; (Basic Linear Algebra Communication Subprograms) – набор базовых коммуникационных процедур линейной алгебры, созданных для линейной алгебры. Вычислительная модель состоит из одномерной или двумерной решетки процессов, где каждый процесссодержит часть матрицы или вектора. BLACS используется как коммуникационный слой проекта ScaLAPACK, который переносит библиотеку LAPACK на машины с распределенной памятью; &lt;br /&gt;
:5.&#039;&#039;&#039;BlockSolve95&#039;&#039;&#039; – параллельная библиотека для решения разреженных систем линейных уравнений; &lt;br /&gt;
:6.&#039;&#039;&#039;BPKIT2&#039;&#039;&#039; – пакет блочных способов предобусловливания, ориентированных на разреженные матрицы; &lt;br /&gt;
:7.&#039;&#039;&#039;CAPSS&#039;&#039;&#039; – пакет для параллельного решения разреженных линейных систем; &lt;br /&gt;
:8.&#039;&#039;&#039;CXML&#039;&#039;&#039; (The Compaq Extended Math Library) – расширенная математическая библиотека, включающая в себя часть функциональности BLAS, LAPACK, Direct Sparse Solvers и Iterative-solvers; &lt;br /&gt;
:9.&#039;&#039;&#039;Direct Sparse Solvers&#039;&#039;&#039; – пакет программ для решения разреженных систем прямыми методами; &lt;br /&gt;
:10.&#039;&#039;&#039;EISPACK&#039;&#039;&#039; (Eigensystem Package) – пакет программ решения алгебраической проблемы собственных значений; &lt;br /&gt;
:11.&#039;&#039;&#039;Expokit&#039;&#039;&#039; – пакет программ для решения не больших СЛАУ с плотной матрицей и больших разреженных систем; &lt;br /&gt;
:12.&#039;&#039;&#039;ILUPACK&#039;&#039;&#039; – библиотке, содержащая способы предобусловливания, ориентированная на разреженные СЛАУ. Пакет включает реализацию процедур BLAS, SPARSEKIT. Реализована на языке С и Fortran; &lt;br /&gt;
:13.&#039;&#039;&#039;IML++&#039;&#039;&#039; (Iterative Methods Library) – библиотека итерационных методов решения разреженных СЛАУ, позволяющая использовать несколько простых способов предобусловливания. Пакет включает часть BLAS и MV; &lt;br /&gt;
:14.&#039;&#039;&#039;Intel MKL&#039;&#039;&#039; (Intel Math Kernel Library) включает несколько стандартных библиотек для высокопроизводительных системах (BLAS, LAPACK и FFTPACK – подпрограммы быстрого преобразования Фурье); &lt;br /&gt;
:15.&#039;&#039;&#039;IOMDRV&#039;&#039;&#039; – пакет подпрограмм для решения симметричных и несимметричных линейных систем методами крыловских подпространств; &lt;br /&gt;
:16.&#039;&#039;&#039;Iterative-solvers&#039;&#039;&#039; – пакет подпрограмм решения разреженных систем итерационными методами; &lt;br /&gt;
:17.&#039;&#039;&#039;ITL&#039;&#039;&#039; (Iterative Template Library) – библиотека программ итерационных методов и способов предобусловливания, являющаяся составной частью MTL. &lt;br /&gt;
:18.&#039;&#039;&#039;ITPACK&#039;&#039;&#039; (Iterative Package) – пакет программ для решения разреженных систем итерационными методами; &lt;br /&gt;
:19.&#039;&#039;&#039;ITSOL&#039;&#039;&#039; (The New Sparskit Preconditionning Module) – пакет, содержащий способы предобусловливания, ориентированные на разреженные матрицы. Является составной частью пакета SPARSKIT; &lt;br /&gt;
:20.&#039;&#039;&#039;JAMA/C++&#039;&#039;&#039; – библиотека для решения СЛАУ прямыми методами; &lt;br /&gt;
:21.&#039;&#039;&#039;LAPACK&#039;&#039;&#039; (Linear Algebra Package) – набор реализаций «продвинутых» методов линейной алгебры. LAPACK содержит процедуры для решения систем линейных уравнений, задач нахождения собственных значений и факторизации матриц. Обрабатываются заполненные и ленточные матрицы, но не разреженные матрицы общего вида. Во всех случаях можно обрабатывать действительные и комплексные матрицы с одиночной и удвоенной точностью. Процедуры LAPACK построены таким образом, чтобы как можно больше вычислений выполнялось с помощью обращений к BLAS с использованием всех его трех уровней. Вследствие крупнозернистости операций уровня 3 BLAS, их использование обеспечивает высокую эффективность на многих высокопроизводительных компьютерах, в частности, если производителем создана специализированная реализация. ScaLAPACK является успешным результатом переноса пакета LAPACK на системы с передачей сообщений. Но в таких системах необходимы процедуры, обеспечивающие обмен данными между взаимодействующими процессами. Для этого в ScaLAPACK используется библиотека BLACS; &lt;br /&gt;
:22.&#039;&#039;&#039;Laspack&#039;&#039;&#039; – пакет программ для решения разреженных систем итерационными методами; &lt;br /&gt;
:23.&#039;&#039;&#039;LGSOLV&#039;&#039;&#039; – библиотека для решения СЛАУ прямыми методами; &lt;br /&gt;
:24.&#039;&#039;&#039;LINPACK&#039;&#039;&#039; (Linear Package) – пакет программ решения систем линейных алгебраических уравнений и линейной задачи наименьших квадратов прямыми методами; &lt;br /&gt;
:25.&#039;&#039;&#039;LinPar&#039;&#039;&#039; – пакет предназначенный для решения плохообусловленных СЛАУ, включая прямоугольные. Если для решения задачи необходимо предобусловливание СЛАУ, то оно выполняется отдельно и методы применяются к уже предобусловленной системе. Соответственно, по окончании процесса решения найденный вектор должен быть пересчитан согласно выполненному предобусловливанию. В схемы методов эти процедуры не включаются; &lt;br /&gt;
:26.&#039;&#039;&#039;MET&#039;&#039;&#039; (Matrix Expression Templates) – реализованная на языке C++ программа для инженеров и научных работников; &lt;br /&gt;
:27.&#039;&#039;&#039;MINOS&#039;&#039;&#039; – пакет подпрограмм решения больших разреженных задач линейного и нелинейного программирования; &lt;br /&gt;
:28.&#039;&#039;&#039;MTL&#039;&#039;&#039; (The Matrix Template Library) – реализованная на языке C++ библиотека базовых операций линейной алгебры, позволяющая решать СЛАУ с разреженными матрицами итерационными методами с предобусловлмванием, за счет включенного пакета ITL; &lt;br /&gt;
:29.&#039;&#039;&#039;MV++&#039;&#039;&#039; – небольшая библиотека, содержащая базовые операции линейной алгебры. Данный пакет часто является составной частью более крупных и высокопроизводительных библиотек; &lt;br /&gt;
:30.&#039;&#039;&#039;ParPre&#039;&#039;&#039; – пакет параллельных версий способов предобусловливания, ориентированных на разреженные матрицы, являющийся составной частью PETs; &lt;br /&gt;
:31.&#039;&#039;&#039;Parallel Algorithms Project&#039;&#039;&#039; – пакет параллельных версий итерационных методов Крыловского типа для решения разреженных систем; &lt;br /&gt;
:32.&#039;&#039;&#039;PASVA&#039;&#039;&#039; – пакет подпрограмм решения разреженных систем с блочно-двухдиагональной структурой; &lt;br /&gt;
:33.&#039;&#039;&#039;PBLAS&#039;&#039;&#039; – Параллельные версии базовых процедур линейной алгебры (BLAS) ; &lt;br /&gt;
:34.&#039;&#039;&#039;PCGPAK&#039;&#039;&#039; (Preconditioned Conjugate Gradient PAcKage) – пакет программ для решения симметричных и несимметричных разреженных линейных систем методом сопряженных градиентов; &lt;br /&gt;
:35.&#039;&#039;&#039;PIM&#039;&#039;&#039; (The Parallel Iterative Methods) – набор процедур на Фортран-77, реализующих параллельные версии различных итеративных методов решения разреженных систем линейных уравнений; &lt;br /&gt;
:36.&#039;&#039;&#039;PSparselib&#039;&#039;&#039; (A Portable Library of Parallel Sparse Iterative Solvers) – библиотека параллельных итерационных методов для разреженных линейных систем; &lt;br /&gt;
:37.&#039;&#039;&#039;PSPASES&#039;&#039;&#039; (Parallel Sparse Symmetric Direct Solver) – библиотека параллельных версий прямых методов для решения симметричных линейных систем; &lt;br /&gt;
:38.&#039;&#039;&#039;RALAPACK&#039;&#039;&#039; – пакет подпрограмм для различных операций с разреженными матрицами; &lt;br /&gt;
:39.&#039;&#039;&#039;ScaLAPACK&#039;&#039;&#039; (Scalable LAPACK) – параллельная версия LAPACK. Широкий набор подпрограмм для решения стандартных задач линейной алгебры; &lt;br /&gt;
:40.&#039;&#039;&#039;SIRSM&#039;&#039;&#039; – пакет подпрограмм для решения разреженных несимметричных линейных систем; &lt;br /&gt;
:41.&#039;&#039;&#039;Software Iterative Methods: GMRESR and BiCGstab(ell)&#039;&#039;&#039; – пакет прогамм решения больших разреженных систем с несимметричной матрицей; &lt;br /&gt;
:42.&#039;&#039;&#039;SPAI&#039;&#039;&#039; (Sparse Approximate Inverse Preconditioner) – пакет способов предобусловливания, ориентированных на разреженные матрицы; &lt;br /&gt;
:43.&#039;&#039;&#039;SPARKS&#039;&#039;&#039; – пакет подпрограмм для решения разреженных линейных систем в полунеявных методах Рунге-Кутта численного интегрирования систем обыкновенных дифференциальных уравнений; &lt;br /&gt;
:44.&#039;&#039;&#039;SparseLib++&#039;&#039;&#039; – библиотка, реализованная на языке C++, позволяющая решать разреженные СЛАУ итерационными методами с предобусловливанием. Включает часть процедур BLAS и IML; &lt;br /&gt;
:45.&#039;&#039;&#039;SPARSKIT&#039;&#039;&#039; – мощный пакет для решения разреженных СЛАУ итерационными методами с предобусловливанием. Библиотека реализованна на языке Fortran; &lt;br /&gt;
:46.&#039;&#039;&#039;SPARSPAK&#039;&#039;&#039; (Sparsee Iinear Equations Package) – пакет программ решения разреженных систем линейных алгебраических уравнений с симметричными положительно определенными матрицами; &lt;br /&gt;
:47.&#039;&#039;&#039;SPLIB&#039;&#039;&#039; – библиотека, позволяющая решать СЛАУ с разреженной матрицей итерационными методами с предобусловливанием, реализованная на языке Fortran; &lt;br /&gt;
:48.&#039;&#039;&#039;SPLP&#039;&#039;&#039; (Sparse Linear Programming Subprogram) – пакет программ решения задач линейного программирования; &lt;br /&gt;
:49.&#039;&#039;&#039;SPOOLES&#039;&#039;&#039; – библиотека для решения СЛАУ с разреженной матрицей прямыми методами; &lt;br /&gt;
:50.&#039;&#039;&#039;SSLES&#039;&#039;&#039; – пакет подпрограмм для решения разреженных несимметричных линейных систем; &lt;br /&gt;
:51.&#039;&#039;&#039;TCHLIB&#039;&#039;&#039; – пакет подпрограмм для решения симметричных и несимметричных линейных систем методом Чебышева; &lt;br /&gt;
:52.&#039;&#039;&#039;TNT&#039;&#039;&#039; (Template Numerical Toolkit) – библиотека базовых операций линейной алгебры, ориентированная на разреженные матрицы. Библиотека разработана на языке Fortran; &lt;br /&gt;
:53.&#039;&#039;&#039;WSMP&#039;&#039;&#039; (Watson Sparse Matrix Package) – пакет программ решения разреженных систем линейных алгебраических уравнений; &lt;br /&gt;
:54.&#039;&#039;&#039;XMP&#039;&#039;&#039; – пакет подпрограмм для решения задач линейного программирования; &lt;br /&gt;
:55.&#039;&#039;&#039;YI2M&#039;&#039;&#039; – комплекс программ решения разреженных систем;&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Dan</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:%D0%90%D0%BD%D1%8E%D1%88%D0%B5%D0%B2%D0%B0_%D0%98%D1%80%D0%B8%D0%BD%D0%B0&amp;diff=17876</id>
		<title>Обсуждение участника:Анюшева Ирина</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:%D0%90%D0%BD%D1%8E%D1%88%D0%B5%D0%B2%D0%B0_%D0%98%D1%80%D0%B8%D0%BD%D0%B0&amp;diff=17876"/>
		<updated>2016-11-17T11:13:14Z</updated>

		<summary type="html">&lt;p&gt;Dan: /* Пункт 1.7 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Пункт 2.4 =&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 14:13, 17 ноября 2016 (MSK) необходимо доработать:&lt;br /&gt;
&lt;br /&gt;
Требования были такие: &lt;br /&gt;
- Реализация: полностью собственная или обращение к библиотечной функции (Intel MKL, PETSc, FFTW, ScaLAPACK). В любом случае, текст исследуемой программы должен быть представлен в отчете. &lt;br /&gt;
- Компьютерная платформа может быть любой (Ломоносов, BlueGene или что-то иное). Описание компьютерной платформы должно быть в отчете. &lt;br /&gt;
- Должен быть представлен график сильной масштабируемости (зависимости производительности от числа процессов; если при этом&lt;br /&gt;
ещё и зависимость от размера задачи - это только в плюс). График должен выглядеть пристойно и понятно, оси и единицы измерения должны быть подписаны. К графику обязательно должны быть словесные пояснения! Требовалось подобрать такие размеры задачи и числа процессоров, чтобы отразить на графике характерные точки, описывающие свойства алгоритма и программы.&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:%D0%90%D0%BD%D1%8E%D1%88%D0%B5%D0%B2%D0%B0_%D0%98%D1%80%D0%B8%D0%BD%D0%B0/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES_(%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D0%BD%D0%B5%D0%B2%D1%8F%D0%B7%D0%BE%D0%BA)&amp;diff=17875</id>
		<title>Участник:Анюшева Ирина/Итерационный метод решения системы линейных алгебраических уравнений GMRES (обобщенный метод минимальных невязок)</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%D0%BA:%D0%90%D0%BD%D1%8E%D1%88%D0%B5%D0%B2%D0%B0_%D0%98%D1%80%D0%B8%D0%BD%D0%B0/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES_(%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D0%BD%D0%B5%D0%B2%D1%8F%D0%B7%D0%BE%D0%BA)&amp;diff=17875"/>
		<updated>2016-11-17T11:12:36Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = GMRES (обобщенный метод минимальных невязок)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(m^2n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = 1&lt;br /&gt;
| pf_width          = 1&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n^2+2n&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[U:Анюшева Ирина|Анюшева Ирина]] (614 группа, разделы: 1.1-1.2, 1.7-1.8, 2.7, 3), Исхаков Эльдар (614 группа, разделы 1.3-1.6, 1.9-1.10)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритма =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Обобщенный метод минимальных невязок (GMRES) для решения системы линейных алгебраических уравнений аппроксимирует решение с помощью вектора в подпространстве Крылова с минимальным остатком. Метод GMRES разработан Ю.Саадом и Мартин Х. Шульцом в 1986 году.  Метод по праву считается одним из самых эффективных численных методов решения несимметричных систем. Он гарантирует неувеличение нормы невязки в ходе итерационного процесса, который основан на построении базиса в соответствующей системе подпространстве Крылова &amp;lt;math&amp;gt;K_j(A, r_0)&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем решение уточняется некоторой добавкой, представленной в виде разложения по этому базису.&lt;br /&gt;
&lt;br /&gt;
Метод обобщенных минимальных невязок популярен из-за наличия ряда преимуществ: он ошибкоустойчив, допускает эффективное распараллеливание, не требует нахождения параметра релаксации, обладает суперлинейной скоростью сходимости. Однако в чистом виде для больших систем метод не используется из-за чрезвычайно больших затрат памяти. Зато широкое распространение получила перезапускаемая версия метода, подоразумевающая перезапуск метода каждые m итераций. Уменьшение размерности пространства может привести к стагнации метода – процессу, при котором с каждой следующей итерацией норма невязки уменьшается незначительно, либо не уменьшается вовсе.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: система линейных алгебраических уравнений &amp;lt;math&amp;gt;Ax=b&amp;lt;/math&amp;gt;, где:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A=(a_{ij})&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt; вещественная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; вектора из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x^*&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt; точное решение системы.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: &amp;lt;math&amp;gt;x^{(s)} - &amp;lt;/math&amp;gt;приближенное решение системы.&lt;br /&gt;
&lt;br /&gt;
===Ортогонализация Арнольди===&lt;br /&gt;
Для построения базиса &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; в подпространстве Крылова в методе GMRES применяется ортогонализация Арнольди.&lt;br /&gt;
&lt;br /&gt;
Формулы метода:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(h_{i+1,i}v_{i+1}) &amp;amp; = Av_i - \sum_{j = 1}^{i} h_{j,i}v_j, \\&lt;br /&gt;
v_1 &amp;amp;= \frac{r_0}{\parallel r_0 \parallel},&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
В матрично-векторных обозначениях соотношение может быть записано как&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
AV_i &amp;amp;= V_i H_i + h_{i+1,i}v_{i+1} e_i^T &amp;amp;=V_{i+1}\overline{H}_i,&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
V_i &amp;amp;= [v_1|v_2|...|v_i], \overline{H}_i - \end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt; верхняя матрица Хессенберга размерности &amp;lt;math&amp;gt;(i+1)\times i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Минимизация невязки===&lt;br /&gt;
&lt;br /&gt;
Невязку уравнения можно определить как&lt;br /&gt;
&amp;lt;math&amp;gt; J(y) = \parallel b- A x\parallel = \parallel b- (Ax_0+V_m y)\parallel =\parallel \beta e_1 - \overline{H}_m y \parallel&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;y -&amp;lt;/math&amp;gt; вектор размерности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вектор &amp;lt;math&amp;gt;x_m&amp;lt;/math&amp;gt; может быть получен как &lt;br /&gt;
&amp;lt;math&amp;gt;x_m = x_0 + V_m y_m&amp;lt;/math&amp;gt;, вектор &amp;lt;math&amp;gt;y_m&amp;lt;/math&amp;gt; может найден как решение линейной задачи наименьших квадратов размера &amp;lt;math&amp;gt;(m+1)\times m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m&amp;lt;&amp;lt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для решения задачи минимизации приведем матрицу &amp;lt;math&amp;gt;\overline{H}_m&amp;lt;/math&amp;gt; к верхнему треугольному виду с помощью вращений Гивенса. На шаге &lt;br /&gt;
&amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; матрица вращения &amp;lt;math&amp;gt;\Omega_i&amp;lt;/math&amp;gt; имеет размеры &amp;lt;math&amp;gt;(m+1)\times (m+1)&amp;lt;/math&amp;gt; и имеет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\Omega_i= \begin{pmatrix}&lt;br /&gt;
1 &amp;amp; &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
&amp;amp;\ddots &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;\\&lt;br /&gt;
&amp;amp;&amp;amp;1&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\        &lt;br /&gt;
&amp;amp;&amp;amp;&amp;amp;c_i&amp;amp;s_i &amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
&amp;amp;&amp;amp;&amp;amp;-s_i&amp;amp; c_i &amp;amp;&amp;amp;&amp;amp;\\&lt;br /&gt;
&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;1&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;\ddots&amp;amp;\\&lt;br /&gt;
&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;1 \\  &lt;br /&gt;
\end{pmatrix}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
&lt;br /&gt;
В алгоритме GMRES присутствуют два ресурсоемких с точки зрения вычислительных мощностей этапа:&lt;br /&gt;
&lt;br /&gt;
* умножение исходной матрицы на вектор при вычислении невязок;&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;
1. Выбрать произвольное &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt;; вычислить &amp;lt;math&amp;gt;r_0=b-Ax_0&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v_1=\frac{r_0}{\parallel r_0 \parallel}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Задать матрицу &amp;lt;math&amp;gt;\overline{H}_m&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;(m+1)\times m&amp;lt;/math&amp;gt; и всем ее элементам присвоить нулевые значения&lt;br /&gt;
&lt;br /&gt;
3. Для &amp;lt;math&amp;gt;j=1,\dots,m&amp;lt;/math&amp;gt; выполнять:&lt;br /&gt;
&lt;br /&gt;
* для &amp;lt;math&amp;gt;i=1,\dots,j&amp;lt;/math&amp;gt; выполнять: &amp;lt;math&amp;gt;h_{i,j}=(Av_j,v_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\omega_j=Av_j-\sum_{i=1}^j h_{i,j}v_i&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;h_{j+1,j}={\parallel \omega_j \parallel}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;v_{j+1}=\frac{\omega_j}{h_{j+1,j}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Вычислить &amp;lt;math&amp;gt;y_m=\arg\min_{y} \parallel \beta e_1 - \overline{H}_my \parallel,\ y \in \mathbb{R}^m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;x_m=x_0+V_my_m&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. Вычислить &amp;lt;math&amp;gt;r_m=b-Ax_m&amp;lt;/math&amp;gt;. Если достигнутая точность удовлетворительна, остановиться.&lt;br /&gt;
&lt;br /&gt;
Иначе принять &amp;lt;math&amp;gt;x_0=x_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v_1=\frac{r_m}{\parallel r_m \parallel}&amp;lt;/math&amp;gt; и вернуться к пункту 2.&lt;br /&gt;
&lt;br /&gt;
===Решение задачи минимизации невязки===&lt;br /&gt;
&lt;br /&gt;
Для нахождения &amp;lt;math&amp;gt;y_m=\arg\min_{y} \parallel \beta e_1 - \overline{H}_my \parallel&amp;lt;/math&amp;gt; необходимо выполнить следующие шаги:&lt;br /&gt;
&lt;br /&gt;
1. Найти &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; матриц вращений Гивенса &amp;lt;math&amp;gt;\Omega_i(c_i,s_i),\ i=1,\dots,m&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;(m+1)\times(m+1)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;s_i=\frac{h_{i+1,i}}{\sqrt{h_{i,i}^2+h_{i+1,i}^2}}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_i=\frac{h_{i,i}}{\sqrt{h_{i,i}^2+h_{i+1,i}^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Вычислить &amp;lt;math&amp;gt;\overline{H}_m^{(m)}=\Omega_1\dots\Omega_m\overline{H}_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\overline{g}_m=\Omega_1\dots\Omega_m\beta e_1&amp;lt;/math&amp;gt;, удалить последнюю строку и последний элемент соответственно и решить СЛАУ с полученной верхнетреугольной матрицей и правой частью. Полученное решение &amp;lt;math&amp;gt;y_m&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;math&amp;gt;3m+1&amp;lt;/math&amp;gt; делений;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;2m+1&amp;lt;/math&amp;gt; вычислений квадратного корня;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{3m+5}{2}n&amp;lt;/math&amp;gt; умножений;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;O(\frac{m^2n^2}{2})&amp;lt;/math&amp;gt; сложений (вычитаний).&lt;br /&gt;
&lt;br /&gt;
==Информационный граф==&lt;br /&gt;
Метод состоит из двух блоков: ортогонализация и минимизация невязки. При ортогонализации основными операциями являются умножение матрицы на вектор и скалярное умножение векторов, для которых возможен параллелизм, что показано в блоке на темно-синем фоне. В блоке &amp;lt;math&amp;gt;min&amp;lt;/math&amp;gt; решается задача минимизации невязки, которая, строго говоря, является отдельной самостоятельной задачей.&lt;br /&gt;
[[file:gmres.jpg|thumb|center|700px|Рис.1. Информационная структура алгоритма GMRES]]&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
Для нахождения матрично-векторных произведений при вычислении невязок матрица СЛАУ должна быть подвергнута декомпозиции на строчные блоки, размеры которых определяются требованиями равномерности загрузки. Соответствующим образом подвергается декомпозиции и вектор правой части. Для наиболее эффективного вычисления скалярных произведений и линейных комбинаций векторов базиса каждый из векторов &amp;lt;math&amp;gt;v_j&amp;lt;/math&amp;gt; должен быть разбит на блоки равного размера по числу процессов; каждый из процессов при этом хранит соответствующие блоки всех векторов. Обработка вектора решения дублируется на всех процессах.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;;&lt;br /&gt;
* вектор-столбец &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;;&lt;br /&gt;
* вектор-столбец &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - начальное приближение;  &lt;br /&gt;
* натуральное число &amp;lt;math&amp;gt;m&amp;lt;&amp;lt;n&amp;lt;/math&amp;gt;, определяющее размерность подпространства Крылова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* вектор-столбец &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - решение системы.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
&lt;br /&gt;
* Вычислительная мощность: весьма маленькая и равна &amp;lt;math&amp;gt;m^2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;m&amp;lt;&amp;lt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Устойчивость: GMRES в этом плане является очень хорошим методом. Теоретически можно получить точное решение не более чем за &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итераций. Однако, очень приемлемые результаты получаются и за &amp;lt;math&amp;gt;m&amp;lt;&amp;lt;n&amp;lt;/math&amp;gt; итераций. Однако, есть примеры, в которых видно, что первые &amp;lt;math&amp;gt;m-1&amp;lt;/math&amp;gt; итераций дают невязку, равную некой константе, а на итерации под номером &amp;lt;math&amp;gt;m&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;
* Реализация алгоритма в библиотеке SciPy [https://docs.scipy.org/doc/scipy-0.17.0/reference/generated/scipy.sparse.linalg.gmres.html]&lt;br /&gt;
* Реализация алгоритма в библиотеке IML++ [http://math.nist.gov/iml++/gmres.h.txt]&lt;br /&gt;
* Библиотека для MATLAB [http://www.mathworks.com/help/matlab/ref/gmres.html]&lt;br /&gt;
&lt;br /&gt;
= Литература=&lt;br /&gt;
1. Y. Saad, M.H. Schultz. GMRES: A generalized minimal residual algorithm for solving nonsymmetric linear systems. SIAM J. Sci. Statist. Comput., 7 (1986), pp. 856–869&lt;br /&gt;
&lt;br /&gt;
2. Е.Е. Тыртышников. Методы численного анализа. – Москва: Академия, 2007&lt;br /&gt;
&lt;br /&gt;
3. М.Ю. Баландин, Э.П. Шурина. Некоторые оценки эффективности параллельных алгоритмов решения СЛАУ на подпространствах Крылова. - Вычислительные технологии, том 3, №1, 1998&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:Ilya4870/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%80%D0%B0%D0%B7%D0%B1%D0%B8%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D1%80%D0%B0%D1%84%D0%B0_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D0%B2%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%BE%D1%80%D0%B4%D0%B8%D0%BD%D0%B0%D1%82%D0%BD%D0%BE%D0%B9_%D0%B1%D0%B8%D1%81%D0%B5%D0%BA%D1%86%D0%B8%D0%B8&amp;diff=17874</id>
		<title>Участник:Ilya4870/Алгоритм разбиения графа методом рекурсивной координатной бисекции</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%D0%BA:Ilya4870/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%80%D0%B0%D0%B7%D0%B1%D0%B8%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D1%80%D0%B0%D1%84%D0%B0_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D0%B2%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%BE%D1%80%D0%B4%D0%B8%D0%BD%D0%B0%D1%82%D0%BD%D0%BE%D0%B9_%D0%B1%D0%B8%D1%81%D0%B5%D0%BA%D1%86%D0%B8%D0%B8&amp;diff=17874"/>
		<updated>2016-11-17T11:11:05Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Dan}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: Габдуллина М.И. (1.1, 1.3, 1.5, 1.9, 2.7), Урюпов И.В. (1.2, 1.4, 1.6, 1.7, 1.8, 1.10), группа м218.&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Задача рациональной декомпозиции расчетных сеток возникает при численном моделировании на высокопроизводительных вычислительных системах проблем механики сплошных сред, импульсной энергетики, электродинамики и многих других. Такие задачи сводятся к более общей задачи - разбиение вершин графа. Оптимальным считается разбиение на домены, при котором выровнен суммарный вес вершин в доменах и минимизирован суммарный вес разрезанных ребер (разрезанное ребро – ребро, соединяющее вершины из разных доменов). Одним из методов разбиения вершин графа на равные по мощности блоки является метод рекурсивной координатной бисекции.&amp;lt;ref name=&amp;quot;G1&amp;quot;/&amp;gt;&amp;lt;ref name=&amp;quot;G2&amp;quot;/&amp;gt;&amp;lt;ref name=&amp;quot;Y&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На каждом этапе рекурсивной бисекции область разбивается на две части.&lt;br /&gt;
Соотношение размеров частей зависит от количества доменов, которые&lt;br /&gt;
должны быть образованы в каждой из частей. Полученные подобласти разбиваются дальше аналогичным образом до тех пор, пока в подобластях не останется по одному домену. При рекурсивной координатной бисекции на этапе разбиения выбирается координатная ось, вдоль которой область имеет наибольшую протяженность. Область разбивается перпендикулярно полученной оси.&lt;br /&gt;
Достоинством данного метода является то, что при разбиении на равные домены числа вершин в получаемых доменах отличаются не больше, чем на единицу. Другими достоинствами являются экономичное использование памяти и относительная быстрота работы.&amp;lt;ref name=&amp;quot;G1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;G = (V,E)&amp;lt;/math&amp;gt; – неориентированный граф, где &amp;lt;math&amp;gt;V = \{v_i\}&amp;lt;/math&amp;gt; – множество вершин, &amp;lt;math&amp;gt;E = \{e_{ij}\}&amp;lt;/math&amp;gt; – множество рёбер. И вершины, и рёбра, имеют целочисленные веса &amp;lt;math&amp;gt;|v_i|&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;|e_{ij}|&amp;lt;/math&amp;gt;, соответственно.&lt;br /&gt;
&lt;br /&gt;
Декомпозиция является отображением множества вершин &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; на заданное число &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; доменов &amp;lt;math&amp;gt;S_j&amp;lt;/math&amp;gt; такое, что каждая вершина &amp;lt;math&amp;gt;v_i&amp;lt;/math&amp;gt; принадлежит некоторому домену &amp;lt;math&amp;gt;S_j&amp;lt;/math&amp;gt;, и &amp;lt;math&amp;gt;S_k \cap S_m = \emptyset&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммарный вес вершин в домене &amp;lt;math&amp;gt;S_j&amp;lt;/math&amp;gt; равен сумме весов вершин, принадлежащих этому домену:&lt;br /&gt;
&amp;lt;math&amp;gt;|S_j| = \sum_{i}{|v_i|}, v_i \in S_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммарный вес разрезанных рёбер равен сумме весов рёбер, соединяющих вершины из разных доменов:&lt;br /&gt;
&amp;lt;math&amp;gt;|E_c|=\sum_{ij}{|e_ij|}, v_i \in S_k, v_j \in S_m, k &amp;lt; m&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Каждый домен &amp;lt;math&amp;gt;S_j&amp;lt;/math&amp;gt; является некоторым подграфом &amp;lt;math&amp;gt;G^j = (V^j, E^j)&amp;lt;/math&amp;gt; графа &amp;lt;math&amp;gt;G = (V, E)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;V^j \subseteq V, E^j \subseteq E&amp;lt;/math&amp;gt;.&lt;br /&gt;
Домен является связным, если его граф состоит из одной компоненты связности, то есть между любой парой вершин этого графа существует как минимум один путь.&lt;br /&gt;
&lt;br /&gt;
Требуется найти такое разбиение множества вершин &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; на заданное число &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; связных доменов &amp;lt;math&amp;gt;S_j&amp;lt;/math&amp;gt;, при котором&amp;lt;ref name=&amp;quot;G1&amp;quot;/&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;div style=&amp;quot;max-width: 50%;&amp;quot;&amp;gt;выровнен суммарный вес вершин в доменах: &amp;lt;math&amp;gt;|S_j| \approx |V|/p&amp;lt;/math&amp;gt;,&amp;lt;span id=&amp;quot;condition1&amp;quot; style=&amp;quot;float: right;&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;div style=&amp;quot;max-width: 50%;&amp;quot;&amp;gt;минимизирован суммарный вес разрезанных рёбер: &amp;lt;math&amp;gt;min(|E_c|)&amp;lt;/math&amp;gt;.&amp;lt;span id=&amp;quot;condition2&amp;quot; style=&amp;quot;float: right;&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Используя обозначения выше, определим:&lt;br /&gt;
&lt;br /&gt;
* Входные данные алгоритма: множество координат вершин &amp;lt;math&amp;gt;C = \{c_i\}&amp;lt;/math&amp;gt; графа &amp;lt;math&amp;gt;G = (V, E)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;c_i = (v_i^x, v_i^y, v_i^z)&amp;lt;/math&amp;gt; - координаты вершины &amp;lt;math&amp;gt;v_i \in V&amp;lt;/math&amp;gt;, число доменов &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Выходные данные алгоритма: разбиение множества вершин &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; на заданное число &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; доменов &amp;lt;math&amp;gt;S_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Основные этапы алгоритма:&lt;br /&gt;
&lt;br /&gt;
* вычисляются протяжённости осей: &amp;lt;math&amp;gt;l_k = |max(v_i^k) - min(v_i^k)|&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;k = x, y, z&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
* производится сортировка множества &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; по координате, соответствующей наибольшей &amp;lt;math&amp;gt;l_k&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
* множество &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; разбивается на две части в соответствии с новым порядком элементов, то есть перпендикулярно координатной оси, вдоль которой она имеет наибольшую протяжённость; соотношение размеров частей зависит от количества доменов, которые должны быть образованы в каждой из частей,&lt;br /&gt;
&lt;br /&gt;
* полученные подмножества разбиваются дальше аналогичным образом до тех пор, пока на очередном шаге рекурсии в них не останется по одному домену.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Большую часть времени занимает сортировка массива координат вершин  &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, выполняемая на каждом шаге рекурсии. &lt;br /&gt;
Сортировка может быть выполнена любым способом, в зависимости от реализации. В дальнейшем положим, что используется алгоритм с оптимальной вычислительной сложностью &amp;lt;math&amp;gt;O(nlog_2{n})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Как записано и в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть метода составляют сортировки массивов координат вершин &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, выполняемые на каждом шаге рекурсии.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
# Вычисляются минимумы и максимумы по каждой из координат, определяющие параллелепипед, охватывающий вершины данной области. Далее запускается процесс рекурсии, на каждом шаге которого выполняется следующее:&lt;br /&gt;
## Определяется координата &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, вдоль которой параллелепипед, обрабатывающийся на данном этапе, имеет наибольшую протяженность.&lt;br /&gt;
## Определяется количество доменов, которое делится на данном этапе. В левую часть (вершины с меньшей координатой &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;) попадет половина доменов. Сначала набираются домены нулевого типа, потом, если они закончились, первого, и т.д. до получения нужного числа доменов в левой части. Подсчитывается общее число вершин n1, которое окажется в этих доменах. В правой части будут сформированы оставшиеся домены.&lt;br /&gt;
## Пусть все вершины в параллелепипеде имеют координаты &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, принадлежащие интервалу &amp;lt;math&amp;gt;[j_{min}, j_{max}]&amp;lt;/math&amp;gt;. Интервал делится на &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; равных малых интервалов. &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; – некоторая константа. Подсчитываются количества вершин, принадлежащие каждому малому интервалу. Исходя из того, что в левую часть должна попасть &amp;lt;math&amp;gt;n_1&amp;lt;/math&amp;gt; вершина с меньшей координатой &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, определяется, в какой малый интервал &amp;lt;math&amp;gt;[j_{from}, j_{to}]&amp;lt;/math&amp;gt; попадает медиана. Затем вершины из интервала &amp;lt;math&amp;gt;[j_{from}, j_{to}]&amp;lt;/math&amp;gt; записываются в отдельный массив, отсортированный по всем координатам. Определяется медиана – последняя вершина, которая попадет в левую часть.&lt;br /&gt;
## Если предполагается построение локальных деревьев, для вершины &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; двоичного дерева запоминаются данные о медиане: ее координаты, номер вершины медианы и номер координаты &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, по которой проводилось деление.&lt;br /&gt;
## Проводится разделение данных по аналогии с обменной сортировкой с разделением Хоару (быстрая сортировка), чтобы на следующих этапах просматривались только вершины из разбиваемой области. Два указателя, &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;end&amp;lt;/math&amp;gt;, выставляются на начало и на конец массива данных, соответственно. Вершина, на которую указывает указатель &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt;, сравнивается с медианой по всем координатам, и, если она попадает в левую часть параллелепипеда, указатель &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt; сдвигается к следующей вершине. Так до тех пор, пока указатель &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt; не остановится на вершине, которая должна попасть в правую часть. Указатель &amp;lt;math&amp;gt;end&amp;lt;/math&amp;gt; конца массива сдвигается влево до тех пор, пока не остановится на вершине, которая должна попасть в левую часть. Если указатель &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt; находится левее указателя &amp;lt;math&amp;gt;end&amp;lt;/math&amp;gt;, вершины, на которые указывают указатели, меняются местами, после чего указатель &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt; сдвигается вправо, а &amp;lt;math&amp;gt;end&amp;lt;/math&amp;gt; – влево.Если указатель &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt; все еще левее указателя &amp;lt;math&amp;gt;end&amp;lt;/math&amp;gt;, весь процесс повторяется снова. Если после выхода из цикла указатели указывают на одну и ту же вершину, она сравнивается с медианой по всем координатам, и если вершина попадает в левую часть, указатель &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt; сдвигается к следующей вершине. Указатель &amp;lt;math&amp;gt;begin&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;j&amp;lt;/math&amp;gt; приравнивается к координате &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; медианы. Передается число доменов каждого вида, которое будет в левой части. Номер вершины двоичного дерева, отвечающей за деление левой части, будет равным &amp;lt;math&amp;gt;2i&amp;lt;/math&amp;gt;. Правой части передается указатель &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt; в качестве нового указателя на массив данных и оставшееся число вершин. Минимальная координата &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; приравнивается к координате медианы. Передаются числа доменов каждого вида. Номер вершины двоичного дерева, отвечающей за деление правой части, будет равным &amp;lt;math&amp;gt;2i + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Перед делением каждой из частей проверяется, сколько доменов осталось в данной части. Если остался только один домен, то все вершины помещаются в данный домен. Домены считаются по порядку от номера &amp;lt;math&amp;gt;gr_0&amp;lt;/math&amp;gt; первого домена. Если предполагается построение локальных деревьев, в лист дерева записывается номер домена. Запоминается максимальный номер вершины. Если в части осталось больше одного домена, она отправляется на деление. &lt;br /&gt;
&lt;br /&gt;
[[file:bisection_1.jpg|thumb|center|700px|Рисунок 1. Пример координатной бисекции на три домена.&amp;lt;ref name=&amp;quot;G1&amp;quot;/&amp;gt;]]&lt;br /&gt;
Алгоритм работает только с координатами вершин и не учитывает связи между ними, что делает его экономичным по памяти.&amp;lt;ref name=&amp;quot;G2&amp;quot;/&amp;gt;&amp;lt;ref name=&amp;quot;Y&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Для разбиения графа с количеством вершин &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; методом рекурсивной координатной бисекции на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; доменов требуется:&lt;br /&gt;
* для каждого шага рекурсии:&lt;br /&gt;
** определить максимум и минимум координат, &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций сравнения,&lt;br /&gt;
** отсортировать подобласть по одной из координат, &amp;lt;math&amp;gt;O(nlog_2{n})&amp;lt;/math&amp;gt; операций сравнения.&lt;br /&gt;
Глубина рекурсии - &amp;lt;math&amp;gt;log_2{p}+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сравнения составляют &#039;&#039;основную часть алгоритма&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, алгоритм имеет последовательную сложность &amp;lt;math&amp;gt;O(n, p) = n \log_2{n} \log_2{p}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма&amp;lt;ref name=&amp;quot;V&amp;quot;&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. - СПб.: БХВ-Петербург, 2002. - 608 с.&amp;lt;/ref&amp;gt; в виде рисунка.&lt;br /&gt;
[[File:AepPhDGxoJDcFhdr.png|alt=information graph|thumb|center|900px|Рисунок 2. Информационный граф алгоритма. In - входные данные,LS - локальная сортировка, PS - параллельная сортировка с помощью сортировочной сести, D - декомпозиция, Out - выходные данные&amp;lt;ref name=&amp;quot;G1&amp;quot;/&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, соответствующих бисекции по процессам (LS и PS) и локальной бисекции на каждом процессе (D). Первая группа делится на подгруппы, каждая подгруппа содержит некоторое количество сетей параллельной сортировки (PS), каждая из которых может выполнятся независимо от других. Во второй же группе вершин все операции в одной вершине не зависят от других вершин.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Исходя из того, что метод является геометрическим, алгоритм обладает координатным параллелизмом. Таким образом структура параллельного алгоритма включает в себя следующие этапы&amp;lt;ref name=&amp;quot;G2&amp;quot;&amp;gt;Головченко Е.Н. Параллельный пакет декомпозиции больших сеток // Математическое моделирование. 2011. Т. 23. № 10. 3-18. URL: http://cyberleninka.ru/article/n/razbienie-bolshih-setok&amp;lt;/ref&amp;gt;: &lt;br /&gt;
# Начальное распределение вершин по процессорам. Начальное распределение может быть любым, например, в соответствии с порядковыми номерами вершин.&lt;br /&gt;
# Определение числа доменов, которые должны быть сформированы на каждом из процессоров, и количества вершин в них.&lt;br /&gt;
# Рекурсивная координатная бисекция вершин по процессорам. На каждом этапе сначала вычисляется координатная ось, вдоль которой область имеет наибольшую протяженность. Затем блок вершин бьется на две части перпендикулярно данной оси. Группа процессоров делится на две, далее каждая из групп делит свой блок вершин аналогичным образом. Для разделения блока вершин используется параллельная сортировка. После рекурсивной координатной бисекции вершин по процессорам на процессорах оказывается столько вершин, сколько должно быть в образуемых на них доменах.&lt;br /&gt;
# Локальная рекурсивная координатная бисекция вершин по доменам. Дальнейшее разбиение на домены проводится локально на каждом процессоре.&lt;br /&gt;
&lt;br /&gt;
Для разбиения графа &amp;lt;math&amp;gt;G=(V, E), |V|=n&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; доменов в параллельном варианте при количестве процессов &amp;lt;math&amp;gt;N_p&amp;lt;/math&amp;gt; требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* для бисекции по процессам &amp;amp;mdash; &amp;lt;math&amp;gt;log_2{N_p}&amp;lt;/math&amp;gt; пар ярусов, содержащих:&lt;br /&gt;
** локальную сортировку, при количестве вершин &amp;lt;math&amp;gt;n, \frac{n}{2}, \frac{n}{4},\ldots;&amp;lt;/math&amp;gt;&lt;br /&gt;
** параллельную сеть сортировки, при количестве элементов &amp;lt;math&amp;gt;n, \frac{n}{2}, \frac{n}{4},\ldots&amp;lt;/math&amp;gt;, при количестве процессов &amp;lt;math&amp;gt;N_p, \frac{N_p}{2}, \frac{N_p}{4},\ldots;&amp;lt;/math&amp;gt;&lt;br /&gt;
* один ярус, содержащий локальную бисекцию на каждом процессе для количества вершин &amp;lt;math&amp;gt;\frac{n}{N_p}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, параллельный вариант алгоритма обладает двухступенчатой структурой. При классификации по высоте ЯПФ его сложность &amp;amp;mdash; &amp;lt;math&amp;gt;O\left(\left[m \log_2{m} + \frac{1}{2} \log_2{n} (\log_2{n} + 1)\right]\log_2{N_p} + m \log_2{m} \log_2{p}\right)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m=\frac{n}{N_p}&amp;lt;/math&amp;gt;.&lt;br /&gt;
При классификации по ширине ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N_p)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Входные данные алгоритма: множество координат вершин &amp;lt;math&amp;gt;C = \{c_i\}&amp;lt;/math&amp;gt; графа &amp;lt;math&amp;gt;G = (V, E)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;c_i = (v_i^x, v_i^y, v_i^z)&amp;lt;/math&amp;gt; - координаты вершины &amp;lt;math&amp;gt;v_i \in V&amp;lt;/math&amp;gt;. Таким образом, множество координат вершин может быть передано как массив трёхмерных векторов. Число доменов &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; передается в виде натурального числа, не может превышать число вершин.&amp;lt;ref name=&amp;quot;G2&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество элементов массива входных данных может быть очень большим, например, алгоритм используется для нерегулярных сеток, содержащих &amp;lt;math&amp;gt;10^9&amp;lt;/math&amp;gt; и более вершин. В настоящее время такие сетки невозможно разместить в памяти одного процессора (на гексаэдральную сетку, состоящую из &amp;lt;math&amp;gt;1.2 \cdot 10^8&amp;lt;/math&amp;gt; ячеек, требуется порядка 200 ГБ), поэтому для декомпозиции нужен параллельный алгоритм.&amp;lt;ref name=&amp;quot;G1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Число процессоров, на котором будет считаться вычислительная задача, как правило, заранее неизвестно. Поэтому имеет смысл предварительно однократно разбить сетку на большое число микродоменов, а потом формировать из них домены. Количество микродоменов на несколько порядков меньше числа вершин, поэтому многократное разбиение микродоменов на домены быстрее многократного разбиения всей сетки.&lt;br /&gt;
&lt;br /&gt;
Выходные данные алгоритма: разбиение множества вершин &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; на заданное число &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; доменов &amp;lt;math&amp;gt;S_j&amp;lt;/math&amp;gt;. Эти данные могут быть записаны как массив четырехмерных векторов координат вершин, четвертой координатой будет номер домена, которому принадлежит вершина.&amp;lt;ref name=&amp;quot;G1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Алгоритм детерминирован в случае использования устойчивой сортировки вершин. Алгоритм устойчив, так как работает с целочисленными данными, ошибки округления отсутствуют.&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, равна &amp;lt;math&amp;gt;O(\log_2{n} \log_2{p})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин в графе, &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - количество доменов.&lt;br /&gt;
&lt;br /&gt;
Так как основной операцией алгоритма является сравнение целых чисел при сортировке, наблюдается дисбаланс арифметических операций по отношению к операциям обращения к памяти. Алгоритм обладает сбалансированностью операций между параллельными ветвями алгоритма, что следует из [[#condition1|условия &amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;]] - количество вершин на разных процессах примерно одинаково.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершины, соответствующей сети сортировки с номером &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, имеют степень &amp;lt;math&amp;gt;\frac{N_p}{2^k}, k = 0, 1,\ldots, \log_2{N_p}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это означает, что их степень убывает в ходе работы алгоритма от &amp;lt;math&amp;gt;N_p&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&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;
Проведём исследование масштабируемости параллельной реализации алгоритма разбиения графа методом рекурсивной координатной бисекции согласно [[Scalability methodology|методике]]. Исследование проводилось на суперкомпьютере [http://hpc.cs.msu.ru/bgp &amp;quot;BlueGene/P&amp;quot;]&amp;lt;ref name=&amp;quot;bgp&amp;quot;&amp;gt;Gilge, Megan. IBM system blue gene solution blue gene/Q application development. IBM Redbooks, 2014.&amp;lt;/ref&amp;gt;, с использованием библиотеки [https://trilinos.org/docs/dev/packages/zoltan2/doc/html/index.html Zoltan2].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
* число процессоров [1 : 512] с множителем 2; &lt;br /&gt;
* количество вершин в графе - &amp;lt;math&amp;gt;1.5 \cdot 10^7&amp;lt;/math&amp;gt;;&lt;br /&gt;
* количество доменов - &amp;lt;math&amp;gt;2048&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
* минимальная эффективность реализации &amp;lt;math&amp;gt;35%&amp;lt;/math&amp;gt;;&lt;br /&gt;
* максимальная эффективность реализации &amp;lt;math&amp;gt;94%&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Ускорение|ускорения]] и [[Глоссарий#Эффективность реализации|эффективности]] выбранной реализации алгоритма разбиения графа методом рекурсивной координатной бисекции в зависимости от числа процессоров.&lt;br /&gt;
&lt;br /&gt;
[[file:RCB_Speedup.png|thumb|center|700px|Рисунок 3. Ускорение алгоритма разбиения графа методом рекурсивной координатной бисекции в зависимости от числа процессоров.]]&lt;br /&gt;
[[file:RCB_Efficiency.png|thumb|center|700px|Рисунок 4. Эффективность алгоритма разбиения графа методом рекурсивной координатной бисекции в зависимости от числа процессоров.]]&lt;br /&gt;
&lt;br /&gt;
Построим оценку масштабируемости выбранной реализации алгоритма разбиения графа методом рекурсивной координатной бисекции.&lt;br /&gt;
* По числу процессов: &amp;lt;math&amp;gt;-0,0131&amp;lt;/math&amp;gt;. При увеличении числа процессов эффективность на рассмотренной области изменений параметров запуска уменьшается. Уменьшение эффективности на рассмотренной области работы параллельной программы объясняется быстрым ростом накладных расходов на организацию параллельного выполнения.&lt;br /&gt;
&lt;br /&gt;
[http://pastebin.com/Ljk8LPnd Исследованная параллельная реализация на языке C++.]&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;ref name=&amp;quot;G1&amp;quot;&amp;gt;Головченко Е.Н. Декомпозиция расчетных сеток для решения задач механики сплошных сред на высокопроиводительных вычислительных системах. Дисс ... канд. ф.-м.наук. Институт прикладной математики им. М. В. Келдыша РАН, г. Москва URL: http://keldysh.ru/council/3/D00202403/golovchenko_diss.pdf&amp;lt;/ref&amp;gt;: METIS, JOSTLE, SCOTCH, CHACO и PARTY. &lt;br /&gt;
К параллельным пакетам относятся PARMETIS (параллельная версия пакета METIS), JOSTLE, PT-SCOTCH (параллельная версия пакета SCOTCH) и ZOLTAN.&lt;br /&gt;
&lt;br /&gt;
ParMETIS и METIS распространяются свободно URL: http://glaros.dtc.umn.edu/gkhome/software .&lt;br /&gt;
&lt;br /&gt;
ZOLTAN - свободная лицензия, URL: http://www.cs.sandia.gov/~web1400/1400_download.html .&lt;br /&gt;
&lt;br /&gt;
Также алгоритм реализован в параллельном пакете GridSpiderPar&amp;lt;ref name=&amp;quot;Y&amp;quot;&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2012. – 328 с., илл. – (Серия «Суперкомпьютерное образование»), ISBN 978-5-211-06382-2 URL: http://lira.imamod.ru/ITTPMOPS/&amp;lt;/ref&amp;gt;, URL: http://lira.imamod.ru/FondProgramm/Decomposition/&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:%D0%A1%D0%B5%D1%80%D0%B3%D0%B5%D0%B9/%D0%A5%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B5%D0%BD%D1%83%D0%BB%D0%B5%D0%B2%D1%8B%D1%85_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B6%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B._%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B6%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%BD%D0%B0_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80&amp;diff=17873</id>
		<title>Участник:Сергей/Хранение ненулевых элементов разреженной матрицы. Умножение разреженной матрицы на вектор</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%D0%BA:%D0%A1%D0%B5%D1%80%D0%B3%D0%B5%D0%B9/%D0%A5%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B5%D0%BD%D1%83%D0%BB%D0%B5%D0%B2%D1%8B%D1%85_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B6%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B._%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B6%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%BD%D0%B0_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80&amp;diff=17873"/>
		<updated>2016-11-17T11:09:28Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор: [[U:Сергей|Герасимов Сергей]] (619)&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Разреженная матрица&#039;&#039;&#039; — это матрица с преимущественно нулевыми элементами. В противном случае, если бо́льшая часть элементов матрицы ненулевые, матрица считается плотной.&lt;br /&gt;
&lt;br /&gt;
Нет единства в определении того, какое именно количество ненулевых элементов делает матрицу разрежённой. Разные авторы предлагают различные варианты. Для матрицы порядка n число ненулевых элементов:&lt;br /&gt;
&lt;br /&gt;
~ есть O(n). Такое определение подходит разве что для теоретического анализа асимптотических свойств матричных алгоритмов;&lt;br /&gt;
&lt;br /&gt;
~ в каждой строке не превышает 10 в типичном случае;&lt;br /&gt;
&lt;br /&gt;
~ ограничено &amp;lt;math&amp;gt;n^{1+\gamma}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\gamma &amp;lt; 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Огромные разрежённые матрицы часто возникают при решении таких задач, как дифференциальное уравнение в частных производных.&lt;br /&gt;
&lt;br /&gt;
При хранении и преобразовании разрежённых матриц в компьютере бывает полезно, а часто и необходимо, использовать специальные алгоритмы и структуры данных, которые учитывают разрежённую структуру матрицы. Операции и алгоритмы, применяемые для работы с обычными, плотными матрицами, применительно к большим разрежённым матрицам работают относительно медленно и требуют значительных объёмов памяти. Однако разрежённые матрицы могут быть легко сжаты путём записи только своих ненулевых элементов, что снижает требования к компьютерной памяти.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Существуют различные форматы хранения разреженных матриц.&#039;&#039;&#039; Одни предназначены для хранения матриц специального вида (например, ленточных), другие обеспечивают работу с матрицами общего вида. Ниже рассмотрим некоторые весьма распространенные способы представления разреженных матриц.&lt;br /&gt;
&lt;br /&gt;
По-видимому, наиболее очевидным способом хранения произвольной разреженной матрицы является &#039;&#039;&#039;координатный формат&#039;&#039;&#039;: хранятся только ненулевые элементы матрицы, и их координаты (номера строк и столбцов). При данном подходе хранение матрицы A можно обеспечить в трех одномерных массивах:&lt;br /&gt;
&lt;br /&gt;
~ массив ненулевых элементов матрицы A (обозначим его как values);&lt;br /&gt;
&lt;br /&gt;
~ массив номеров строк матрицы A, соответствующих элементам массива values (обозначим его как rows);&lt;br /&gt;
&lt;br /&gt;
~ массив номеров столбцов матрицы A, соответствующих элементам массива values (обозначим его как cols);&lt;br /&gt;
&lt;br /&gt;
Данный способ представления называют полным, поскольку представлена вся матрица А, и неупорядоченным, поскольку элементы матрицы могут храниться в произвольном порядке.&lt;br /&gt;
&lt;br /&gt;
Хотя многие математические библиотеки поддерживают матрично-векторные операции в координатном формате, данный формат обеспечивает медленный доступ к элементам матрицы, и является затратным по используемой памяти. В рассмотренном выше примере избыточность по памяти образом проявляется в массиве rows, в котором строчные координаты хранятся неоптимальным образом.&lt;br /&gt;
&lt;br /&gt;
Перейдем далее к рассмотрению более экономных форматов хранения. &#039;&#039;&#039;Разреженный строчный формат&#039;&#039;&#039; - это одна из наиболее широко используемых схем хранения разреженных матриц. Эта схема предъявляет минимальные требования к памяти и в то же время оказывается очень удобной для нескольких важных операций над разреженными матрицами: сложения, умножения, перестановок строк и столбцов, транспонирования, решения линейных систем с разреженными матрицами коэффициентов как прямыми, так и итерационными методами и т. д.&lt;br /&gt;
&lt;br /&gt;
В соответствии с рассматриваемой схемой для хранения матрицы A требуется три одномерных массива:&lt;br /&gt;
&lt;br /&gt;
~ массив ненулевых элементов матрицы A, в котором они перечислены по строкам от первой до последней (обозначим его опять как values);&lt;br /&gt;
&lt;br /&gt;
~ массив номеров столбцов для соответствующих элементов массива values (обозначим его как cols);&lt;br /&gt;
&lt;br /&gt;
~ массив указателей позиций, с которых начинается описание очередной строки (обозначим его pointer). Описание k-й строки хранится в позициях с pointer[k]-й по (pointer[k+1]–1)-ю массивов values и cols. Если pointer[k]=pointer[k+1], то k-я строка пустая. Если матрица A состоит из n строк, то длина массива pointer будет n+1.&lt;br /&gt;
&lt;br /&gt;
Данный способ представления также является полным, и упорядоченным, поскольку элементы каждой строки хранятся в соответствии с возрастанием столбцовых индексов.&lt;br /&gt;
&lt;br /&gt;
Очевидно, что объем памяти, требуемый для хранения вектора pointer, значительно меньше, чем для хранения вектора rows. Более того, разреженный строчный формат обеспечивает эффективный доступ к строчкам матрицы; доступ к столбцам по прежнему затруднен. Поэтому предпочтительно использовать этот способ хранения в тех алгоритмах, в которых преобладают строчные операции.&lt;br /&gt;
&lt;br /&gt;
Существует также &#039;&#039;&#039;разреженный столбцовый формат&#039;&#039;&#039;, который строится аналогичным способом.&lt;br /&gt;
&lt;br /&gt;
Теперь, разобравшись со способами хранения разреженных матриц, можно перейти к &#039;&#039;алгоритму умножения разреженной матрицы на вектор&#039;&#039;. Умножение матрицы на вектор является подзадачей для нахождения решений СЛАУ итерационными методами.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Пусть матрица размером &amp;lt;math&amp;gt;N\times M&amp;lt;/math&amp;gt; содержит в себе &amp;lt;math&amp;gt;NZ&amp;lt;/math&amp;gt; ненулевых элементов, где &amp;lt;math&amp;gt;NZ\ll N^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Условимся использовать строчный формат хранения матрицы, который описан выше.&lt;br /&gt;
&lt;br /&gt;
На входе у нас 4 массива: val(ненулевые элементы матрицы), col(номера столбцов), row(массив указателей) и vec(вектор, на который мы умножаем матрицу).&lt;br /&gt;
&lt;br /&gt;
На выходе получим вектор out.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;out_i = \sum_{j=row_i}^{row_{i+1} - 1} val_j \cdot vec_{col_j}, \ i=\overline{0,N-1}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;N&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;
&amp;lt;math&amp;gt;out_i = \sum_{j=row_i}^{row_{i+1} - 1} val_j \cdot vec_{col_j}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итого: &amp;lt;math&amp;gt;NZ&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; сложений(&amp;lt;math&amp;gt;NZ-N&amp;lt;x&amp;lt;NZ-1&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;
[[Файл:sparse.jpg|thumb|center|500px|Рис.1 Умножение разреженной матрицы на вектор]]&lt;br /&gt;
&lt;br /&gt;
Элементы из массива val умножаются на элементы из массива vec с соответствующим индексом. Черным отмечены ненулевые элементы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Предполагается, что матрица представлена в разреженном строчном формате.&lt;br /&gt;
&lt;br /&gt;
    for(i=0; i&amp;lt;N; i++)&lt;br /&gt;
    {&lt;br /&gt;
        out[i]=0;&lt;br /&gt;
        for(j=row[i]; j&amp;lt;row[i+1]; j++)&lt;br /&gt;
        {&lt;br /&gt;
            out[i] += val[j]*vec[col[j]];&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Внешний цикл - цикл по элементам выходного вектора. Внутренний - цикл по строкам разреженной матрицы.&lt;br /&gt;
Во внутреннем цикле реализовано накопление сумм произведений в выходной элемент.&lt;br /&gt;
Индекс &#039;&#039;j&#039;&#039; показывает с какого по какой элемент нужно считать из &#039;&#039;val&#039;&#039; (вектор с ненулевыми значениями матрицы), а также позволяет определить в каких столбцах расположены эти значения в матрице (с помощью вектора &#039;&#039;col&#039;&#039;).&lt;br /&gt;
Минимальное и максимальное значение &#039;&#039;j&#039;&#039; узнается из вектора &#039;&#039;row&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bullet \ NZ&amp;lt;/math&amp;gt; умножений &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bullet \ x&amp;lt;/math&amp;gt; сложений(&amp;lt;math&amp;gt;NZ-N&amp;lt;x&amp;lt;NZ-1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Всего &amp;lt;math&amp;gt;2NZ&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;NZ&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;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция вычисляет функцию &amp;lt;math&amp;gt;a \cdot b&amp;lt;/math&amp;gt;. Координаты области следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;0&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;\cdot&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt;, принимая все натуральные значения,&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;k = k(i) = row[i+1]-row[i]&amp;lt;/math&amp;gt;. (На рисунке вместо обозначения &#039;&#039;row&#039;&#039; использовано обозначение &#039;&#039;r&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Результаты операции - &#039;&#039;&#039;промежуточные&#039;&#039;&#039; данные алгоритма.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция вычисляет функцию &amp;lt;math&amp;gt;a + b&amp;lt;/math&amp;gt;. &lt;br /&gt;
Координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;0&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;\cdot&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;k-1&amp;lt;/math&amp;gt;, принимая все натуральные значения,&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;k = k(i) = row[i+1]-row[i]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результат операции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;j &amp;lt; k - 1&amp;lt;/math&amp;gt; является &#039;&#039;&#039;промежуточным&#039;&#039;&#039; данным алгоритма;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;j = k - 1&amp;lt;/math&amp;gt; является &#039;&#039;&#039;выходным&#039;&#039;&#039; данным &amp;lt;math&amp;gt;out[i]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Описанный граф изображен на Рис.2. Здесь вершины первой группы обозначены красным цветом и отмечены знаком умножения, вершины второй - зелёным цветом и знаком сложения. Вершины, соответствующие входным данным обозначены белым цветом и выходным - синим.&lt;br /&gt;
&lt;br /&gt;
[[Файл:new_sparse.png|thumb|center|1000px|Рис.2 Умножение разреженной матрицы на вектор. Информационный граф]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
При наличии бесконечного числа процессоров для умножения разреженной матрицы на вектор потребуется:&lt;br /&gt;
&lt;br /&gt;
~ 1 ярус умножений&lt;br /&gt;
&lt;br /&gt;
~ &amp;lt;math&amp;gt;Z-1&amp;lt;/math&amp;gt; операция сложения, где Z - максимальное число ненулевых элементов в строке.&lt;br /&gt;
&lt;br /&gt;
Максимальное число требуемых процессоров - NZ.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
~ массив ненулевых элементов матрицы A, в котором они перечислены по строкам от первой до последней (обозначим его как val);&lt;br /&gt;
&lt;br /&gt;
~ массив номеров столбцов для соответствующих элементов массива val (обозначим его как col);&lt;br /&gt;
&lt;br /&gt;
~ массив указателей позиций, с которых начинается описание очередной строки (обозначим его row);&lt;br /&gt;
&lt;br /&gt;
~ вектор, на который будет умножаться матрица (обозначим его vec).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Для матрицы размером &amp;lt;math&amp;gt;N\times M&amp;lt;/math&amp;gt;, содержащей в себе &amp;lt;math&amp;gt;NZ&amp;lt;/math&amp;gt; ненулевых элементов, где &amp;lt;math&amp;gt;NZ\ll N^2&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
~ вектор val - NZ элементов;&lt;br /&gt;
&lt;br /&gt;
~ вектор col - NZ элементов;&lt;br /&gt;
&lt;br /&gt;
~ вектор row - N+1 элемент;&lt;br /&gt;
&lt;br /&gt;
~ вектор vec - M элементов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Вектор out размером N.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является &#039;&#039;линейным&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных – чуть меньше &#039;&#039;единицы&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм обладает свойством детерминированности.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
[[Файл:plot_more_points.png|thumb|center|1000px|Рис.3 Умножение разреженной матрицы на вектор. Масштабируемость]]&lt;br /&gt;
&lt;br /&gt;
[[Файл:plot_eff_new.png|thumb|center|1000px|Рис.4 Умножение разреженной матрицы на вектор. Эффективность]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Эффективная работа с разреженными матрицами реализована во многих библиотеках, например, [https://software.intel.com/en-us/intel-mkl Intel Math Kernel Library], базирующуюся на библиотеках BLAS и LAPACK, также математических пакет [http://matlab.ru/products/matlab Matlab] имеет собственную реализацию.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
[1] Писсанецки С. Технология разреженных матриц. - М.: Мир, 1988. — 410 с.&lt;br /&gt;
&lt;br /&gt;
[2] https://software.intel.com/sites/default/files/m/d/4/1/d/8/LW_SparseMM_ppt.pdf&lt;/div&gt;</summary>
		<author><name>Dan</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:%D0%A1%D0%B5%D1%80%D0%B3%D0%B5%D0%B9&amp;diff=17872</id>
		<title>Обсуждение участника:Сергей</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:%D0%A1%D0%B5%D1%80%D0%B3%D0%B5%D0%B9&amp;diff=17872"/>
		<updated>2016-11-17T11:08:33Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Правки =&lt;br /&gt;
Не удаляйте замечания&lt;br /&gt;
	&lt;br /&gt;
= Пункт 2.4 =&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 14:08, 17 ноября 2016 (MSK) необходимо доработать:&lt;br /&gt;
&lt;br /&gt;
Требования были такие: &lt;br /&gt;
- Реализация: полностью собственная или обращение к библиотечной функции (Intel MKL, PETSc, FFTW, ScaLAPACK). В любом случае, текст исследуемой программы должен быть представлен в отчете. &lt;br /&gt;
- Компьютерная платформа может быть любой (Ломоносов, BlueGene или что-то иное). Описание компьютерной платформы должно быть в отчете. &lt;br /&gt;
- Должен быть представлен график сильной масштабируемости (зависимости производительности от числа процессов; если при этом&lt;br /&gt;
ещё и зависимость от размера задачи - это только в плюс). График должен выглядеть пристойно и понятно, оси и единицы измерения должны быть подписаны. К графику обязательно должны быть словесные пояснения! Требовалось подобрать такие размеры задачи и числа процессоров, чтобы отразить на графике характерные точки, описывающие свойства алгоритма и программы.&lt;/div&gt;</summary>
		<author><name>Dan</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:%D0%AE%D0%BB%D0%B8%D1%8F_%D0%96%D0%BE%D1%81%D0%B0%D0%BD&amp;diff=17870</id>
		<title>Обсуждение участника:Юлия Жосан</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:%D0%AE%D0%BB%D0%B8%D1%8F_%D0%96%D0%BE%D1%81%D0%B0%D0%BD&amp;diff=17870"/>
		<updated>2016-11-17T11:03:30Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Пункт 1.10 =&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 14:03, 17 ноября 2016 (MSK) Отсутствует оценка вычислительной мощности&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 2.4 =&lt;br /&gt;
[[Участник:Dan|Dan]] ([[Обсуждение участника:Dan|обсуждение]]) 14:03, 17 ноября 2016 (MSK) отсутствует исследование масштабируемости&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:%D0%A1%D0%B5%D1%80%D0%B3%D0%B5%D0%B9/%D0%A5%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B5%D0%BD%D1%83%D0%BB%D0%B5%D0%B2%D1%8B%D1%85_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B6%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B._%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B6%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%BD%D0%B0_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80&amp;diff=17291</id>
		<title>Участник:Сергей/Хранение ненулевых элементов разреженной матрицы. Умножение разреженной матрицы на вектор</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%D0%BA:%D0%A1%D0%B5%D1%80%D0%B3%D0%B5%D0%B9/%D0%A5%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B5%D0%BD%D1%83%D0%BB%D0%B5%D0%B2%D1%8B%D1%85_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B6%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B._%D0%A3%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D0%B6%D0%B5%D0%BD%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%BD%D0%B0_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80&amp;diff=17291"/>
		<updated>2016-11-15T14:39:59Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; {{Assignment|Dan}}&lt;br /&gt;
&lt;br /&gt;
Автор: [[U:Сергей|Герасимов Сергей]] (619)&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Разреженная матрица&#039;&#039;&#039; — это матрица с преимущественно нулевыми элементами. В противном случае, если бо́льшая часть элементов матрицы ненулевые, матрица считается плотной.&lt;br /&gt;
&lt;br /&gt;
Нет единства в определении того, какое именно количество ненулевых элементов делает матрицу разрежённой. Разные авторы предлагают различные варианты. Для матрицы порядка n число ненулевых элементов:&lt;br /&gt;
&lt;br /&gt;
~ есть O(n). Такое определение подходит разве что для теоретического анализа асимптотических свойств матричных алгоритмов;&lt;br /&gt;
&lt;br /&gt;
~ в каждой строке не превышает 10 в типичном случае;&lt;br /&gt;
&lt;br /&gt;
~ ограничено &amp;lt;math&amp;gt;n^{1+\gamma}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\gamma &amp;lt; 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Огромные разрежённые матрицы часто возникают при решении таких задач, как дифференциальное уравнение в частных производных.&lt;br /&gt;
&lt;br /&gt;
При хранении и преобразовании разрежённых матриц в компьютере бывает полезно, а часто и необходимо, использовать специальные алгоритмы и структуры данных, которые учитывают разрежённую структуру матрицы. Операции и алгоритмы, применяемые для работы с обычными, плотными матрицами, применительно к большим разрежённым матрицам работают относительно медленно и требуют значительных объёмов памяти. Однако разрежённые матрицы могут быть легко сжаты путём записи только своих ненулевых элементов, что снижает требования к компьютерной памяти.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Существуют различные форматы хранения разреженных матриц.&#039;&#039;&#039; Одни предназначены для хранения матриц специального вида (например, ленточных), другие обеспечивают работу с матрицами общего вида. Ниже рассмотрим некоторые весьма распространенные способы представления разреженных матриц.&lt;br /&gt;
&lt;br /&gt;
По-видимому, наиболее очевидным способом хранения произвольной разреженной матрицы является &#039;&#039;&#039;координатный формат&#039;&#039;&#039;: хранятся только ненулевые элементы матрицы, и их координаты (номера строк и столбцов). При данном подходе хранение матрицы A можно обеспечить в трех одномерных массивах:&lt;br /&gt;
&lt;br /&gt;
~ массив ненулевых элементов матрицы A (обозначим его как values);&lt;br /&gt;
&lt;br /&gt;
~ массив номеров строк матрицы A, соответствующих элементам массива values (обозначим его как rows);&lt;br /&gt;
&lt;br /&gt;
~ массив номеров столбцов матрицы A, соответствующих элементам массива values (обозначим его как cols);&lt;br /&gt;
&lt;br /&gt;
Данный способ представления называют полным, поскольку представлена вся матрица А, и неупорядоченным, поскольку элементы матрицы могут храниться в произвольном порядке.&lt;br /&gt;
&lt;br /&gt;
Хотя многие математические библиотеки поддерживают матрично-векторные операции в координатном формате, данный формат обеспечивает медленный доступ к элементам матрицы, и является затратным по используемой памяти. В рассмотренном выше примере избыточность по памяти образом проявляется в массиве rows, в котором строчные координаты хранятся неоптимальным образом.&lt;br /&gt;
&lt;br /&gt;
Перейдем далее к рассмотрению более экономных форматов хранения. &#039;&#039;&#039;Разреженный строчный формат&#039;&#039;&#039; - это одна из наиболее широко используемых схем хранения разреженных матриц. Эта схема предъявляет минимальные требования к памяти и в то же время оказывается очень удобной для нескольких важных операций над разреженными матрицами: сложения, умножения, перестановок строк и столбцов, транспонирования, решения линейных систем с разреженными матрицами коэффициентов как прямыми, так и итерационными методами и т. д.&lt;br /&gt;
&lt;br /&gt;
В соответствии с рассматриваемой схемой для хранения матрицы A требуется три одномерных массива:&lt;br /&gt;
&lt;br /&gt;
~ массив ненулевых элементов матрицы A, в котором они перечислены по строкам от первой до последней (обозначим его опять как values);&lt;br /&gt;
&lt;br /&gt;
~ массив номеров столбцов для соответствующих элементов массива values (обозначим его как cols);&lt;br /&gt;
&lt;br /&gt;
~ массив указателей позиций, с которых начинается описание очередной строки (обозначим его pointer). Описание k-й строки хранится в позициях с pointer[k]-й по (pointer[k+1]–1)-ю массивов values и cols. Если pointer[k]=pointer[k+1], то k-я строка пустая. Если матрица A состоит из n строк, то длина массива pointer будет n+1.&lt;br /&gt;
&lt;br /&gt;
Данный способ представления также является полным, и упорядоченным, поскольку элементы каждой строки хранятся в соответствии с возрастанием столбцовых индексов.&lt;br /&gt;
&lt;br /&gt;
Очевидно, что объем памяти, требуемый для хранения вектора pointer, значительно меньше, чем для хранения вектора rows. Более того, разреженный строчный формат обеспечивает эффективный доступ к строчкам матрицы; доступ к столбцам по прежнему затруднен. Поэтому предпочтительно использовать этот способ хранения в тех алгоритмах, в которых преобладают строчные операции.&lt;br /&gt;
&lt;br /&gt;
Существует также &#039;&#039;&#039;разреженный столбцовый формат&#039;&#039;&#039;, который строится аналогичным способом.&lt;br /&gt;
&lt;br /&gt;
Теперь, разобравшись со способами хранения разреженных матриц, можно перейти к &#039;&#039;алгоритму умножения разреженной матрицы на вектор&#039;&#039;. Умножение матрицы на вектор является подзадачей для нахождения решений СЛАУ итерационными методами.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Пусть матрица размером &amp;lt;math&amp;gt;N\times M&amp;lt;/math&amp;gt; содержит в себе &amp;lt;math&amp;gt;NZ&amp;lt;/math&amp;gt; ненулевых элементов, где &amp;lt;math&amp;gt;NZ\ll N^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Условимся использовать строчный формат хранения матрицы, который описан выше.&lt;br /&gt;
&lt;br /&gt;
На входе у нас 4 массива: val(ненулевые элементы матрицы), col(номера столбцов), row(массив указателей) и vec(вектор, на который мы умножаем матрицу).&lt;br /&gt;
&lt;br /&gt;
На выходе получим вектор out.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;out_i = \sum_{j=row_i}^{row_{i+1} - 1} val_j \cdot vec_{col_j}, \ i=\overline{0,N-1}&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;N&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;
&amp;lt;math&amp;gt;out_i = \sum_{j=row_i}^{row_{i+1} - 1} val_j \cdot vec_{col_j}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итого: &amp;lt;math&amp;gt;NZ&amp;lt;/math&amp;gt; умножений + &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; сложений(&amp;lt;math&amp;gt;NZ-N&amp;lt;x&amp;lt;NZ-1&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;
[[Файл:sparse.jpg|thumb|center|500px|Рис.1 Умножение разреженной матрицы на вектор]]&lt;br /&gt;
&lt;br /&gt;
Элементы из массива val умножаются на элементы из массива vec с соответствующим индексом. Черным отмечены ненулевые элементы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Предполагается, что матрица представлена в разреженном строчном формате.&lt;br /&gt;
&lt;br /&gt;
    for(i=0; i&amp;lt;N; i++)&lt;br /&gt;
    {&lt;br /&gt;
        out[i]=0;&lt;br /&gt;
        for(j=row[i]; j&amp;lt;row[i+1]; j++)&lt;br /&gt;
        {&lt;br /&gt;
            out[i] += val[j]*vec[col[j]];&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Внешний цикл - цикл по элементам выходного вектора. Внутренний - цикл по строкам разреженной матрицы.&lt;br /&gt;
Во внутреннем цикле реализовано накопление сумм произведений в выходной элемент.&lt;br /&gt;
Индекс &#039;&#039;j&#039;&#039; показывает с какого по какой элемент нужно считать из &#039;&#039;val&#039;&#039; (вектор с ненулевыми значениями матрицы), а также позволяет определить в каких столбцах расположены эти значения в матрице (с помощью вектора &#039;&#039;col&#039;&#039;).&lt;br /&gt;
Минимальное и максимальное значение &#039;&#039;j&#039;&#039; узнается из вектора &#039;&#039;row&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bullet \ NZ&amp;lt;/math&amp;gt; умножений &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bullet \ x&amp;lt;/math&amp;gt; сложений(&amp;lt;math&amp;gt;NZ-N&amp;lt;x&amp;lt;NZ-1&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Всего &amp;lt;math&amp;gt;2NZ&amp;lt;/math&amp;gt; операций, где &amp;lt;math&amp;gt;NZ&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;
&#039;&#039;&#039;Первая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция вычисляет функцию &amp;lt;math&amp;gt;a \cdot b&amp;lt;/math&amp;gt;. Координаты области следующие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;0&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;\cdot&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt; k &amp;lt;/math&amp;gt;, принимая все натуральные значения,&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;k = k(i) = row[i+1]-row[i]&amp;lt;/math&amp;gt;. (На рисунке вместо обозначения &#039;&#039;row&#039;&#039; использовано обозначение &#039;&#039;r&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
Результаты операции - &#039;&#039;&#039;промежуточные&#039;&#039;&#039; данные алгоритма.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вторая&#039;&#039;&#039; группа вершин расположена в двумерной области, соответствующая ей операция вычисляет функцию &amp;lt;math&amp;gt;a + b&amp;lt;/math&amp;gt;. &lt;br /&gt;
Координаты области таковы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;0&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;\cdot&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; — меняется в диапазоне от &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;k-1&amp;lt;/math&amp;gt;, принимая все натуральные значения,&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;k = k(i) = row[i+1]-row[i]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Результат операции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;j &amp;lt; k - 1&amp;lt;/math&amp;gt; является &#039;&#039;&#039;промежуточным&#039;&#039;&#039; данным алгоритма;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\cdot&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;j = k - 1&amp;lt;/math&amp;gt; является &#039;&#039;&#039;выходным&#039;&#039;&#039; данным &amp;lt;math&amp;gt;out[i]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Описанный граф изображен на Рис.2. Здесь вершины первой группы обозначены красным цветом и отмечены знаком умножения, вершины второй - зелёным цветом и знаком сложения. Вершины, соответствующие входным данным обозначены белым цветом и выходным - синим.&lt;br /&gt;
&lt;br /&gt;
[[Файл:new_sparse.png|thumb|center|1000px|Рис.2 Умножение разреженной матрицы на вектор. Информационный граф]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
При наличии бесконечного числа процессоров для умножения разреженной матрицы на вектор потребуется:&lt;br /&gt;
&lt;br /&gt;
~ 1 ярус умножений&lt;br /&gt;
&lt;br /&gt;
~ &amp;lt;math&amp;gt;Z-1&amp;lt;/math&amp;gt; операция сложения, где Z - максимальное число ненулевых элементов в строке.&lt;br /&gt;
&lt;br /&gt;
Максимальное число требуемых процессоров - NZ.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
~ массив ненулевых элементов матрицы A, в котором они перечислены по строкам от первой до последней (обозначим его как val);&lt;br /&gt;
&lt;br /&gt;
~ массив номеров столбцов для соответствующих элементов массива val (обозначим его как col);&lt;br /&gt;
&lt;br /&gt;
~ массив указателей позиций, с которых начинается описание очередной строки (обозначим его row);&lt;br /&gt;
&lt;br /&gt;
~ вектор, на который будет умножаться матрица (обозначим его vec).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Для матрицы размером &amp;lt;math&amp;gt;N\times M&amp;lt;/math&amp;gt;, содержащей в себе &amp;lt;math&amp;gt;NZ&amp;lt;/math&amp;gt; ненулевых элементов, где &amp;lt;math&amp;gt;NZ\ll N^2&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
~ вектор val - NZ элементов;&lt;br /&gt;
&lt;br /&gt;
~ вектор col - NZ элементов;&lt;br /&gt;
&lt;br /&gt;
~ вектор row - N+1 элемент;&lt;br /&gt;
&lt;br /&gt;
~ вектор vec - M элементов.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Вектор out размером N.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов, как хорошо видно, является &#039;&#039;линейным&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных – чуть меньше &#039;&#039;единицы&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Данный алгоритм обладает свойством детерминированности.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Эффективная работа с разреженными матрицами реализована во многих библиотеках, например, [https://software.intel.com/en-us/intel-mkl Intel Math Kernel Library], базирующуюся на библиотеках BLAS и LAPACK, также математических пакет [http://matlab.ru/products/matlab Matlab] имеет собственную реализацию.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
[1] Писсанецки С. Технология разреженных матриц. - М.: Мир, 1988. — 410 с.&lt;br /&gt;
&lt;br /&gt;
[2] https://software.intel.com/sites/default/files/m/d/4/1/d/8/LW_SparseMM_ppt.pdf&lt;/div&gt;</summary>
		<author><name>Dan</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:%D0%A1%D0%B5%D1%80%D0%B3%D0%B5%D0%B9&amp;diff=17290</id>
		<title>Обсуждение участника:Сергей</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:%D0%A1%D0%B5%D1%80%D0%B3%D0%B5%D0%B9&amp;diff=17290"/>
		<updated>2016-11-15T14:39:30Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Правки =&lt;br /&gt;
Не удаляйте замечания&lt;br /&gt;
	&lt;br /&gt;
= Содержание =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; Следует добавить содержание (рубрикация по разделам) как в шаблоне.&lt;br /&gt;
 		 	&lt;br /&gt;
= Пункт 1 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; Все пункты должны именоваться строго по шаблону. например, в данном случае, первый уровень - просто: &amp;quot;Свойства и структура алгоритмов&amp;quot;&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.3 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; Лучше избегать ссылок на соседние пункты. Подразделы д.б. самодостаточны.&lt;br /&gt;
 &lt;br /&gt;
= Пункт 1.4 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; &#039;&#039;Подпункты должны быть самодостаточны. Приведите схему или опишите словами. Приведенного описания недостаточно.&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Следует просто привести описание макроструктуры, без ссылки на другие пункты.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.5 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; &#039;&#039;Пункты должны быть самодостаточны, расширьте описание.&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Добавить описание к псевдокоду.&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.6 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; Указать итоговую сложность.&lt;br /&gt;
 &lt;br /&gt;
= Пункт 1.7 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; &#039;&#039;Приведенная схема не является информационным графом, можно ее перенести в раздел макроструктуры, наверное. В п.1.7 необходимо привести информационный граф.&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Оформить как рисунок с номером и подписью. Если рисунок заимствован, надо дать ссылку на источник.&lt;br /&gt;
&lt;br /&gt;
= Пункт 2 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; Аналогично, именование пункта д.б. по шаблону.&lt;br /&gt;
&lt;br /&gt;
= Пункты 2.1-2.6 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; Добавить заголовки. Содержимое подпунктов можно не заполнять.&lt;br /&gt;
&lt;br /&gt;
= Пункт 2.7 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; Добавить ссылки на реализации.&lt;br /&gt;
 &lt;br /&gt;
= Литература =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; Отсутствует раздел источников, необходимо добавить.&lt;/div&gt;</summary>
		<author><name>Dan</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:Margarita.gabdullina&amp;diff=16861</id>
		<title>Обсуждение участника:Margarita.gabdullina</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:Margarita.gabdullina&amp;diff=16861"/>
		<updated>2016-11-14T07:30:54Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Вклад = &lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; Необходимо явно указать вклад каждого соавтора.&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.5 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; Если рисунок не собственный, надо дать ссылку на источник.&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.7 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
+/-Граф следует снабдить пояснением.&lt;br /&gt;
+Рисунок следует оформить как рисунок, с номером. Если заимствован, дать ссылку на источник.&lt;br /&gt;
&lt;br /&gt;
Приведенный рисунок представляет собой некую схему, а требуется привести информационный граф.&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.10 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; Явно не сказано про мощность алгоритма.&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:Ilya4870/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%80%D0%B0%D0%B7%D0%B1%D0%B8%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D1%80%D0%B0%D1%84%D0%B0_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D0%B2%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%BE%D1%80%D0%B4%D0%B8%D0%BD%D0%B0%D1%82%D0%BD%D0%BE%D0%B9_%D0%B1%D0%B8%D1%81%D0%B5%D0%BA%D1%86%D0%B8%D0%B8&amp;diff=16860</id>
		<title>Участник:Ilya4870/Алгоритм разбиения графа методом рекурсивной координатной бисекции</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%D0%BA:Ilya4870/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D1%80%D0%B0%D0%B7%D0%B1%D0%B8%D0%B5%D0%BD%D0%B8%D1%8F_%D0%B3%D1%80%D0%B0%D1%84%D0%B0_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%BC_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D0%B2%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%BE%D1%80%D0%B4%D0%B8%D0%BD%D0%B0%D1%82%D0%BD%D0%BE%D0%B9_%D0%B1%D0%B8%D1%81%D0%B5%D0%BA%D1%86%D0%B8%D0%B8&amp;diff=16860"/>
		<updated>2016-11-14T07:30:18Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Dan}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: Габдуллина М.И. (1.1, 1.3, 1.5, 1.9, 2.7), Урюпов И.В. (1.2, 1.4, 1.6, 1.7, 1.8, 1.10), группа м218.&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Задача рациональной декомпозиции расчетных сеток возникает при численном моделировании на высокопроизводительных вычислительных системах проблем механики сплошных сред, импульсной энергетики, электродинамики и многих других. Такие задачи сводятся к более общей задачи - разбиение вершин графа. Оптимальным считается разбиение на домены, при котором выровнен суммарный вес вершин в доменах и минимизирован суммарный вес разрезанных ребер (разрезанное ребро – ребро, соединяющее вершины из разных доменов). Одним из методов разбиения вершин графа на равные по мощности блоки является метод рекурсивной координатной бисекции.&amp;lt;ref name=&amp;quot;G1&amp;quot;/&amp;gt;&amp;lt;ref name=&amp;quot;G2&amp;quot;/&amp;gt;&amp;lt;ref name=&amp;quot;Y&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На каждом этапе рекурсивной бисекции область разбивается на две части.&lt;br /&gt;
Соотношение размеров частей зависит от количества доменов, которые&lt;br /&gt;
должны быть образованы в каждой из частей. Полученные подобласти разбиваются дальше аналогичным образом до тех пор, пока в подобластях не останется по одному домену. При рекурсивной координатной бисекции на этапе разбиения выбирается координатная ось, вдоль которой область имеет наибольшую протяженность. Область разбивается перпендикулярно полученной оси.&lt;br /&gt;
Достоинством данного метода является то, что при разбиении на равные домены числа вершин в получаемых доменах отличаются не больше, чем на единицу. Другими достоинствами являются экономичное использование памяти и относительная быстрота работы.&amp;lt;ref name=&amp;quot;G1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;G = (V,E)&amp;lt;/math&amp;gt; – неориентированный граф, где &amp;lt;math&amp;gt;V = \{v_i\}&amp;lt;/math&amp;gt; – множество вершин, &amp;lt;math&amp;gt;E = \{e_{ij}\}&amp;lt;/math&amp;gt; – множество рёбер. И вершины, и рёбра, имеют целочисленные веса &amp;lt;math&amp;gt;|v_i|&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;|e_{ij}|&amp;lt;/math&amp;gt;, соответственно.&lt;br /&gt;
&lt;br /&gt;
Декомпозиция является отображением множества вершин &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; на заданное число &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; доменов &amp;lt;math&amp;gt;S_j&amp;lt;/math&amp;gt; такое, что каждая вершина &amp;lt;math&amp;gt;v_i&amp;lt;/math&amp;gt; принадлежит некоторому домену &amp;lt;math&amp;gt;S_j&amp;lt;/math&amp;gt;, и &amp;lt;math&amp;gt;S_k \cap S_m = \emptyset&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммарный вес вершин в домене &amp;lt;math&amp;gt;S_j&amp;lt;/math&amp;gt; равен сумме весов вершин, принадлежащих этому домену:&lt;br /&gt;
&amp;lt;math&amp;gt;|S_j| = \sum_{i}{|v_i|}, v_i \in S_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Суммарный вес разрезанных рёбер равен сумме весов рёбер, соединяющих вершины из разных доменов:&lt;br /&gt;
&amp;lt;math&amp;gt;|E_c|=\sum_{ij}{|e_ij|}, v_i \in S_k, v_j \in S_m, k &amp;lt; m&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Каждый домен &amp;lt;math&amp;gt;S_j&amp;lt;/math&amp;gt; является некоторым подграфом &amp;lt;math&amp;gt;G^j = (V^j, E^j)&amp;lt;/math&amp;gt; графа &amp;lt;math&amp;gt;G = (V, E)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;V^j \subseteq V, E^j \subseteq E&amp;lt;/math&amp;gt;.&lt;br /&gt;
Домен является связным, если его граф состоит из одной компоненты связности, то есть между любой парой вершин этого графа существует как минимум один путь.&lt;br /&gt;
&lt;br /&gt;
Требуется найти такое разбиение множества вершин &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; на заданное число &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; связных доменов &amp;lt;math&amp;gt;S_j&amp;lt;/math&amp;gt;, при котором&amp;lt;ref name=&amp;quot;G1&amp;quot;/&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;div style=&amp;quot;max-width: 50%;&amp;quot;&amp;gt;выровнен суммарный вес вершин в доменах: &amp;lt;math&amp;gt;|S_j| \approx |V|/p&amp;lt;/math&amp;gt;,&amp;lt;span id=&amp;quot;condition1&amp;quot; style=&amp;quot;float: right;&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;div style=&amp;quot;max-width: 50%;&amp;quot;&amp;gt;минимизирован суммарный вес разрезанных рёбер: &amp;lt;math&amp;gt;min(|E_c|)&amp;lt;/math&amp;gt;.&amp;lt;span id=&amp;quot;condition2&amp;quot; style=&amp;quot;float: right;&amp;quot;&amp;gt;&amp;lt;math&amp;gt;(2)&amp;lt;/math&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Используя обозначения выше, определим:&lt;br /&gt;
&lt;br /&gt;
* Входные данные алгоритма: множество координат вершин &amp;lt;math&amp;gt;C = \{c_i\}&amp;lt;/math&amp;gt; графа &amp;lt;math&amp;gt;G = (V, E)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;c_i = (v_i^x, v_i^y, v_i^z)&amp;lt;/math&amp;gt; - координаты вершины &amp;lt;math&amp;gt;v_i \in V&amp;lt;/math&amp;gt;, число доменов &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Выходные данные алгоритма: разбиение множества вершин &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; на заданное число &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; доменов &amp;lt;math&amp;gt;S_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Основные этапы алгоритма:&lt;br /&gt;
&lt;br /&gt;
* вычисляются протяжённости осей: &amp;lt;math&amp;gt;l_k = |max(v_i^k) - min(v_i^k)|&amp;lt;/math&amp;gt; для &amp;lt;math&amp;gt;k = x, y, z&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
* производится сортировка множества &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; по координате, соответствующей наибольшей &amp;lt;math&amp;gt;l_k&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
* множество &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; разбивается на две части в соответствии с новым порядком элементов, то есть перпендикулярно координатной оси, вдоль которой она имеет наибольшую протяжённость; соотношение размеров частей зависит от количества доменов, которые должны быть образованы в каждой из частей,&lt;br /&gt;
&lt;br /&gt;
* полученные подмножества разбиваются дальше аналогичным образом до тех пор, пока на очередном шаге рекурсии в них не останется по одному домену.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Большую часть времени занимает сортировка массива координат вершин  &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, выполняемая на каждом шаге рекурсии. &lt;br /&gt;
Сортировка может быть выполнена любым способом, в зависимости от реализации. В дальнейшем положим, что используется алгоритм с оптимальной вычислительной сложностью &amp;lt;math&amp;gt;O(nlog_2{n})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Как записано и в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть метода составляют сортировки массивов координат вершин &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, выполняемые на каждом шаге рекурсии.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
# Вычисляются минимумы и максимумы по каждой из координат, определяющие параллелепипед, охватывающий вершины данной области. Далее запускается процесс рекурсии, на каждом шаге которого выполняется следующее:&lt;br /&gt;
## Определяется координата &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, вдоль которой параллелепипед, обрабатывающийся на данном этапе, имеет наибольшую протяженность.&lt;br /&gt;
## Определяется количество доменов, которое делится на данном этапе. В левую часть (вершины с меньшей координатой &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;) попадет половина доменов. Сначала набираются домены нулевого типа, потом, если они закончились, первого, и т.д. до получения нужного числа доменов в левой части. Подсчитывается общее число вершин n1, которое окажется в этих доменах. В правой части будут сформированы оставшиеся домены.&lt;br /&gt;
## Пусть все вершины в параллелепипеде имеют координаты &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, принадлежащие интервалу &amp;lt;math&amp;gt;[j_{min}, j_{max}]&amp;lt;/math&amp;gt;. Интервал делится на &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; равных малых интервалов. &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; – некоторая константа. Подсчитываются количества вершин, принадлежащие каждому малому интервалу. Исходя из того, что в левую часть должна попасть &amp;lt;math&amp;gt;n_1&amp;lt;/math&amp;gt; вершина с меньшей координатой &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, определяется, в какой малый интервал &amp;lt;math&amp;gt;[j_{from}, j_{to}]&amp;lt;/math&amp;gt; попадает медиана. Затем вершины из интервала &amp;lt;math&amp;gt;[j_{from}, j_{to}]&amp;lt;/math&amp;gt; записываются в отдельный массив, отсортированный по всем координатам. Определяется медиана – последняя вершина, которая попадет в левую часть.&lt;br /&gt;
## Если предполагается построение локальных деревьев, для вершины &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; двоичного дерева запоминаются данные о медиане: ее координаты, номер вершины медианы и номер координаты &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, по которой проводилось деление.&lt;br /&gt;
## Проводится разделение данных по аналогии с обменной сортировкой с разделением Хоару (быстрая сортировка), чтобы на следующих этапах просматривались только вершины из разбиваемой области. Два указателя, &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;end&amp;lt;/math&amp;gt;, выставляются на начало и на конец массива данных, соответственно. Вершина, на которую указывает указатель &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt;, сравнивается с медианой по всем координатам, и, если она попадает в левую часть параллелепипеда, указатель &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt; сдвигается к следующей вершине. Так до тех пор, пока указатель &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt; не остановится на вершине, которая должна попасть в правую часть. Указатель &amp;lt;math&amp;gt;end&amp;lt;/math&amp;gt; конца массива сдвигается влево до тех пор, пока не остановится на вершине, которая должна попасть в левую часть. Если указатель &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt; находится левее указателя &amp;lt;math&amp;gt;end&amp;lt;/math&amp;gt;, вершины, на которые указывают указатели, меняются местами, после чего указатель &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt; сдвигается вправо, а &amp;lt;math&amp;gt;end&amp;lt;/math&amp;gt; – влево.Если указатель &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt; все еще левее указателя &amp;lt;math&amp;gt;end&amp;lt;/math&amp;gt;, весь процесс повторяется снова. Если после выхода из цикла указатели указывают на одну и ту же вершину, она сравнивается с медианой по всем координатам, и если вершина попадает в левую часть, указатель &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt; сдвигается к следующей вершине. Указатель &amp;lt;math&amp;gt;begin&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;j&amp;lt;/math&amp;gt; приравнивается к координате &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; медианы. Передается число доменов каждого вида, которое будет в левой части. Номер вершины двоичного дерева, отвечающей за деление левой части, будет равным &amp;lt;math&amp;gt;2i&amp;lt;/math&amp;gt;. Правой части передается указатель &amp;lt;math&amp;gt;begin&amp;lt;/math&amp;gt; в качестве нового указателя на массив данных и оставшееся число вершин. Минимальная координата &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; приравнивается к координате медианы. Передаются числа доменов каждого вида. Номер вершины двоичного дерева, отвечающей за деление правой части, будет равным &amp;lt;math&amp;gt;2i + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Перед делением каждой из частей проверяется, сколько доменов осталось в данной части. Если остался только один домен, то все вершины помещаются в данный домен. Домены считаются по порядку от номера &amp;lt;math&amp;gt;gr_0&amp;lt;/math&amp;gt; первого домена. Если предполагается построение локальных деревьев, в лист дерева записывается номер домена. Запоминается максимальный номер вершины. Если в части осталось больше одного домена, она отправляется на деление. &lt;br /&gt;
&lt;br /&gt;
[[file:bisection_1.jpg|thumb|center|700px|Рисунок 1. Пример координатной бисекции на три домена.&amp;lt;ref name=&amp;quot;G1&amp;quot;/&amp;gt;]]&lt;br /&gt;
Алгоритм работает только с координатами вершин и не учитывает связи между ними, что делает его экономичным по памяти.&amp;lt;ref name=&amp;quot;G2&amp;quot;/&amp;gt;&amp;lt;ref name=&amp;quot;Y&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Для разбиения графа с количеством вершин &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; методом рекурсивной координатной бисекции на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; доменов требуется:&lt;br /&gt;
* для каждого шага рекурсии:&lt;br /&gt;
** определить максимум и минимум координат, &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; операций сравнения,&lt;br /&gt;
** отсортировать подобласть по одной из координат, &amp;lt;math&amp;gt;O(nlog_2{n})&amp;lt;/math&amp;gt; операций сравнения.&lt;br /&gt;
Глубина рекурсии - &amp;lt;math&amp;gt;log_2{p}+1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сравнения составляют &#039;&#039;основную часть алгоритма&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, алгоритм имеет последовательную сложность &amp;lt;math&amp;gt;O(n, p) = n \log_2{n} \log_2{p}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма&amp;lt;ref name=&amp;quot;V&amp;quot;&amp;gt;Воеводин В.В., Воеводин Вл.В. Параллельные вычисления. - СПб.: БХВ-Петербург, 2002. - 608 с.&amp;lt;/ref&amp;gt; в виде рисунка.&lt;br /&gt;
[[File:AepPhDGxoJDcFhdr.png|alt=information graph|thumb|center|900px|Рисунок 2. Информационный граф алгоритма. In - входные данные,LS - локальная сортировка, PS - параллельная сортировка с помощью сортировочной сести, D - декомпозиция, Out - выходные данные&amp;lt;ref name=&amp;quot;G1&amp;quot;/&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Граф алгоритма состоит из двух групп вершин, соответствующих бисекции по процессам (LS и PS) и локальной бисекции на каждом процессе (D). Первая группа делится на подгруппы, каждая подгруппа содержит некоторое количество сетей параллельной сортировки (PS), каждая из которых может выполнятся независимо от других. Во второй же группе вершин все операции в одной вершине не зависят от других вершин.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Исходя из того, что метод является геометрическим, алгоритм обладает координатным параллелизмом. Таким образом структура параллельного алгоритма включает в себя следующие этапы&amp;lt;ref name=&amp;quot;G2&amp;quot;&amp;gt;Головченко Е.Н. Параллельный пакет декомпозиции больших сеток // Математическое моделирование. 2011. Т. 23. № 10. 3-18. URL: http://cyberleninka.ru/article/n/razbienie-bolshih-setok&amp;lt;/ref&amp;gt;: &lt;br /&gt;
# Начальное распределение вершин по процессорам. Начальное распределение может быть любым, например, в соответствии с порядковыми номерами вершин.&lt;br /&gt;
# Определение числа доменов, которые должны быть сформированы на каждом из процессоров, и количества вершин в них.&lt;br /&gt;
# Рекурсивная координатная бисекция вершин по процессорам. На каждом этапе сначала вычисляется координатная ось, вдоль которой область имеет наибольшую протяженность. Затем блок вершин бьется на две части перпендикулярно данной оси. Группа процессоров делится на две, далее каждая из групп делит свой блок вершин аналогичным образом. Для разделения блока вершин используется параллельная сортировка. После рекурсивной координатной бисекции вершин по процессорам на процессорах оказывается столько вершин, сколько должно быть в образуемых на них доменах.&lt;br /&gt;
# Локальная рекурсивная координатная бисекция вершин по доменам. Дальнейшее разбиение на домены проводится локально на каждом процессоре.&lt;br /&gt;
&lt;br /&gt;
Для разбиения графа &amp;lt;math&amp;gt;G=(V, E), |V|=n&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; доменов в параллельном варианте при количестве процессов &amp;lt;math&amp;gt;N_p&amp;lt;/math&amp;gt; требуется последовательно выполнить следующие ярусы:&lt;br /&gt;
* для бисекции по процессам &amp;amp;mdash; &amp;lt;math&amp;gt;log_2{N_p}&amp;lt;/math&amp;gt; пар ярусов, содержащих:&lt;br /&gt;
** локальную сортировку, при количестве вершин &amp;lt;math&amp;gt;n, \frac{n}{2}, \frac{n}{4},\ldots;&amp;lt;/math&amp;gt;&lt;br /&gt;
** параллельную сеть сортировки, при количестве элементов &amp;lt;math&amp;gt;n, \frac{n}{2}, \frac{n}{4},\ldots&amp;lt;/math&amp;gt;, при количестве процессов &amp;lt;math&amp;gt;N_p, \frac{N_p}{2}, \frac{N_p}{4},\ldots;&amp;lt;/math&amp;gt;&lt;br /&gt;
* один ярус, содержащий локальную бисекцию на каждом процессе для количества вершин &amp;lt;math&amp;gt;\frac{n}{N_p}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, параллельный вариант алгоритма обладает двухступенчатой структурой. При классификации по высоте ЯПФ его сложность &amp;amp;mdash; &amp;lt;math&amp;gt;O\left(\left[m \log_2{m} + \frac{1}{2} \log_2{n} (\log_2{n} + 1)\right]\log_2{N_p} + m \log_2{m} \log_2{p}\right)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m=\frac{n}{N_p}&amp;lt;/math&amp;gt;.&lt;br /&gt;
При классификации по ширине ЯПФ его сложность будет &amp;lt;math&amp;gt;O(N_p)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Входные данные алгоритма: множество координат вершин &amp;lt;math&amp;gt;C = \{c_i\}&amp;lt;/math&amp;gt; графа &amp;lt;math&amp;gt;G = (V, E)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;c_i = (v_i^x, v_i^y, v_i^z)&amp;lt;/math&amp;gt; - координаты вершины &amp;lt;math&amp;gt;v_i \in V&amp;lt;/math&amp;gt;. Таким образом, множество координат вершин может быть передано как массив трёхмерных векторов. Число доменов &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; передается в виде натурального числа, не может превышать число вершин.&amp;lt;ref name=&amp;quot;G2&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Количество элементов массива входных данных может быть очень большим, например, алгоритм используется для нерегулярных сеток, содержащих &amp;lt;math&amp;gt;10^9&amp;lt;/math&amp;gt; и более вершин. В настоящее время такие сетки невозможно разместить в памяти одного процессора (на гексаэдральную сетку, состоящую из &amp;lt;math&amp;gt;1.2 \cdot 10^8&amp;lt;/math&amp;gt; ячеек, требуется порядка 200 ГБ), поэтому для декомпозиции нужен параллельный алгоритм.&amp;lt;ref name=&amp;quot;G1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Число процессоров, на котором будет считаться вычислительная задача, как правило, заранее неизвестно. Поэтому имеет смысл предварительно однократно разбить сетку на большое число микродоменов, а потом формировать из них домены. Количество микродоменов на несколько порядков меньше числа вершин, поэтому многократное разбиение микродоменов на домены быстрее многократного разбиения всей сетки.&lt;br /&gt;
&lt;br /&gt;
Выходные данные алгоритма: разбиение множества вершин &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; на заданное число &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; доменов &amp;lt;math&amp;gt;S_j&amp;lt;/math&amp;gt;. Эти данные могут быть записаны как массив четырехмерных векторов координат вершин, четвертой координатой будет номер домена, которому принадлежит вершина.&amp;lt;ref name=&amp;quot;G1&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Алгоритм детерминирован в случае использования устойчивой сортировки вершин. Алгоритм устойчив, так как работает с целочисленными данными, ошибки округления отсутствуют.&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных, равна &amp;lt;math&amp;gt;O(\log_2{n} \log_2{p})&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - количество вершин в графе, &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; - количество доменов.&lt;br /&gt;
&lt;br /&gt;
Так как основной операцией алгоритма является сравнение целых чисел при сортировке, наблюдается дисбаланс арифметических операций по отношению к операциям обращения к памяти. Алгоритм обладает сбалансированностью операций между параллельными ветвями алгоритма, что следует из [[#condition1|условия &amp;lt;math&amp;gt;(1)&amp;lt;/math&amp;gt;]] - количество вершин на разных процессах примерно одинаково.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершины, соответствующей сети сортировки с номером &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, имеют степень &amp;lt;math&amp;gt;\frac{N_p}{2^k}, k = 0, 1,\ldots, \log_2{N_p}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Это означает, что их степень убывает в ходе работы алгоритма от &amp;lt;math&amp;gt;N_p&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;1&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;
Алгоритм, как и многие другие алгоритмы разбиения графов реализованы в следующих последовательных пакетах декомпозиции графов&amp;lt;ref name=&amp;quot;G1&amp;quot;&amp;gt;Головченко Е.Н. Декомпозиция расчетных сеток для решения задач механики сплошных сред на высокопроиводительных вычислительных системах. Дисс ... канд. ф.-м.наук. Институт прикладной математики им. М. В. Келдыша РАН, г. Москва URL: http://keldysh.ru/council/3/D00202403/golovchenko_diss.pdf&amp;lt;/ref&amp;gt;: METIS, JOSTLE, SCOTCH, CHACO и PARTY. &lt;br /&gt;
К параллельным пакетам относятся PARMETIS (параллельная версия пакета METIS), JOSTLE, PT-SCOTCH (параллельная версия пакета SCOTCH) и ZOLTAN.&lt;br /&gt;
&lt;br /&gt;
ParMETIS и METIS распространяются свободно URL: http://glaros.dtc.umn.edu/gkhome/software .&lt;br /&gt;
&lt;br /&gt;
ZOLTAN - свободная лицензия, URL: http://www.cs.sandia.gov/~web1400/1400_download.html .&lt;br /&gt;
&lt;br /&gt;
Также алгоритм реализован в параллельном пакете GridSpiderPar&amp;lt;ref name=&amp;quot;Y&amp;quot;&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2012. – 328 с., илл. – (Серия «Суперкомпьютерное образование»), ISBN 978-5-211-06382-2 URL: http://lira.imamod.ru/ITTPMOPS/&amp;lt;/ref&amp;gt;, URL: http://lira.imamod.ru/FondProgramm/Decomposition/&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Dan</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:%D0%90%D0%BD%D1%8E%D1%88%D0%B5%D0%B2%D0%B0_%D0%98%D1%80%D0%B8%D0%BD%D0%B0&amp;diff=16859</id>
		<title>Обсуждение участника:Анюшева Ирина</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:%D0%90%D0%BD%D1%8E%D1%88%D0%B5%D0%B2%D0%B0_%D0%98%D1%80%D0%B8%D0%BD%D0%B0&amp;diff=16859"/>
		<updated>2016-11-14T07:29:23Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Пункт 1.7 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; Пояснить, что есть что на приведенной схеме. Приведенная схема скорее более уместна в описании макроструктуры, а в п.1.7 требуется информационный граф.&lt;br /&gt;
&lt;br /&gt;
Добавьте инф. граф и не забудьте описать его элементы.&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:%D0%90%D0%BD%D1%8E%D1%88%D0%B5%D0%B2%D0%B0_%D0%98%D1%80%D0%B8%D0%BD%D0%B0/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES_(%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D0%BD%D0%B5%D0%B2%D1%8F%D0%B7%D0%BE%D0%BA)&amp;diff=16858</id>
		<title>Участник:Анюшева Ирина/Итерационный метод решения системы линейных алгебраических уравнений GMRES (обобщенный метод минимальных невязок)</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%D0%BA:%D0%90%D0%BD%D1%8E%D1%88%D0%B5%D0%B2%D0%B0_%D0%98%D1%80%D0%B8%D0%BD%D0%B0/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES_(%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D0%BD%D0%B5%D0%B2%D1%8F%D0%B7%D0%BE%D0%BA)&amp;diff=16858"/>
		<updated>2016-11-14T07:29:00Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Dan}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = GMRES (обобщенный метод минимальных невязок)&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(m^2n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = 1&lt;br /&gt;
| pf_width          = 1&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n^2+2n&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[U:Анюшева Ирина|Анюшева Ирина]] (614 группа, разделы: 1.1-1.2, 1.7-1.8, 2.7, 3), Исхаков Эльдар (614 группа, разделы 1.3-1.6, 1.9-1.10)&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритма =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Обобщенный метод минимальных невязок (GMRES) для решения системы линейных алгебраических уравнений аппроксимирует решение с помощью вектора в подпространстве Крылова с минимальным остатком. Метод GMRES разработан Ю.Саадом и Мартин Х. Шульцом в 1986 году.  Метод по праву считается одним из самых эффективных численных методов решения несимметричных систем. Он гарантирует неувеличение нормы невязки в ходе итерационного процесса, который основан на построении базиса в соответствующей системе подпространстве Крылова &amp;lt;math&amp;gt;K_j(A, r_0)&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем решение уточняется некоторой добавкой, представленной в виде разложения по этому базису.&lt;br /&gt;
&lt;br /&gt;
Метод обобщенных минимальных невязок популярен из-за наличия ряда преимуществ: он ошибкоустойчив, допускает эффективное распараллеливание, не требует нахождения параметра релаксации, обладает суперлинейной скоростью сходимости. Однако в чистом виде для больших систем метод не используется из-за чрезвычайно больших затрат памяти. Зато широкое распространение получила перезапускаемая версия метода, подоразумевающая перезапуск метода каждые m итераций. Уменьшение размерности пространства может привести к стагнации метода – процессу, при котором с каждой следующей итерацией норма невязки уменьшается незначительно, либо не уменьшается вовсе.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: система линейных алгебраических уравнений &amp;lt;math&amp;gt;Ax=b&amp;lt;/math&amp;gt;, где:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;A=(a_{ij})&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt; вещественная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; вектора из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;x^*&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;-&amp;lt;/math&amp;gt; точное решение системы.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: &amp;lt;math&amp;gt;x^{(s)} - &amp;lt;/math&amp;gt;приближенное решение системы.&lt;br /&gt;
&lt;br /&gt;
===Ортогонализация Арнольди===&lt;br /&gt;
Для построения базиса &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; в подпространстве Крылова в методе GMRES применяется ортогонализация Арнольди.&lt;br /&gt;
&lt;br /&gt;
Формулы метода:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
(h_{i+1,i}v_{i+1}) &amp;amp; = Av_i - \sum_{j = 1}^{i} h_{j,i}v_j, \\&lt;br /&gt;
v_1 &amp;amp;= \frac{r_0}{\parallel r_0 \parallel},&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
В матрично-векторных обозначениях соотношение может быть записано как&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
AV_i &amp;amp;= V_i H_i + h_{i+1,i}v_{i+1} e_i^T &amp;amp;=V_{i+1}\overline{H}_i,&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
V_i &amp;amp;= [v_1|v_2|...|v_i], \overline{H}_i - \end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt; верхняя матрица Хессенберга размерности &amp;lt;math&amp;gt;(i+1)\times i&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Минимизация невязки===&lt;br /&gt;
&lt;br /&gt;
Невязку уравнения можно определить как&lt;br /&gt;
&amp;lt;math&amp;gt; J(y) = \parallel b- A x\parallel = \parallel b- (Ax_0+V_m y)\parallel =\parallel \beta e_1 - \overline{H}_m y \parallel&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;y -&amp;lt;/math&amp;gt; вектор размерности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вектор &amp;lt;math&amp;gt;x_m&amp;lt;/math&amp;gt; может быть получен как &lt;br /&gt;
&amp;lt;math&amp;gt;x_m = x_0 + V_m y_m&amp;lt;/math&amp;gt;, вектор &amp;lt;math&amp;gt;y_m&amp;lt;/math&amp;gt; может найден как решение линейной задачи наименьших квадратов размера &amp;lt;math&amp;gt;(m+1)\times m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;m&amp;lt;&amp;lt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Для решения задачи минимизации приведем матрицу &amp;lt;math&amp;gt;\overline{H}_m&amp;lt;/math&amp;gt; к верхнему треугольному виду с помощью вращений Гивенса. На шаге &lt;br /&gt;
&amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; матрица вращения &amp;lt;math&amp;gt;\Omega_i&amp;lt;/math&amp;gt; имеет размеры &amp;lt;math&amp;gt;(m+1)\times (m+1)&amp;lt;/math&amp;gt; и имеет следующий вид:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\Omega_i= \begin{pmatrix}&lt;br /&gt;
1 &amp;amp; &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
&amp;amp;\ddots &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;\\&lt;br /&gt;
&amp;amp;&amp;amp;1&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\        &lt;br /&gt;
&amp;amp;&amp;amp;&amp;amp;c_i&amp;amp;s_i &amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
&amp;amp;&amp;amp;&amp;amp;-s_i&amp;amp; c_i &amp;amp;&amp;amp;&amp;amp;\\&lt;br /&gt;
&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;1&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;\ddots&amp;amp;\\&lt;br /&gt;
&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;1 \\  &lt;br /&gt;
\end{pmatrix}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Вычислительное ядро алгоритма==&lt;br /&gt;
&lt;br /&gt;
В алгоритме GMRES присутствуют два ресурсоемких с точки зрения вычислительных мощностей этапа:&lt;br /&gt;
&lt;br /&gt;
* умножение исходной матрицы на вектор при вычислении невязок;&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;
1. Выбрать произвольное &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt;; вычислить &amp;lt;math&amp;gt;r_0=b-Ax_0&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v_1=\frac{r_0}{\parallel r_0 \parallel}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Задать матрицу &amp;lt;math&amp;gt;\overline{H}_m&amp;lt;/math&amp;gt; размерности &amp;lt;math&amp;gt;(m+1)\times m&amp;lt;/math&amp;gt; и всем ее элементам присвоить нулевые значения&lt;br /&gt;
&lt;br /&gt;
3. Для &amp;lt;math&amp;gt;j=1,\dots,m&amp;lt;/math&amp;gt; выполнять:&lt;br /&gt;
&lt;br /&gt;
* для &amp;lt;math&amp;gt;i=1,\dots,j&amp;lt;/math&amp;gt; выполнять: &amp;lt;math&amp;gt;h_{i,j}=(Av_j,v_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\omega_j=Av_j-\sum_{i=1}^j h_{i,j}v_i&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;h_{j+1,j}={\parallel \omega_j \parallel}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;v_{j+1}=\frac{\omega_j}{h_{j+1,j}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Вычислить &amp;lt;math&amp;gt;y_m=\arg\min_{y} \parallel \beta e_1 - \overline{H}_my \parallel,\ y \in \mathbb{R}^m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;x_m=x_0+V_my_m&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. Вычислить &amp;lt;math&amp;gt;r_m=b-Ax_m&amp;lt;/math&amp;gt;. Если достигнутая точность удовлетворительна, остановиться.&lt;br /&gt;
&lt;br /&gt;
Иначе принять &amp;lt;math&amp;gt;x_0=x_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;v_1=\frac{r_m}{\parallel r_m \parallel}&amp;lt;/math&amp;gt; и вернуться к пункту 2.&lt;br /&gt;
&lt;br /&gt;
===Решение задачи минимизации невязки===&lt;br /&gt;
&lt;br /&gt;
Для нахождения &amp;lt;math&amp;gt;y_m=\arg\min_{y} \parallel \beta e_1 - \overline{H}_my \parallel&amp;lt;/math&amp;gt; необходимо выполнить следующие шаги:&lt;br /&gt;
&lt;br /&gt;
1. Найти &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; матриц вращений Гивенса &amp;lt;math&amp;gt;\Omega_i(c_i,s_i),\ i=1,\dots,m&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;(m+1)\times(m+1)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;s_i=\frac{h_{i+1,i}}{\sqrt{h_{i,i}^2+h_{i+1,i}^2}}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;c_i=\frac{h_{i,i}}{\sqrt{h_{i,i}^2+h_{i+1,i}^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Вычислить &amp;lt;math&amp;gt;\overline{H}_m^{(m)}=\Omega_1\dots\Omega_m\overline{H}_m&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\overline{g}_m=\Omega_1\dots\Omega_m\beta e_1&amp;lt;/math&amp;gt;, удалить последнюю строку и последний элемент соответственно и решить СЛАУ с полученной верхнетреугольной матрицей и правой частью. Полученное решение &amp;lt;math&amp;gt;y_m&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;math&amp;gt;3m+1&amp;lt;/math&amp;gt; делений;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;2m+1&amp;lt;/math&amp;gt; вычислений квадратного корня;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{3m+5}{2}n&amp;lt;/math&amp;gt; умножений;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;O(\frac{m^2n^2}{2})&amp;lt;/math&amp;gt; сложений (вычитаний).&lt;br /&gt;
&lt;br /&gt;
==Информационный граф==&lt;br /&gt;
Метод состоит из двух блоков: ортогонализация и минимизация невязки. При ортогонализации основными операциями являются умножение матрицы на вектор и скалярное умножение векторов, для которых возможен параллелизм, что показано в блоке на темно-синем фоне. В блоке &amp;lt;math&amp;gt;min&amp;lt;/math&amp;gt; решается задача минимизации невязки, которая, строго говоря, является отдельной самостоятельной задачей.&lt;br /&gt;
[[file:gmres.jpg|thumb|center|700px|Рис.1. Информационная структура алгоритма GMRES]]&lt;br /&gt;
&lt;br /&gt;
==Ресурс параллелизма алгоритма==&lt;br /&gt;
Для нахождения матрично-векторных произведений при вычислении невязок матрица СЛАУ должна быть подвергнута декомпозиции на строчные блоки, размеры которых определяются требованиями равномерности загрузки. Соответствующим образом подвергается декомпозиции и вектор правой части. Для наиболее эффективного вычисления скалярных произведений и линейных комбинаций векторов базиса каждый из векторов &amp;lt;math&amp;gt;v_j&amp;lt;/math&amp;gt; должен быть разбит на блоки равного размера по числу процессов; каждый из процессов при этом хранит соответствующие блоки всех векторов. Обработка вектора решения дублируется на всех процессах.&lt;br /&gt;
&lt;br /&gt;
==Входные и выходные данные алгоритма==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039;&lt;br /&gt;
* матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n\times n&amp;lt;/math&amp;gt;;&lt;br /&gt;
* вектор-столбец &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;;&lt;br /&gt;
* вектор-столбец &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - начальное приближение;  &lt;br /&gt;
* натуральное число &amp;lt;math&amp;gt;m&amp;lt;&amp;lt;n&amp;lt;/math&amp;gt;, определяющее размерность подпространства Крылова.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
* вектор-столбец &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - решение системы.&lt;br /&gt;
&lt;br /&gt;
==Свойства алгоритма==&lt;br /&gt;
&lt;br /&gt;
* Вычислительная мощность: весьма маленькая и равна &amp;lt;math&amp;gt;m^2&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;m&amp;lt;&amp;lt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Устойчивость: GMRES в этом плане является очень хорошим методом. Теоретически можно получить точное решение не более чем за &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; итераций. Однако, очень приемлемые результаты получаются и за &amp;lt;math&amp;gt;m&amp;lt;&amp;lt;n&amp;lt;/math&amp;gt; итераций. Однако, есть примеры, в которых видно, что первые &amp;lt;math&amp;gt;m-1&amp;lt;/math&amp;gt; итераций дают невязку, равную некой константе, а на итерации под номером &amp;lt;math&amp;gt;m&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;
* Реализация алгоритма в библиотеке SciPy [https://docs.scipy.org/doc/scipy-0.17.0/reference/generated/scipy.sparse.linalg.gmres.html]&lt;br /&gt;
* Реализация алгоритма в библиотеке IML++ [http://math.nist.gov/iml++/gmres.h.txt]&lt;br /&gt;
* Библиотека для MATLAB [http://www.mathworks.com/help/matlab/ref/gmres.html]&lt;br /&gt;
&lt;br /&gt;
= Литература=&lt;br /&gt;
1. Y. Saad, M.H. Schultz. GMRES: A generalized minimal residual algorithm for solving nonsymmetric linear systems. SIAM J. Sci. Statist. Comput., 7 (1986), pp. 856–869&lt;br /&gt;
&lt;br /&gt;
2. Е.Е. Тыртышников. Методы численного анализа. – Москва: Академия, 2007&lt;br /&gt;
&lt;br /&gt;
3. М.Ю. Баландин, Э.П. Шурина. Некоторые оценки эффективности параллельных алгоритмов решения СЛАУ на подпространствах Крылова. - Вычислительные технологии, том 3, №1, 1998&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:%D0%9C%D0%B0%D0%BA%D0%B0%D1%80%D0%BE%D0%B2%D0%B0_%D0%90%D0%BB%D1%91%D0%BD%D0%B0/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES_(%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D0%BD%D0%B5%D0%B2%D1%8F%D0%B7%D0%BE%D0%BA)&amp;diff=16857</id>
		<title>Участник:Макарова Алёна/Итерационный метод решения системы линейных алгебраических уравнений GMRES (обобщенный метод минимальных невязок)</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%D0%BA:%D0%9C%D0%B0%D0%BA%D0%B0%D1%80%D0%BE%D0%B2%D0%B0_%D0%90%D0%BB%D1%91%D0%BD%D0%B0/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES_(%D0%BE%D0%B1%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D1%85_%D0%BD%D0%B5%D0%B2%D1%8F%D0%B7%D0%BE%D0%BA)&amp;diff=16857"/>
		<updated>2016-11-14T07:28:13Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Dan}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Обобщенный метод минимальных невязок&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(nm^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n(n + 1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&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;
Впервые метод минимальных невязок был описан в книге Марчука и Кузнецова &amp;quot;Итерационные методы и квадратичные функционалы&amp;quot; &amp;lt;ref&amp;gt; Г.И. Марчук, Ю.А. Кузнецов, Итерационные методы и квадратичные функционалы, Методы вычислительной математики, Новосибирск, 1975, с. 4-143.&amp;lt;/ref&amp;gt; и представлял собой геометрическую реализацию метода минимальных невязок.&lt;br /&gt;
&lt;br /&gt;
Алгебраическая реализация метода минимальных невязок была предложена Саадом и Шульцем в 1986 году &amp;lt;ref&amp;gt;Y.Saad, M.H. Schultz, GMRES: A generalized minimal residual algorithm for solving nonsymmetric linear systems, SIAM J. Scientific and Stat. Comp. 7: 856-869 (1986). &amp;lt;/ref&amp;gt;. С их подачи за методом закрепилась аббревиатура GMRES (обобщенный метод минимальных невязок).&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для решения системы &amp;lt;math&amp;gt;Ax = b&amp;lt;/math&amp;gt; с невырожденной матрицей &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;, выбирается начальное приближение &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt;, затем решается редуцированная система &amp;lt;math&amp;gt;Au = r_0&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;r_0 = b - Ax_0, x = x_0 + u&amp;lt;/math&amp;gt;. Подпространства Крылова строятся для редуцированной системы (в предположении, что &amp;lt;math&amp;gt;r_0 \neq 0&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;x_i = x_0 + y&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt; y \in \mathcal{K}_i &amp;lt;/math&amp;gt;. Невязка имеет вид &amp;lt;math&amp;gt;r_i = r_0 - Ay&amp;lt;/math&amp;gt;, а её длина минимальна, в силу теоремы Пифагора, в том и только том случае, когда &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
r_i \perp A\mathcal{K}_i &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, для реализации &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-го шага требуется опустить перпендикуляр из вектора &amp;lt;math&amp;gt;r_0&amp;lt;/math&amp;gt; на подпространство &amp;lt;math&amp;gt;A\mathcal{K}_i&amp;lt;/math&amp;gt;. Проще всего это сделать, если в данном подпространстве уже найден ортогональный базис. &amp;lt;ref&amp;gt; Тыртышников Е. Е. Методы численного анализа — М., Академия, 2007.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Геометрическая реализация ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Геометрическая реализация&#039;&#039; метода минимальных невязок заключается в построении последовательности векторов &amp;lt;math&amp;gt;q_1, q_2,...&amp;lt;/math&amp;gt; таким образом, что &amp;lt;math&amp;gt;q_1, q_2,.., q_i&amp;lt;/math&amp;gt; дают базис в подпространстве Крылова &amp;lt;math&amp;gt;\mathcal{K}_i&amp;lt;/math&amp;gt; и при этом вектора &amp;lt;math&amp;gt;p_1 = Aq_1, ..., p_i = Aq_i&amp;lt;/math&amp;gt; образуют ортогональный базис в подпространстве &amp;lt;math&amp;gt;A\mathcal{K}_i&amp;lt;/math&amp;gt;. Вектор &amp;lt;math&amp;gt;q_{i+1} \notin \mathcal{K}_i&amp;lt;/math&amp;gt; должен обладать следующими свойствами:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
q_{i+1} \in \mathcal{K}_{i+1}, p_{i+1} = Aq_{i+1} \perp A\mathcal{K}_i&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Его можно получить с помощью процесса ортогонализации, применённого к вектору &amp;lt;math&amp;gt;p = Aq&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;q = Aq_i&amp;lt;/math&amp;gt;. В геометрической реализации необходимо хранить две системы векторов: &amp;lt;math&amp;gt;q_1, ..., q_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p_1, ..., p_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Алгебраическая реализация ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Алгебраическая реализация&#039;&#039; метода минимальных невязок использует лишь одну систему векторов, образующих ортогональные базисы в подпространствах &amp;lt;math&amp;gt;\mathcal{K}_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_1 = r_0/||r_0||_2&amp;lt;/math&amp;gt;. Чтобы получить ортонормированный базис  &amp;lt;math&amp;gt;q_1, ..., q_{i+1}&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;\mathcal{K}_{i+1} = \mathcal{K}_{i+1}(r_0, A)&amp;lt;/math&amp;gt;, проводим ортогонализацию вектора &amp;lt;math&amp;gt;Aq_i&amp;lt;/math&amp;gt; к векторам &amp;lt;math&amp;gt;q_1, ..., q_i&amp;lt;/math&amp;gt;. Если &amp;lt;math&amp;gt;Q_i \equiv [q_1, ..., q_i] \in \mathbb{C}^{n*i}&amp;lt;/math&amp;gt;, то получим&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
AQ_i = Q_{i+1}\hat{H_i}, \hat{H_i}= \begin{bmatrix} H_i \\ 0 ... 0 &amp;amp; h_{i+1 i} \end{bmatrix},&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt;H_i&amp;lt;/math&amp;gt; - верхняя хессенбергова матрица порядка &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим &amp;lt;math&amp;gt;QR&amp;lt;/math&amp;gt;-разложение прямоугольной матрицы &amp;lt;math&amp;gt;\hat{H_i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\hat{H_i} = U_iR_i, R_i \in \mathbb{C}^{i*i}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Тогда минимум невязки &amp;lt;math&amp;gt;||r_0 - AQ_iy||_2&amp;lt;/math&amp;gt; по всем &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; будет достигаться в том случае, если &amp;lt;math&amp;gt;y = y_i&amp;lt;/math&amp;gt; удовлетворяет уравнению&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
R_iy_i = z_i \equiv ||r_0||_2U^T_ie_1, e_1 = \begin{bmatrix} 1 0 ... 0 \end{bmatrix}^T,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;R_i&amp;lt;/math&amp;gt; невырожденная, следовательно,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
x_i = x_0 + Q_iy_i = x_0 + Q_iR_i^{-1}z_i&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Сходимость метода ====&lt;br /&gt;
&lt;br /&gt;
Метод минимизации невязок на подпространствах Крылова за конечное число итераций приводит к точному решению и по этой причине является прямым методом. Но чаще его рассматривают как итерационный метод - с типичными для итерационных методов оценками сходимости. Идея заключается в том, что спустя некоторое количество итераций, полученное приближение уже является хорошей оценкой ответа.&lt;br /&gt;
&lt;br /&gt;
Но об этом не верно говорить в общем. Согласно теореме (Greenbaum, Pták and Strakoš), для каждой монотонной последовательности &amp;lt;math&amp;gt; a_1,..., a_{m-1}, a_m = 0 &amp;lt;/math&amp;gt;, найдётся матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; такая что &amp;lt;math&amp;gt;||r_n|| = a_n&amp;lt;/math&amp;gt; для всех &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;r_n&amp;lt;/math&amp;gt; невязка, определенная ранее.&lt;br /&gt;
&lt;br /&gt;
На практике для матрицы порядка  &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; число шагов может оказаться равным &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, а норма невязки может оставаться равной норме начальной невязки на всех шагах, кроме последнего. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Пример&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\begin{bmatrix} 0 1 &amp;amp; ... \\ 0 0 1 &amp;amp; ... \\...\\... &amp;amp; 01 \\1 &amp;amp; ... \end{bmatrix} \begin{bmatrix} 1 \\ 0 \\...\\ 0 \\ 0 \end{bmatrix} = \begin{bmatrix} 0 \\ 0 \\...\\ 0 \\ 1 \end{bmatrix}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; x_0 = 0 &amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt; r_0 = b&amp;lt;/math&amp;gt;. Подпространства Крылова получаются такие:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
\mathcal{K}_i = span \{ e_n, e_{n-1}, ..., e_{n-i+1}\}, i \le i \le n &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Точное решение системы имеет вид &amp;lt;math&amp;gt;x = e_1&amp;lt;/math&amp;gt;, а на итерациях получаются следующие векторы:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
x_0 = x_1 = ... = x_{n-1} = 0, x_n = e_1&lt;br /&gt;
&lt;br /&gt;
&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;math&amp;gt;A&amp;lt;/math&amp;gt; положительно определена, то&lt;br /&gt;
:&amp;lt;math&amp;gt; &lt;br /&gt;
\|r_n\| \leq \left( 1-\frac{\lambda_{\mathrm{min}}^2(1/2(A^T + A))}{ \lambda_{\mathrm{max}}(A^T A)} \right)^{n/2} \|r_0\|, &lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_{\mathrm{min}}(M)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_{\mathrm{max}}(M)&amp;lt;/math&amp;gt; обозначают наибольшее и наименьшее собственное значение матрицы &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;, соответственно. &amp;lt;ref&amp;gt;Eisenstat, Elman &amp;amp; Schultz, Thm 3.3. NB all results for GCR also hold for GMRES, cf. Saad &amp;amp; Schultz&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Сходимость для симметричной матрицы =====&lt;br /&gt;
Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; является симметрично и положительно определена, тогда&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
\|r_n\| \leq \left( \frac{\kappa_2(A)^2-1}{\kappa_2(A)^2} \right)^{n/2} \|r_0\|&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;\kappa_2(A)&amp;lt;/math&amp;gt; число обусловленности матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; в Евклидовой норме.&lt;br /&gt;
&lt;br /&gt;
Если не требовать положительной определённости&lt;br /&gt;
:&amp;lt;math&amp;gt; &lt;br /&gt;
\|r_n\| \le \inf_{p \in P_n} \|p(A)\| \le \kappa_2(V) \inf_{p \in P_n} \max_{\lambda \in \sigma(A)} |p(\lambda)| \|r_0\|, \, &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;P_n&amp;lt;/math&amp;gt; обозначает множество полиномов степени не выше &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;p(0) = 1&amp;lt;/math&amp;gt;, матрица &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; появляется из спектрального разложения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sigma(A)&amp;lt;/math&amp;gt; - спектр матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Грубо говоря, это означает, что быстрая сходимость имеет место, когда собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; невелики и &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не сильно отклоняется от нормальной матрицы.&amp;lt;ref&amp;gt;Trefethen &amp;amp; Bau, Thm 35.2&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Все эти неравенства связаны с невязкой вместо фактической ошибки, т.е. расстоянием между текущей итерацией и точным решением.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Самой трудоёмкой процедурой в методе является &amp;lt;math&amp;gt;QR&amp;lt;/math&amp;gt;-разложение &amp;lt;math&amp;gt;\hat{H_i}&amp;lt;/math&amp;gt;. В общем случае требуется &amp;lt;math&amp;gt;\mathcal{O}(i^3)&amp;lt;/math&amp;gt; арифметических операций, однако то, что &amp;lt;math&amp;gt;\hat{H_i}&amp;lt;/math&amp;gt; является хессенберговой матрицей, позволяет сократить требуемый объём до &amp;lt;math&amp;gt;\mathcal{O}(i^2)&amp;lt;/math&amp;gt; действий.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм начинается с выбора начального приближения &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt;.&lt;br /&gt;
Далее для &amp;lt;math&amp;gt;i = 1,2 ..&amp;lt;/math&amp;gt;&lt;br /&gt;
: 1. Вычисляем матрицу &amp;lt;math&amp;gt;\hat{H_i}&amp;lt;/math&amp;gt;.&lt;br /&gt;
: 2. Находим её &amp;lt;math&amp;gt;QR&amp;lt;/math&amp;gt;-разложение: &amp;lt;math&amp;gt;\hat{H_i} = U_iR_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
: 3. Решаем систему &amp;lt;math&amp;gt;R_iy_i = U^T_ie_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
: 4. Находим приближение &amp;lt;math&amp;gt;x_i = x_0 + Q_iy_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм завершается, когда норма вектора невязки становится достаточно малой. При большом числе итераций вычислительные затраты и требуемая для хранения векторов &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; память могу оказаться чрезмерно большими. В таких случаях применяют алгоритм с перезапусками (restart): задают максимальную допустимую размерность &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; пространств Крылова &amp;lt;math&amp;gt;\mathcal{K}_i&amp;lt;/math&amp;gt;, и если точность не достигнута, берут полученное приближение в качестве нового начального приближения &amp;lt;math&amp;gt;x^0_{new} = x_K&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
* Инициализация начальных значений&lt;br /&gt;
&lt;br /&gt;
1. Выбрать начальное приближение &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt; и точность решения &amp;lt;math&amp;gt;\epsilon&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. Для &amp;lt;math&amp;gt; k = 1, 2, .. &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Вычисление невязки&lt;br /&gt;
&lt;br /&gt;
3. &amp;lt;math&amp;gt;r_0 = b - Ax_0&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\beta = ||r_0||&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;q_1 = r_0/\beta&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
4. Цикл по &amp;lt;math&amp;gt; j = 1, 2, .. k &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Ортогонализация Арнольди&lt;br /&gt;
&lt;br /&gt;
5. Для каждого &amp;lt;math&amp;gt; i = 1, 2, .. j &amp;lt;/math&amp;gt; вычислим:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij} = (Aq_j, q_i)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
6. Построим вектор: &amp;lt;math&amp;gt;z_{j+1} = Aq_j - \sum_{i = 1}^j h_{ij}q_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
7. Вычислим его норму &amp;lt;math&amp;gt;h_{j+1,j} = ||z_{j+1}||_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
8. Если &amp;lt;math&amp;gt;h_{j+1,j}&amp;lt;/math&amp;gt; = 0, то останавливаемся.&lt;br /&gt;
&lt;br /&gt;
9. Построим очередной вектор базиса &amp;lt;math&amp;gt;q_{j+1} = z_{j+1}/h_{j+1,j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
10. Конец цикла по &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
11. Процесс требует хранения всех предыдущих элементов базиса:&amp;lt;math&amp;gt;q_1, .. q_k&amp;lt;/math&amp;gt;. Будем хранить их в виде матриц &amp;lt;math&amp;gt;Q_k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Задача наименьших квадратов&lt;br /&gt;
&lt;br /&gt;
12. Чтобы вычислить &amp;lt;math&amp;gt;x_k = x_0 + Q_ky_k&amp;lt;/math&amp;gt;, решаем задачу: &amp;lt;math&amp;gt; y_k = argmin ||r_0 - AP_ky_k||_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Проверка достижения требуемой точности приближения&lt;br /&gt;
&lt;br /&gt;
13. Если  &amp;lt;math&amp;gt;||b - Ax_k|| &amp;lt; \epsilon&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x_k = x_0 + Q_ky_k&amp;lt;/math&amp;gt; перейти к п.15&lt;br /&gt;
&lt;br /&gt;
14. &amp;lt;math&amp;gt;x_0 = x_k&amp;lt;/math&amp;gt;, перейти к п.2&lt;br /&gt;
&lt;br /&gt;
*Конец&lt;br /&gt;
&lt;br /&gt;
15. &amp;lt;math&amp;gt;x^* = x_k&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Будем предполагать, что матрица решаемой СЛАУ является разреженной.&lt;br /&gt;
Пусть несимметричная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; имеет симметричный портрет и число ненулевых элементов в нижнем(верхнем) треугольнике равно  &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При &amp;lt;math&amp;gt; m &amp;lt;&amp;lt; n &amp;lt;/math&amp;gt; можно говорить, что один GMRES-цикл имеет сложность &amp;lt;math&amp;gt;\mathcal{O}(nm^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Требования по памяти с учетом &amp;lt;math&amp;gt;1 &amp;lt; m &amp;lt;&amp;lt; n&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k &amp;lt;&amp;lt; n&amp;lt;/math&amp;gt; составляют &amp;lt;math&amp;gt;\mathcal{O}(mn)&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt; М.Ю. Баландин, Э.П.Шурина, Некоторые оценки эффективности параллельных алгоритмов решения СЛАУ на подпространствах Крылова, Вычислительные технологии, 1998, Т.3&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Основная и самая трудоёмкая операция в алгоритме - умножение матрицы на вектор. Для этой операции приводится граф вычисления операции.&lt;br /&gt;
&lt;br /&gt;
[[Файл:graf.png|thumb|center|1400px|Рисунок 2. Граф вычислений подзадачи умножения матрицы на вектор&amp;lt;ref&amp;gt; http://ssd.sscc.ru/sites/default/files/content/attach/449/shkorin_-_gmres.pdf&amp;lt;/ref&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
В вычислительной схеме присутствуют два интенсивных в вычислительном плане этапа:&lt;br /&gt;
:1. Умножение матрицы СЛАУ на вектор (для нахождения невязок).&lt;br /&gt;
Для нахождения матрично-векторных произведений при вычислении невязок матрича должна быть подвергнута декомпозиции на строчные блоки.&lt;br /&gt;
:2. Нахождение скалярных произведений векторов (при построении ортонормального базиса подпространства Крылова).&lt;br /&gt;
Для наиболее эффективного вычисления скалярных проихведений и линейных комбинаций векоров базиса каждый из векторов &amp;lt;math&amp;gt;p_i&amp;lt;/math&amp;gt; должен быть разбит на блоки равного размера по числу процессоров.&lt;br /&gt;
&lt;br /&gt;
Кроме того, на хранение векторов базиса приходится бОльшая часть затрат памяти.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные: &#039;&#039;&#039;&lt;br /&gt;
Обязательные параметры:&lt;br /&gt;
:&amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; - квадратная матрица &#039;&#039;(n x n)&#039;&#039;.&lt;br /&gt;
:&amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; - вектор правой части &#039;&#039;(n x 1)&#039;&#039;.&lt;br /&gt;
Вариативно:&lt;br /&gt;
:&amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt; - начальное приближение (может не передаваться и быть всегда нулевым).&lt;br /&gt;
:&amp;lt;math&amp;gt;\epsilon&amp;lt;/math&amp;gt; - погрешность (может не передаваться и быть заданным по умолчанию, обычно равна 1e-6).&lt;br /&gt;
:Максимальное число итераций.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;math&amp;gt;x^*&amp;lt;/math&amp;gt; - решение системы &amp;lt;math&amp;gt;Ax = b&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
:1. Рассматриваемый алгоритм предназначен для решения невырожденных линейных систем большой размерности. При этом симметрия и положительная определенность матрицы не предполагается.&lt;br /&gt;
&lt;br /&gt;
:2. Для систем с разряженной матрицей алгоритм требует гораздо меньшей вычислительной мощности.&lt;br /&gt;
&lt;br /&gt;
:3. Особенностью метода является то, что с целью экономии памяти выбирается некоторая размерность Крылова &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;, и после того как &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; базисных векторов построены, решение уточняется.&lt;br /&gt;
&lt;br /&gt;
:4. Одной из важных практических особенностей метода является  то, что на первых итерациях метод сходится гораздо быстрее, чем асимптотически. Для ускорения сходимости метода минимальных невязок целесообразно время о времени использовать один шаг двух-шагового метода минимальных невязок.&lt;br /&gt;
&lt;br /&gt;
==Программная реализация алгоритма==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Реализация GMRES с преобуславливанием на python, доступная в пакете scipy (scipy.sparse.linal)&amp;lt;ref&amp;gt; https://github.com/scipy/scipy/blob/v0.14.0/scipy/sparse/linalg/isolve/iterative.py.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def gmres(A, b, x0=None, tol=1e-5, restart=None, maxiter=None, xtype=None, M=None, callback=None, restrt=None):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Use Generalized Minimal RESidual iteration to solve A x = b.&lt;br /&gt;
    Parameters&lt;br /&gt;
    ----------&lt;br /&gt;
    A : {sparse matrix, dense matrix, LinearOperator}&lt;br /&gt;
        The real or complex N-by-N matrix of the linear system.&lt;br /&gt;
    b : {array, matrix}&lt;br /&gt;
        Right hand side of the linear system. Has shape (N,) or (N,1).&lt;br /&gt;
    Returns&lt;br /&gt;
    -------&lt;br /&gt;
    x : {array, matrix}&lt;br /&gt;
        The converged solution.&lt;br /&gt;
    info : int&lt;br /&gt;
        Provides convergence information:&lt;br /&gt;
          * 0  : successful exit&lt;br /&gt;
          * &amp;gt;0 : convergence to tolerance not achieved, number of iterations&lt;br /&gt;
          * &amp;lt;0 : illegal input or breakdown&lt;br /&gt;
    Other parameters&lt;br /&gt;
    ----------------&lt;br /&gt;
    x0 : {array, matrix}&lt;br /&gt;
        Starting guess for the solution (a vector of zeros by default).&lt;br /&gt;
    tol : float&lt;br /&gt;
        Tolerance to achieve. The algorithm terminates when either the relative&lt;br /&gt;
        or the absolute residual is below `tol`.&lt;br /&gt;
    restart : int, optional&lt;br /&gt;
        Number of iterations between restarts. Larger values increase&lt;br /&gt;
        iteration cost, but may be necessary for convergence.&lt;br /&gt;
        Default is 20.&lt;br /&gt;
    maxiter : int, optional&lt;br /&gt;
        Maximum number of iterations (restart cycles).  Iteration will stop&lt;br /&gt;
        after maxiter steps even if the specified tolerance has not been&lt;br /&gt;
        achieved.&lt;br /&gt;
    xtype : {&#039;f&#039;,&#039;d&#039;,&#039;F&#039;,&#039;D&#039;}&lt;br /&gt;
        This parameter is DEPRECATED --- avoid using it.&lt;br /&gt;
        The type of the result.  If None, then it will be determined from&lt;br /&gt;
        A.dtype.char and b.  If A does not have a typecode method then it&lt;br /&gt;
        will compute A.matvec(x0) to get a typecode.   To save the extra&lt;br /&gt;
        computation when A does not have a typecode attribute use xtype=0&lt;br /&gt;
        for the same type as b or use xtype=&#039;f&#039;,&#039;d&#039;,&#039;F&#039;,or &#039;D&#039;.&lt;br /&gt;
        This parameter has been superseded by LinearOperator.&lt;br /&gt;
    M : {sparse matrix, dense matrix, LinearOperator}&lt;br /&gt;
        Inverse of the preconditioner of A.  M should approximate the&lt;br /&gt;
        inverse of A and be easy to solve for (see Notes).  Effective&lt;br /&gt;
        preconditioning dramatically improves the rate of convergence,&lt;br /&gt;
        which implies that fewer iterations are needed to reach a given&lt;br /&gt;
        error tolerance.  By default, no preconditioner is used.&lt;br /&gt;
    callback : function&lt;br /&gt;
        User-supplied function to call after each iteration.  It is called&lt;br /&gt;
        as callback(rk), where rk is the current residual vector.&lt;br /&gt;
    restrt : int, optional&lt;br /&gt;
        DEPRECATED - use `restart` instead.&lt;br /&gt;
    See Also&lt;br /&gt;
    --------&lt;br /&gt;
    LinearOperator&lt;br /&gt;
    Notes&lt;br /&gt;
    -----&lt;br /&gt;
    A preconditioner, P, is chosen such that P is close to A but easy to solve&lt;br /&gt;
    for. The preconditioner parameter required by this routine is&lt;br /&gt;
    ``M = P^-1``. The inverse should preferably not be calculated&lt;br /&gt;
    explicitly.  Rather, use the following template to produce M::&lt;br /&gt;
      # Construct a linear operator that computes P^-1 * x.&lt;br /&gt;
      import scipy.sparse.linalg as spla&lt;br /&gt;
      M_x = lambda x: spla.spsolve(P, x)&lt;br /&gt;
      M = spla.LinearOperator((n, n), M_x)&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # Change &#039;restrt&#039; keyword to &#039;restart&#039;&lt;br /&gt;
    if restrt is None:&lt;br /&gt;
        restrt = restart&lt;br /&gt;
    elif restart is not None:&lt;br /&gt;
        raise ValueError(&amp;quot;Cannot specify both restart and restrt keywords. &amp;quot;&lt;br /&gt;
                         &amp;quot;Preferably use &#039;restart&#039; only.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    A,M,x,b,postprocess = make_system(A,M,x0,b,xtype)&lt;br /&gt;
&lt;br /&gt;
    n = len(b)&lt;br /&gt;
    if maxiter is None:&lt;br /&gt;
        maxiter = n*10&lt;br /&gt;
&lt;br /&gt;
    if restrt is None:&lt;br /&gt;
        restrt = 20&lt;br /&gt;
    restrt = min(restrt, n)&lt;br /&gt;
&lt;br /&gt;
    matvec = A.matvec&lt;br /&gt;
    psolve = M.matvec&lt;br /&gt;
    ltr = _type_conv[x.dtype.char]&lt;br /&gt;
    revcom = getattr(_iterative, ltr + &#039;gmresrevcom&#039;)&lt;br /&gt;
    stoptest = getattr(_iterative, ltr + &#039;stoptest2&#039;)&lt;br /&gt;
&lt;br /&gt;
    resid = tol&lt;br /&gt;
    ndx1 = 1&lt;br /&gt;
    ndx2 = -1&lt;br /&gt;
    work = np.zeros((6+restrt)*n,dtype=x.dtype)&lt;br /&gt;
    work2 = np.zeros((restrt+1)*(2*restrt+2),dtype=x.dtype)&lt;br /&gt;
    ijob = 1&lt;br /&gt;
    info = 0&lt;br /&gt;
    ftflag = True&lt;br /&gt;
    bnrm2 = -1.0&lt;br /&gt;
    iter_ = maxiter&lt;br /&gt;
    old_ijob = ijob&lt;br /&gt;
    first_pass = True&lt;br /&gt;
    resid_ready = False&lt;br /&gt;
    iter_num = 1&lt;br /&gt;
    while True:&lt;br /&gt;
        olditer = iter_&lt;br /&gt;
        x, iter_, resid, info, ndx1, ndx2, sclr1, sclr2, ijob = \&lt;br /&gt;
           revcom(b, x, restrt, work, work2, iter_, resid, info, ndx1, ndx2, ijob)&lt;br /&gt;
        # if callback is not None and iter_ &amp;gt; olditer:&lt;br /&gt;
        #    callback(x)&lt;br /&gt;
        slice1 = slice(ndx1-1, ndx1-1+n)&lt;br /&gt;
        slice2 = slice(ndx2-1, ndx2-1+n)&lt;br /&gt;
        if (ijob == -1):  # gmres success, update last residual&lt;br /&gt;
            if resid_ready and callback is not None:&lt;br /&gt;
                callback(resid)&lt;br /&gt;
                resid_ready = False&lt;br /&gt;
&lt;br /&gt;
            break&lt;br /&gt;
        elif (ijob == 1):&lt;br /&gt;
            work[slice2] *= sclr2&lt;br /&gt;
            work[slice2] += sclr1*matvec(x)&lt;br /&gt;
        elif (ijob == 2):&lt;br /&gt;
            work[slice1] = psolve(work[slice2])&lt;br /&gt;
            if not first_pass and old_ijob == 3:&lt;br /&gt;
                resid_ready = True&lt;br /&gt;
&lt;br /&gt;
            first_pass = False&lt;br /&gt;
        elif (ijob == 3):&lt;br /&gt;
            work[slice2] *= sclr2&lt;br /&gt;
            work[slice2] += sclr1*matvec(work[slice1])&lt;br /&gt;
            if resid_ready and callback is not None:&lt;br /&gt;
                callback(resid)&lt;br /&gt;
                resid_ready = False&lt;br /&gt;
                iter_num = iter_num+1&lt;br /&gt;
&lt;br /&gt;
        elif (ijob == 4):&lt;br /&gt;
            if ftflag:&lt;br /&gt;
                info = -1&lt;br /&gt;
                ftflag = False&lt;br /&gt;
            bnrm2, resid, info = stoptest(work[slice1], b, bnrm2, tol, info)&lt;br /&gt;
&lt;br /&gt;
        old_ijob = ijob&lt;br /&gt;
        ijob = 2&lt;br /&gt;
&lt;br /&gt;
        if iter_num &amp;gt; maxiter:&lt;br /&gt;
            break&lt;br /&gt;
&lt;br /&gt;
    if info &amp;gt;= 0 and resid &amp;gt; tol:&lt;br /&gt;
        # info isn&#039;t set appropriately otherwise&lt;br /&gt;
        info = maxiter&lt;br /&gt;
&lt;br /&gt;
    return postprocess(x), info&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;lt;ref&amp;gt; С.А. Буренков, Организация и исследование эффективных вычислений для решения задач аэроакустики на кластерных архитектурах, Москва, 2014.&amp;lt;/ref&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;
Рассмотрим операции, которые выполняются неоднократно в процессе выполнения алгоритма: умножение матрицы на вектор, произведение векторов, расчет нормы вектора, нахождение взвешенной суммы векторов. Эти подзадачи можно разделить на 2 группы: операции между матрицей и вектором (например, умножение матрицы на вектор) и операции между двумя векторами (например, скалярное умножение, взвешенная сумма векторов и пр.). Подзадачи умножения константы на вектор и определение нормы вектора будем относить ко второй группе, так как их трудоемкость одного порядка. &lt;br /&gt;
&lt;br /&gt;
Особенности выполнения операций между матрицей и вектором определены способом распределения входных данных. На рис. 2 схематично изображен процесс параллельного умножения матрицы на вектор на трех процессорах. &lt;br /&gt;
&lt;br /&gt;
[[file:Matr_x_v.png|thumb|center|700px|Рисунок 2. Схема параллельного выполнения операции между матрицей и вектором]]&lt;br /&gt;
&lt;br /&gt;
Заштрихованные участки соответствуют данным, расположенным в памяти процессора исполнителя. Каждый исполнитель получает свою часть результата выполнения операции.&lt;br /&gt;
&lt;br /&gt;
По схожему принципу организовано параллельное выполнение операций между двумя векторами. Несмотря на то, что каждому процессу доступна полная информация о векторах, вычисления производятся лишь над участком, соответствующим процессу-исполнителю. На рис. 3 изображен пример параллельного выполнения операций между двумя векторами.&lt;br /&gt;
&lt;br /&gt;
[[file:V x v.png|thumb|center|700px|Рисунок 3. Схема параллельного выполнения операции между двумя векторами]]&lt;br /&gt;
&lt;br /&gt;
Таким образом, параллельное выполнение любой из выделенных подзадач привело к распределению вычислительной нагрузки между всеми исполнителями. &lt;br /&gt;
&lt;br /&gt;
==== Объединение результатов расчетов ====&lt;br /&gt;
&lt;br /&gt;
Результатом выполнения рассматриваемых операций является, чаще всего, вектор, части которого расположены на участвовавших в вычислениях процессорах. Для объединения результатов расчета и получения полного вектора на каждом процессоре вычислительной системы необходимо выполнить операцию сбора данных. В качестве обменных взаимодействий в модели с распределённой памятью могут выступать операции массовых коммуникационных обменов. С их помощью каждый процессор передаст свой вычисленный элемент вектора всем остальным процессорам (см. рис. 4).&lt;br /&gt;
[[file:Collect.png|thumb|center|700px|Рисунок 4. Принцип сбора результатов вычислений]]&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
Алгоритм GMRES достаточно популярен и его реализацию можно найти во многих пакетах прикладных программ.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Пример: MATLAB&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;matlab&amp;quot;&amp;gt;   &lt;br /&gt;
&lt;br /&gt;
Итерационный метод минимизации обобщенной невязки реализован в системе MATLAB. Для этого используется функция gmres:&lt;br /&gt;
&lt;br /&gt;
gmres (А, В. restart) — возвращает решение X СЛУ А*Х=В. А —квадратная матрица. Функция gmres начинает итерации от начальной оценки, представляющей собой вектор размера и, состоящий из нулей. Итерации производятся либо до сходимости к решению, либо до появления ошибки, либо до достижения максимального числа итераций. Сходимость достигается, когда относительный остаток norm(B-A*X)/norm(B) меньше или равен заданной погрешности (по умолчанию 1е-6). Максимальное число итераций — минимум из n:restart и 10. Функция gmres (...) имеет и ряд других форм записи, аналогичных описанным для функции bieg(...).  &lt;br /&gt;
&lt;br /&gt;
» gmres(A.B)&lt;br /&gt;
&lt;br /&gt;
GMRES(4) converged at Iteration 1(4) to a solution with relative residual le-016&lt;br /&gt;
&lt;br /&gt;
ans =&lt;br /&gt;
&lt;br /&gt;
1.0000&lt;br /&gt;
&lt;br /&gt;
2.0000&lt;br /&gt;
&lt;br /&gt;
3.0000&lt;br /&gt;
&lt;br /&gt;
4.0000&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Список пакетов, в которых присутствует реализация метод минимизации обобщенной невязки:&lt;br /&gt;
:1.&#039;&#039;&#039;ATLAS&#039;&#039;&#039; (Automatically Tuned Linear Algebra Software) – оптимизированная библиотека, включающая реализацию процедур BLAS и часть функциональности LAPACK; &lt;br /&gt;
:2.&#039;&#039;&#039;AZTEC&#039;&#039;&#039; – библиотека параллельных подпрограмм для решения больших систем линейных алгебраических уравнений с разреженными матрицами; &lt;br /&gt;
:3.&#039;&#039;&#039;BLAS&#039;&#039;&#039; (Basic Linear Algebra Subprograms) – библиотека высококачественных процедур, «строительными блоками» для которых являются вектора, матрицы или их части. Уровень 1 BLAS используется для выполнения операций вектор-вектор, уровень 2 :BLAS – для выполнения матрично-векторных операций, наконец, уровень 3 BLAS – для выполнения матрично-матричных операций. Поскольку программы BLAS являются эффективными, переносимыми и легко доступными, они используются как базовые компоненты для развития высококачественного программного обеспечения для задач линейной алгебры. Так были созданы широко известные пакеты LINPACK, EISPACK, которые затем были перекрыты пакетом LAPACK, получившим большое распространение. Перечисленные пакеты разработаны на языке Fortran; &lt;br /&gt;
:4.&#039;&#039;&#039;BLACS&#039;&#039;&#039; (Basic Linear Algebra Communication Subprograms) – набор базовых коммуникационных процедур линейной алгебры, созданных для линейной алгебры. Вычислительная модель состоит из одномерной или двумерной решетки процессов, где каждый процесссодержит часть матрицы или вектора. BLACS используется как коммуникационный слой проекта ScaLAPACK, который переносит библиотеку LAPACK на машины с распределенной памятью; &lt;br /&gt;
:5.&#039;&#039;&#039;BlockSolve95&#039;&#039;&#039; – параллельная библиотека для решения разреженных систем линейных уравнений; &lt;br /&gt;
:6.&#039;&#039;&#039;BPKIT2&#039;&#039;&#039; – пакет блочных способов предобусловливания, ориентированных на разреженные матрицы; &lt;br /&gt;
:7.&#039;&#039;&#039;CAPSS&#039;&#039;&#039; – пакет для параллельного решения разреженных линейных систем; &lt;br /&gt;
:8.&#039;&#039;&#039;CXML&#039;&#039;&#039; (The Compaq Extended Math Library) – расширенная математическая библиотека, включающая в себя часть функциональности BLAS, LAPACK, Direct Sparse Solvers и Iterative-solvers; &lt;br /&gt;
:9.&#039;&#039;&#039;Direct Sparse Solvers&#039;&#039;&#039; – пакет программ для решения разреженных систем прямыми методами; &lt;br /&gt;
:10.&#039;&#039;&#039;EISPACK&#039;&#039;&#039; (Eigensystem Package) – пакет программ решения алгебраической проблемы собственных значений; &lt;br /&gt;
:11.&#039;&#039;&#039;Expokit&#039;&#039;&#039; – пакет программ для решения не больших СЛАУ с плотной матрицей и больших разреженных систем; &lt;br /&gt;
:12.&#039;&#039;&#039;ILUPACK&#039;&#039;&#039; – библиотке, содержащая способы предобусловливания, ориентированная на разреженные СЛАУ. Пакет включает реализацию процедур BLAS, SPARSEKIT. Реализована на языке С и Fortran; &lt;br /&gt;
:13.&#039;&#039;&#039;IML++&#039;&#039;&#039; (Iterative Methods Library) – библиотека итерационных методов решения разреженных СЛАУ, позволяющая использовать несколько простых способов предобусловливания. Пакет включает часть BLAS и MV; &lt;br /&gt;
:14.&#039;&#039;&#039;Intel MKL&#039;&#039;&#039; (Intel Math Kernel Library) включает несколько стандартных библиотек для высокопроизводительных системах (BLAS, LAPACK и FFTPACK – подпрограммы быстрого преобразования Фурье); &lt;br /&gt;
:15.&#039;&#039;&#039;IOMDRV&#039;&#039;&#039; – пакет подпрограмм для решения симметричных и несимметричных линейных систем методами крыловских подпространств; &lt;br /&gt;
:16.&#039;&#039;&#039;Iterative-solvers&#039;&#039;&#039; – пакет подпрограмм решения разреженных систем итерационными методами; &lt;br /&gt;
:17.&#039;&#039;&#039;ITL&#039;&#039;&#039; (Iterative Template Library) – библиотека программ итерационных методов и способов предобусловливания, являющаяся составной частью MTL. &lt;br /&gt;
:18.&#039;&#039;&#039;ITPACK&#039;&#039;&#039; (Iterative Package) – пакет программ для решения разреженных систем итерационными методами; &lt;br /&gt;
:19.&#039;&#039;&#039;ITSOL&#039;&#039;&#039; (The New Sparskit Preconditionning Module) – пакет, содержащий способы предобусловливания, ориентированные на разреженные матрицы. Является составной частью пакета SPARSKIT; &lt;br /&gt;
:20.&#039;&#039;&#039;JAMA/C++&#039;&#039;&#039; – библиотека для решения СЛАУ прямыми методами; &lt;br /&gt;
:21.&#039;&#039;&#039;LAPACK&#039;&#039;&#039; (Linear Algebra Package) – набор реализаций «продвинутых» методов линейной алгебры. LAPACK содержит процедуры для решения систем линейных уравнений, задач нахождения собственных значений и факторизации матриц. Обрабатываются заполненные и ленточные матрицы, но не разреженные матрицы общего вида. Во всех случаях можно обрабатывать действительные и комплексные матрицы с одиночной и удвоенной точностью. Процедуры LAPACK построены таким образом, чтобы как можно больше вычислений выполнялось с помощью обращений к BLAS с использованием всех его трех уровней. Вследствие крупнозернистости операций уровня 3 BLAS, их использование обеспечивает высокую эффективность на многих высокопроизводительных компьютерах, в частности, если производителем создана специализированная реализация. ScaLAPACK является успешным результатом переноса пакета LAPACK на системы с передачей сообщений. Но в таких системах необходимы процедуры, обеспечивающие обмен данными между взаимодействующими процессами. Для этого в ScaLAPACK используется библиотека BLACS; &lt;br /&gt;
:22.&#039;&#039;&#039;Laspack&#039;&#039;&#039; – пакет программ для решения разреженных систем итерационными методами; &lt;br /&gt;
:23.&#039;&#039;&#039;LGSOLV&#039;&#039;&#039; – библиотека для решения СЛАУ прямыми методами; &lt;br /&gt;
:24.&#039;&#039;&#039;LINPACK&#039;&#039;&#039; (Linear Package) – пакет программ решения систем линейных алгебраических уравнений и линейной задачи наименьших квадратов прямыми методами; &lt;br /&gt;
:25.&#039;&#039;&#039;LinPar&#039;&#039;&#039; – пакет предназначенный для решения плохообусловленных СЛАУ, включая прямоугольные. Если для решения задачи необходимо предобусловливание СЛАУ, то оно выполняется отдельно и методы применяются к уже предобусловленной системе. Соответственно, по окончании процесса решения найденный вектор должен быть пересчитан согласно выполненному предобусловливанию. В схемы методов эти процедуры не включаются; &lt;br /&gt;
:26.&#039;&#039;&#039;MET&#039;&#039;&#039; (Matrix Expression Templates) – реализованная на языке C++ программа для инженеров и научных работников; &lt;br /&gt;
:27.&#039;&#039;&#039;MINOS&#039;&#039;&#039; – пакет подпрограмм решения больших разреженных задач линейного и нелинейного программирования; &lt;br /&gt;
:28.&#039;&#039;&#039;MTL&#039;&#039;&#039; (The Matrix Template Library) – реализованная на языке C++ библиотека базовых операций линейной алгебры, позволяющая решать СЛАУ с разреженными матрицами итерационными методами с предобусловлмванием, за счет включенного пакета ITL; &lt;br /&gt;
:29.&#039;&#039;&#039;MV++&#039;&#039;&#039; – небольшая библиотека, содержащая базовые операции линейной алгебры. Данный пакет часто является составной частью более крупных и высокопроизводительных библиотек; &lt;br /&gt;
:30.&#039;&#039;&#039;ParPre&#039;&#039;&#039; – пакет параллельных версий способов предобусловливания, ориентированных на разреженные матрицы, являющийся составной частью PETs; &lt;br /&gt;
:31.&#039;&#039;&#039;Parallel Algorithms Project&#039;&#039;&#039; – пакет параллельных версий итерационных методов Крыловского типа для решения разреженных систем; &lt;br /&gt;
:32.&#039;&#039;&#039;PASVA&#039;&#039;&#039; – пакет подпрограмм решения разреженных систем с блочно-двухдиагональной структурой; &lt;br /&gt;
:33.&#039;&#039;&#039;PBLAS&#039;&#039;&#039; – Параллельные версии базовых процедур линейной алгебры (BLAS) ; &lt;br /&gt;
:34.&#039;&#039;&#039;PCGPAK&#039;&#039;&#039; (Preconditioned Conjugate Gradient PAcKage) – пакет программ для решения симметричных и несимметричных разреженных линейных систем методом сопряженных градиентов; &lt;br /&gt;
:35.&#039;&#039;&#039;PIM&#039;&#039;&#039; (The Parallel Iterative Methods) – набор процедур на Фортран-77, реализующих параллельные версии различных итеративных методов решения разреженных систем линейных уравнений; &lt;br /&gt;
:36.&#039;&#039;&#039;PSparselib&#039;&#039;&#039; (A Portable Library of Parallel Sparse Iterative Solvers) – библиотека параллельных итерационных методов для разреженных линейных систем; &lt;br /&gt;
:37.&#039;&#039;&#039;PSPASES&#039;&#039;&#039; (Parallel Sparse Symmetric Direct Solver) – библиотека параллельных версий прямых методов для решения симметричных линейных систем; &lt;br /&gt;
:38.&#039;&#039;&#039;RALAPACK&#039;&#039;&#039; – пакет подпрограмм для различных операций с разреженными матрицами; &lt;br /&gt;
:39.&#039;&#039;&#039;ScaLAPACK&#039;&#039;&#039; (Scalable LAPACK) – параллельная версия LAPACK. Широкий набор подпрограмм для решения стандартных задач линейной алгебры; &lt;br /&gt;
:40.&#039;&#039;&#039;SIRSM&#039;&#039;&#039; – пакет подпрограмм для решения разреженных несимметричных линейных систем; &lt;br /&gt;
:41.&#039;&#039;&#039;Software Iterative Methods: GMRESR and BiCGstab(ell)&#039;&#039;&#039; – пакет прогамм решения больших разреженных систем с несимметричной матрицей; &lt;br /&gt;
:42.&#039;&#039;&#039;SPAI&#039;&#039;&#039; (Sparse Approximate Inverse Preconditioner) – пакет способов предобусловливания, ориентированных на разреженные матрицы; &lt;br /&gt;
:43.&#039;&#039;&#039;SPARKS&#039;&#039;&#039; – пакет подпрограмм для решения разреженных линейных систем в полунеявных методах Рунге-Кутта численного интегрирования систем обыкновенных дифференциальных уравнений; &lt;br /&gt;
:44.&#039;&#039;&#039;SparseLib++&#039;&#039;&#039; – библиотка, реализованная на языке C++, позволяющая решать разреженные СЛАУ итерационными методами с предобусловливанием. Включает часть процедур BLAS и IML; &lt;br /&gt;
:45.&#039;&#039;&#039;SPARSKIT&#039;&#039;&#039; – мощный пакет для решения разреженных СЛАУ итерационными методами с предобусловливанием. Библиотека реализованна на языке Fortran; &lt;br /&gt;
:46.&#039;&#039;&#039;SPARSPAK&#039;&#039;&#039; (Sparsee Iinear Equations Package) – пакет программ решения разреженных систем линейных алгебраических уравнений с симметричными положительно определенными матрицами; &lt;br /&gt;
:47.&#039;&#039;&#039;SPLIB&#039;&#039;&#039; – библиотека, позволяющая решать СЛАУ с разреженной матрицей итерационными методами с предобусловливанием, реализованная на языке Fortran; &lt;br /&gt;
:48.&#039;&#039;&#039;SPLP&#039;&#039;&#039; (Sparse Linear Programming Subprogram) – пакет программ решения задач линейного программирования; &lt;br /&gt;
:49.&#039;&#039;&#039;SPOOLES&#039;&#039;&#039; – библиотека для решения СЛАУ с разреженной матрицей прямыми методами; &lt;br /&gt;
:50.&#039;&#039;&#039;SSLES&#039;&#039;&#039; – пакет подпрограмм для решения разреженных несимметричных линейных систем; &lt;br /&gt;
:51.&#039;&#039;&#039;TCHLIB&#039;&#039;&#039; – пакет подпрограмм для решения симметричных и несимметричных линейных систем методом Чебышева; &lt;br /&gt;
:52.&#039;&#039;&#039;TNT&#039;&#039;&#039; (Template Numerical Toolkit) – библиотека базовых операций линейной алгебры, ориентированная на разреженные матрицы. Библиотека разработана на языке Fortran; &lt;br /&gt;
:53.&#039;&#039;&#039;WSMP&#039;&#039;&#039; (Watson Sparse Matrix Package) – пакет программ решения разреженных систем линейных алгебраических уравнений; &lt;br /&gt;
:54.&#039;&#039;&#039;XMP&#039;&#039;&#039; – пакет подпрограмм для решения задач линейного программирования; &lt;br /&gt;
:55.&#039;&#039;&#039;YI2M&#039;&#039;&#039; – комплекс программ решения разреженных систем;&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Dan</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:%D0%9C%D0%B0%D0%BA%D0%B0%D1%80%D0%BE%D0%B2%D0%B0_%D0%90%D0%BB%D1%91%D0%BD%D0%B0&amp;diff=16856</id>
		<title>Обсуждение участника:Макарова Алёна</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:%D0%9C%D0%B0%D0%BA%D0%B0%D1%80%D0%BE%D0%B2%D0%B0_%D0%90%D0%BB%D1%91%D0%BD%D0%B0&amp;diff=16856"/>
		<updated>2016-11-14T07:28:10Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Пункт 1.7 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; Необходимо добавить пояснения, что есть что в приведенном графе.&lt;br /&gt;
Если это информационный граф на макроуровне, то для входящих в него значимых операций надо привести соответствующие им информационные графы.&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:Obirvalger/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D0%B2%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%BE%D1%80%D0%B4%D0%B8%D0%BD%D0%B0%D1%82%D0%BD%D0%BE%D0%B9_%D0%B1%D0%B8%D1%81%D0%B5%D0%BA%D1%86%D0%B8%D0%B8&amp;diff=16855</id>
		<title>Участник:Obirvalger/Метод рекурсивной координатной бисекции</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%D0%BA:Obirvalger/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D0%B2%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%BE%D1%80%D0%B4%D0%B8%D0%BD%D0%B0%D1%82%D0%BD%D0%BE%D0%B9_%D0%B1%D0%B8%D1%81%D0%B5%D0%BA%D1%86%D0%B8%D0%B8&amp;diff=16855"/>
		<updated>2016-11-14T07:25:59Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Dan}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Рекурсивная координатная бисекция&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n \log_2{n} \log_2{k})&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;\log_2{k}&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;N|V| + |G|&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы: [[Участник:Obirvalger|Гордеев Михаил]] (разделы 1.4, 1.6, 1.8, 1.10), [[Участник:KolmakovEA|Колмаков Евгений]] (разделы 1.1, 1.2, 1.3, 1.5, 1.7, 1.9, 2.7).&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;&#039;&#039; является одним из методов, применяемых для декомпозиции графов &amp;lt;ref&amp;gt;Якобовский М.В. Введение в параллельные методы решения задач: Учебное пособие / Предисл.: В. А. Садовничий. – М.: Издательство Московского университета, 2012. – 328 с., илл. – (Серия «Суперкомпьютерное образование»), ISBN 978-5-211-06382-2 URL: http://lira.imamod.ru/ITTPMOPS/&amp;lt;/ref&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;
Метод рекурсивной координатной бисекции является частным случаем более общего &#039;&#039;&#039;метода рекурсивной бисекции&#039;&#039;&#039;. В этом методе сетка последовательно за &amp;lt;math&amp;gt;k-1&amp;lt;/math&amp;gt; шаг делится на &amp;lt;math&amp;gt;k&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;
* отсортированное множество разбивается на две части, то есть указывается индекс &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; такой, что в первую часть попадают вершины с номерами меньшими либо равными &amp;lt;math&amp;gt;i&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;
Исходные данные: граф &amp;lt;math&amp;gt;G = (V, E) &amp;lt;/math&amp;gt;, вложенный в &amp;lt;math&amp;gt;\mathbb{R}^N&amp;lt;/math&amp;gt; (то есть каждая вершина этого графа - это точка в &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; мерном пространстве), и число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; доменов, на которое нужно разбить граф.&lt;br /&gt;
Под &#039;&#039;декомпозицией&#039;&#039; графа на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; доменов понимается разбиение множества вершин &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; подмножеств &amp;lt;math&amp;gt;V_1, \dots, V_k&amp;lt;/math&amp;gt; таких, что &lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;V = \bigcup_{i = 1}^k V_i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;V_i \cap V_j = \varnothing&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;i \neq j&amp;lt;/math&amp;gt;.&amp;lt;/center&amp;gt; &lt;br /&gt;
&lt;br /&gt;
С каждым доменом можно связать порождённый им подграф &amp;lt;math&amp;gt;G(V_i) = (V_i, E_i)&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;E_i \subseteq E&amp;lt;/math&amp;gt; - множество рёбер, оба конца которых принадлежат домену.&lt;br /&gt;
&lt;br /&gt;
Задача заключается в нахождении декомпозиции &amp;lt;math&amp;gt;V_1, \dots, V_k&amp;lt;/math&amp;gt;, доставляющей минимум некоторого функционала (см. [[#Критерии декомпозиции| соответствующий пункт]]), например, числа разрезанных рёбер &amp;lt;math&amp;gt;E_{\mbox{cut}} = |\{(u, v) \in E \mid u \in V_i, v \in V_j, i \neq j\}| = |E| - \sum_{i = 1}^k |E_i|&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дадим формальное описание алгоритма. Как уже упоминалось, метод основан на алгоритме рекурсивной бисекции, поэтому представляет собой рекурсивную процедуру, на вход которой поступает граф  &amp;lt;math&amp;gt;G = (V, E) &amp;lt;/math&amp;gt; и число доменов &amp;lt;math&amp;gt;k&amp;lt;/math&amp;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;math&amp;gt;m^* \in \{1, \dots, N\}&amp;lt;/math&amp;gt;;&lt;br /&gt;
** в случае максимизации протяженности: для каждой оси &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; вычисляется величина &amp;lt;math&amp;gt;l_m = \max_{v \in V} v_m - \min_{v \in V} v_m&amp;lt;/math&amp;gt;, и выбирается ось &amp;lt;math&amp;gt;m^* = \arg\max_{m \in \{1, \dots, N\}} l_m&amp;lt;/math&amp;gt;;&lt;br /&gt;
** в случае минимизации числа разрезанных ребер: вершины упорядочиваются вдоль каждой из осей, для каждой оси вычисляется величина &amp;lt;math&amp;gt;E^m_{\mbox{cut}}&amp;lt;/math&amp;gt;, равная числу разрезанных ребер при разбиении вдоль данной оси, и выбирается ось &amp;lt;math&amp;gt;m^* = \arg\max_{m \in \{1, \dots, N\}} E^m_{\mbox{cut}}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* множество вершин сортируется по возрастанию координаты с номером &amp;lt;math&amp;gt;m^*&amp;lt;/math&amp;gt;;&lt;br /&gt;
* отсортированный массив вершин делится на две (непрерывные) части в соответствии с желаемым числом вершин в каждой из частей; &lt;br /&gt;
**как правило, выбирается индекс  &amp;lt;math&amp;gt;i = \lfloor\frac{k+1}{2k}\rfloor \cdot |V|&amp;lt;/math&amp;gt;, соответствующий примерно равному разделению текущего графа на части;&lt;br /&gt;
* первая часть состоит из вершин &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; с индексами &amp;lt;math&amp;gt;j \leqslant i&amp;lt;/math&amp;gt;, вторая - с индексами &amp;lt;math&amp;gt;j &amp;gt; i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро алгоритма составляют сортировки массива вершин сетки по выбранной координате при каждом из &amp;lt;math&amp;gt;k - 1&amp;lt;/math&amp;gt; вызовов процедуры бисекции. &lt;br /&gt;
&lt;br /&gt;
Также, в зависимости от критерия выбора координатной оси, требуются дополнительные вычисления:&lt;br /&gt;
*В случае максимизации протяженности при каждом вызове требуется вычисление величины &amp;lt;math&amp;gt;l_m&amp;lt;/math&amp;gt;.&lt;br /&gt;
*В случае минимизации числа разрезанных ребер при каждом вызове требуется сортировка по каждой из координат (таким образом, при каждом разбиении осуществляется &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; сортировок).&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Как записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть метода составляют множественные (всего &amp;lt;math&amp;gt;k-1&amp;lt;/math&amp;gt;) сортировки (функция argsort в коде в [[#Схема реализации последовательного алгоритма |следующем разделе]]).&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Опишем последовательную реализацию метода рекурсивной координатной бисекции, где выбор оси производится исходя из условия максимизации протяженности вдоль этой оси. Ниже представлен код данного алгоритма на языке Python 3.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# Переменная для хранения результата работы алгоритма&lt;br /&gt;
partition = []&lt;br /&gt;
&lt;br /&gt;
# V - numpy.ndarray размера |V| x N, k - число доменов&lt;br /&gt;
def recursive_bisection(V, k):&lt;br /&gt;
&lt;br /&gt;
    global partition&lt;br /&gt;
&lt;br /&gt;
    # Если текущая часть графа есть домен, добавляем ее к результату разбиения&lt;br /&gt;
    if (k &amp;lt;= 1):&lt;br /&gt;
        partition.append(V)&lt;br /&gt;
        return &lt;br /&gt;
&lt;br /&gt;
    # Вычисляем количество доменов в каждой из частей&lt;br /&gt;
    k1 = (k + 1) / 2&lt;br /&gt;
    k2 = k - k1&lt;br /&gt;
    &lt;br /&gt;
    # Производим разбиение  &lt;br /&gt;
    V1, V2 = bisect(V, k)&lt;br /&gt;
&lt;br /&gt;
    # Рекурсивно разбиваем каждую из частей&lt;br /&gt;
    recursive_bisect(V1, k1) &lt;br /&gt;
    recursive_bisect(V2, k2)&lt;br /&gt;
    &lt;br /&gt;
def bisect(V, k):&lt;br /&gt;
    # Вычисляем координату с наибольшей протяженностью&lt;br /&gt;
    t = V.max(axis=0) - V.min(axis=0)&lt;br /&gt;
    m = t.argmax()&lt;br /&gt;
    &lt;br /&gt;
    # Сортируем вершины по координате с номером m&lt;br /&gt;
    V_sorted = V[V[:, m].argsort()]&lt;br /&gt;
&lt;br /&gt;
    # Вычисляем индекс для разбиения в соответствии с числом доменов&lt;br /&gt;
    ind = (k + 1) * V.shape[0] // (2 * k)&lt;br /&gt;
&lt;br /&gt;
    return V_sorted[:ind, :], V_sorted[ind:, :]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведённый код предназначен для более подробного описания основных шагов в алгоритме, представляет собой лишь схему и не является максимально эффективным. Это сделано для того, чтобы код был более наглядным. В более эффективной реализации, например, вместо создания массивов в процедуре bisect можно везде оперировать только индексами.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Обозначим через &amp;lt;math&amp;gt;D_k(n)&amp;lt;/math&amp;gt; сложность алгоритма рекурсивной координатной бисекции для декомпозиции графа с &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; вершинами на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; доменов.&lt;br /&gt;
&lt;br /&gt;
Определим величину &amp;lt;math&amp;gt;D(n) = D_n(n)&amp;lt;/math&amp;gt;. Для &amp;lt;math&amp;gt;D(n)&amp;lt;/math&amp;gt; имеет место следующее рекуррентное равенство:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{l}&lt;br /&gt;
D(n) = S(n) + 2D(\frac{n}{2}) \\&lt;br /&gt;
D(1) = S(1) = 0. \\&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;S(n)&amp;lt;/math&amp;gt; - это сложность алгоритма сортировки массива из &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; элементов.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;S(n) = O(n\log_2{n})&amp;lt;/math&amp;gt; (например, для сортировки слиянием), тогда по теореме о рекуррентных соотношениях &amp;lt;ref&amp;gt;https://ru.wikipedia.org/wiki/Основная_теорема_о_рекуррентных_соотношениях&amp;lt;/ref&amp;gt; для произвольного положительного &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; имеет место оценка &amp;lt;math&amp;gt;D(n) \lesssim n^{1+\varepsilon}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Величину &amp;lt;math&amp;gt;D_k(n)&amp;lt;/math&amp;gt; можно явно посчитать по формуле &amp;lt;math&amp;gt;\sum\limits_{i=0}^{\lceil\log_2{k}\rceil}2^i S(\frac{n}{2^i})&amp;lt;/math&amp;gt;. Если использовать сортировку со сложностью &amp;lt;math&amp;gt;S(n) = O(n\log_2{n})&amp;lt;/math&amp;gt;, то &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;D_k(n) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;O(\sum\limits_{i=0}^{\lceil\log_2{k}\rceil}2^i \frac{n}{2^i} \log_2{\frac{n}{2^i}}) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;O(n\log_2(\prod\limits_{i=0}^{\lceil\log_2{k}\rceil}\frac{n}{2^i})) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;O(n\log_2{\frac{n^{\log_2{k}}}{2^\frac{\log_2{k}(\log_2{k}+1))}{2}}}) =&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; O(n(\log_2{n}\log_2{k} - \frac{\log^2_2{k}}{2})) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;O(n\log_2{n}\log_2{k})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Под операцией в данном пункте будем понимать макрооперацию сортировки. Передача данных происходит после разбиения множества вершин на две части.&lt;br /&gt;
Таким образом, информационный граф представляет из себя бинарное дерево с &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; листьями. На рисунке ниже приведена часть информационного графа для &amp;lt;math&amp;gt;k = 16&amp;lt;/math&amp;gt;. Зависимость от числа вершин &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; учитывается в самих узлах дерева. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
[[Файл:Tree_sort.svg|thumb|center|800px|Рисунок 1. Граф алгоритма.]]&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Высота ярусно-параллельной формы - &amp;lt;math&amp;gt;\log_2{k}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ширина ярусно-параллельной формы - &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если рассматривать более мелкие операции, используемые в процессе сортировки, то глобально информационный граф будет выглядеть также, однако каждый&lt;br /&gt;
узел будет заменён на информационный граф используемого алгоритма сортировки (или &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; таких графов, если используется критерий минимизации числа разрезов).&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Данный алгоритм обладает координатным параллелизмом.&lt;br /&gt;
Для декомпозиции графа с &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; вершинами на &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; доменов методом рекурсивной координатной бисекции в параллельном варианте требуется последовательно выполнить &amp;lt;math&amp;gt;\lceil\log_2{k}\rceil&amp;lt;/math&amp;gt; ярусов. На &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом ярусе будет выполнятся &amp;lt;math&amp;gt;2^i&amp;lt;/math&amp;gt; операций сортировки. &lt;br /&gt;
Рассмотрим два случая распараллеливания нашего алгоритма:&lt;br /&gt;
* Параллельное выполнение операций на каждом ярусе с использованием последовательного алгоритма сортировки со сложностью &amp;lt;math&amp;gt;O(n\log_2{n})&amp;lt;/math&amp;gt;. &lt;br /&gt;
# На первом шаге один процессор производит сортировку всех вершин, разделяет граф на два подграфа и передает однин из подрафов новому процессору.&lt;br /&gt;
# На &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-ом шаге каждый из уже получивший свой граф процессор производит сортировку всех вершин, разделяет граф на два подграфа и передает однин из подрафов новому процессору.&lt;br /&gt;
&lt;br /&gt;
Тогда сложность нашего алгоритма равна:&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;D_k(n) = O(\sum\limits_{i=0}^{\lceil\log_2{k}\rceil}\frac{n}{2^i} \log_2{\frac{n}{2^i}}) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;n\sum\limits_{i=0}^{\lceil\log_2{k}\rceil}(\frac{\log_2{n}}{2^i} - \frac{i}{2^i}) = &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;O(n\log_2{n}) - O(n) = O(n\log_2{n})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Параллельное выполнение операций на каждом ярусе с использованием параллельного алгоритма сортировки со сложностью &amp;lt;math&amp;gt;O(\log_2^2{n})&amp;lt;/math&amp;gt;&amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Batcher_odd–even_mergesort&amp;lt;/ref&amp;gt;.&lt;br /&gt;
На каждом шаге производится параллельная сортировка вершин и разбиение графа на два подграфа.&lt;br /&gt;
В этом случае &lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt; &lt;br /&gt;
&amp;lt;math&amp;gt;D_k(n) = \sum\limits_{i=0}^{\lceil\log_2{k}\rceil}\log^2_2\frac{n}{2^i} = O(\log^2_2{n}\log_2{k}) = O(\log^3_2{n})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
Известно &amp;lt;ref&amp;gt;https://en.wikipedia.org/wiki/Sorting_algorithm&amp;lt;/ref&amp;gt;, что оптимальная параллельная сортировка имеет сложность &amp;lt;math&amp;gt;O(\log_2{n})&amp;lt;/math&amp;gt;. В этом случае  &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;D_k(n) = \sum\limits_{i=0}^{\lceil\log_2{k}\rceil}\log_2\frac{n}{2^i} = O(\log_2{n}\log_2{k})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; граф &amp;lt;math&amp;gt;G = (V, E) &amp;lt;/math&amp;gt;, вложенный в &amp;lt;math&amp;gt;\mathbb{R}^N&amp;lt;/math&amp;gt;, и число &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; частей (доменов), на которое нужно разбить граф. Таким образом, помимо матрицы смежности (или любого другого представления графа) для каждой вершины &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; задан набор её координат &amp;lt;math&amp;gt;v = (v_1, \dots, v_N) \in \mathbb{R}^N&amp;lt;/math&amp;gt;, поэтому &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; задаётся массивом &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-мерных векторов или матрицей размера &amp;lt;math&amp;gt;|V| \times N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;N|V| + |G|&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;|G|&amp;lt;/math&amp;gt; - объём данных, представляющих граф &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, который в общем случае зависит от выбранного представления.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; доменов графа &amp;lt;math&amp;gt;G&amp;lt;/math&amp;gt;, задающих его декомпозицию.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;|V|&amp;lt;/math&amp;gt; - для каждого домена достаточно хранить соответствующие вершинам из этого домена индексы строк в матрице, представляющей множество вершин.&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Соотношение последовательной и параллельной сложности в случае неограниченных ресурсов является &#039;&#039;линейным&#039;&#039; (отношение &amp;lt;math&amp;gt;O(n\log{n})&amp;lt;/math&amp;gt; к &amp;lt;math&amp;gt;O(\log{n}))&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;
Последовательная версия алгоритма реализована в пакетах Chaco, JOSTLE, [http://glaros.dtc.umn.edu/gkhome/metis/metis/overview METIS], [https://www.labri.fr/perso/pelegrin/scotch/ SCOTCH]. &lt;br /&gt;
&lt;br /&gt;
Параллельная версия реализована в пакетах JOSTLE, [http://glaros.dtc.umn.edu/gkhome/metis/parmetis/overview ParMETIS], [https://www.labri.fr/perso/pelegrin/scotch/ PT-SCOTCH].&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что пакеты METIS и ParMETIS распространяются свободно.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&lt;br /&gt;
[[en:Recursive coordinate bisection method]]&lt;/div&gt;</summary>
		<author><name>Dan</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:Obirvalger&amp;diff=16854</id>
		<title>Обсуждение участника:Obirvalger</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:Obirvalger&amp;diff=16854"/>
		<updated>2016-11-14T07:25:31Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;замечания остались те же:&lt;br /&gt;
&lt;br /&gt;
= Вклад = &lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; Необходимо явно указать вклад каждого соавтора.&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.5 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; Если код не свой, необходимо дать явную ссылку на источник.&lt;br /&gt;
&lt;br /&gt;
Код свой.&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.7 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; Граф следует оформить как рисунок, добавить подпись.&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;&#039;&#039; В первом приближении решили оставить так.&lt;/div&gt;</summary>
		<author><name>Dan</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:Obirvalger&amp;diff=16318</id>
		<title>Обсуждение участника:Obirvalger</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:Obirvalger&amp;diff=16318"/>
		<updated>2016-11-10T13:05:39Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;замечания остались те же:&lt;br /&gt;
&lt;br /&gt;
= Вклад = &lt;br /&gt;
Необходимо явно указать вклад каждого соавтора.&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.5 =&lt;br /&gt;
Если код не свой, необходимо дать явную ссылку на источник.&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.7 =&lt;br /&gt;
Граф следует оформить как рисунок, добавить подпись.&lt;br /&gt;
Представленный рисунок отражает схему работы, а требуется привести информационный граф.&lt;br /&gt;
Приведенный рисунок можно оставить, но информационный граф надо добавить.&lt;/div&gt;</summary>
		<author><name>Dan</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:Obirvalger&amp;diff=16317</id>
		<title>Обсуждение участника:Obirvalger</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:Obirvalger&amp;diff=16317"/>
		<updated>2016-11-10T13:01:52Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;замечания остались те же:&lt;br /&gt;
&lt;br /&gt;
= Вклад = &lt;br /&gt;
Необходимо явно указать вклад каждого соавтора.&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.5 =&lt;br /&gt;
Если код не свой, необходимо дать явную ссылку на источник.&lt;br /&gt;
&lt;br /&gt;
= Пункт 1.7 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039; Граф следует оформить как рисунок, добавить подпись.&lt;/div&gt;</summary>
		<author><name>Dan</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%D0%BA:Lvs/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES&amp;diff=16267</id>
		<title>Участник:Lvs/Итерационный метод решения системы линейных алгебраических уравнений GMRES</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%D0%BA:Lvs/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4_%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B_%D0%BB%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D1%85_%D0%B0%D0%BB%D0%B3%D0%B5%D0%B1%D1%80%D0%B0%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85_%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D0%B9_GMRES&amp;diff=16267"/>
		<updated>2016-11-09T14:48:17Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Dan}}&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Итерационный метод решения системы линейных алгебраических уравнений GMRES (или обобщенный метод минимальных невязок) используется для решения систем линейных алгебраических уравнений с заданной точностью приближения. Метод основан на процессе Арнольди, посредст­вом которого матрица СЛАУ приводится к (верхней) хессенберговой форме.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Дана система линейных алгебраических уравнений &amp;lt;math&amp;gt;Ax = b&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; - квадратная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вычисляется последовательность приближённых решений уравнения &amp;lt;math&amp;gt; x_m &amp;lt;/math&amp;gt;, которая сходится к точному решению уравнения &amp;lt;math&amp;gt;x^*&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Подпространство Крылова размерности &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt;, порожденное вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt; и матрицей &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; – линейное пространство&lt;br /&gt;
&amp;lt;math&amp;gt;K_m(A, v)&amp;lt;/math&amp;gt;, являющееся линейной оболочкой векторов &amp;lt;math&amp;gt;b, Ab, A^2b, ..., A^{m-1}b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Приближённое решение считается по формуле &amp;lt;math&amp;gt; x_m = Q_my_m&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_m&amp;lt;/math&amp;gt; - матрица размера &amp;lt;math&amp;gt;n \times m&amp;lt;/math&amp;gt;, составленная из векторов ортонормированного базиса пространства &amp;lt;math&amp;gt;K_m(A, v)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;y_m \in \mathbb{R}^m&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Итоговым считается решение, минимизирующее норму невязки (&amp;lt;math&amp;gt;||r||_2 = ||b - Ax_m||_2&amp;lt;/math&amp;gt;) с заданной точностью.&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Алгоритм Арнольди:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
q[1] = b/||b||&lt;br /&gt;
for j = 1, ..., n-1 do&lt;br /&gt;
    z = Aq[j]; //очередной вектор&lt;br /&gt;
    for i = 1,..., j do&lt;br /&gt;
        h[i][j] = (z, q[i]);&lt;br /&gt;
        z = z − h[i][j]q[i];&lt;br /&gt;
    end i&lt;br /&gt;
    h[j+1][j] = ||z||;&lt;br /&gt;
    if (h[j+1][j] == 0) break;&lt;br /&gt;
    q[j+1] = z/h[j+1][j];&lt;br /&gt;
end j&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Сложность алгоритма &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
На каждом шаге алгоритма получаются векторы &amp;lt;math&amp;gt;q_1, q_2, ..., q_m&amp;lt;/math&amp;gt;, являющиеся ортонормированным базисом Крыловского пространства &amp;lt;math&amp;gt;K_m(A, b)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Значения &amp;lt;math&amp;gt;h_{i,j}&amp;lt;/math&amp;gt; образуют верхнюю матрицу Хессенберга (обозначим как &amp;lt;math&amp;gt;H_m&amp;lt;/math&amp;gt;, размерность &amp;lt;math&amp;gt;m+1 \times m&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_k = \begin{bmatrix}h_{11} &amp;amp; h_{12} &amp;amp; h_{13} &amp;amp;... &amp;amp; h_{1m-1} &amp;amp; h_{1m} \\ h_{21} &amp;amp; h_{22} &amp;amp; h_{23} &amp;amp; ... &amp;amp; h_{2m-1} &amp;amp; h_{2m} \\ 0 &amp;amp; h_{32} &amp;amp; h_{33} &amp;amp;...&amp;amp; h_{3m-1} &amp;amp; h_{3m} \\ ... &amp;amp; ... &amp;amp; ... &amp;amp; ... &amp;amp; ... &amp;amp; ... \\ 0 &amp;amp; 0 &amp;amp; 0 &amp;amp; ... &amp;amp; h_{m m-1} &amp;amp; h_{mm} \\0 &amp;amp; 0 &amp;amp; 0 &amp;amp; ... &amp;amp; 0 &amp;amp; h_{m+1 m}\end{bmatrix}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Вектор невязки задан уравнением &amp;lt;math&amp;gt;r_m = H_my_m - ||b - Ax_0||e_1&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x_0&amp;lt;/math&amp;gt; - вектор начального приближения. Минимизация второй нормы вектора невязки представляет из себя решение линейной задачи минимальных квадратов размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Приближённое решение вычисляется по формуле &amp;lt;math&amp;gt; x_m = Q_my_m&amp;lt;/math&amp;gt; после нахождения соответствующего значения минимизирующего вторую невязку вектора. Сложность вычислений &amp;lt;math&amp;gt;O(nm)&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;source&amp;gt;&lt;br /&gt;
    Вычислить ортонормированный базис размера m&lt;br /&gt;
    Вычислить минимальное приближение&lt;br /&gt;
    if (приближение &amp;lt; заданная точность)&lt;br /&gt;
        Вычислить результат&lt;br /&gt;
        return;&lt;br /&gt;
    else&lt;br /&gt;
        Повторить для m = m+1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Сложность вычислений собственных векторов на каждом шаге - &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;, но может уменьшиться до &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; при более разреженной матрице.&lt;br /&gt;
&lt;br /&gt;
Сложность решения задачи минимальных квадратов &amp;lt;math&amp;gt;O(m^2)&amp;lt;/math&amp;gt;, но при последовательном выполнении алгоритма можно понизить сложность до &amp;lt;math&amp;gt;O(m)&amp;lt;/math&amp;gt; путём использования подсчитанных на прошлых итерациях значений.&lt;br /&gt;
&lt;br /&gt;
Сложность вычисления решения &amp;lt;math&amp;gt;O(nm)&amp;lt;/math&amp;gt;, поэтому его целесообразно вычислять только в конце.&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
Основной ресурс параллелизма - умножение матрицы на вектор. Для этой операции информационный граф представлен на рисунке.&lt;br /&gt;
&lt;br /&gt;
[[file:GraphLvs2FM.jpg|thumb|center|700px|Рис.1. Информационный граф умножения матрицы на вектор]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
# Параллельное умножение матрицы на вектор выполняется в &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; ярусов умножений и сложений.&lt;br /&gt;
# Шаги алгоритма Арнольди выполняются строго последовательно, однако последующее нахождение невязки можно выполнять параллельно с запуском следующего шага алгоритма.&lt;br /&gt;
# Сложность решения задачи минимальных квадратов зависит от используемого алгоритма. В отличие от последовательного метода данные, полученные на прошлых шагах здесь использовать нельзя.&lt;br /&gt;
# Вычисление результата выполняется один раз, его можно выполнить параллельно в &amp;lt;math&amp;gt; n &amp;lt;/math&amp;gt; ярусов умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; Матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;, вектор &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;, точность &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;. Объём: &amp;lt;math&amp;gt;n^2 + n + 1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные:&#039;&#039;&#039; Вектор &amp;lt;math&amp;gt;x_m&amp;lt;/math&amp;gt;. Объём: &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Теоретически на каждой итерации алгоритма сложность вычислений составляет &amp;lt;math&amp;gt;n + X&amp;lt;/math&amp;gt; операций умножения, где &amp;lt;math&amp;gt;X&amp;lt;/math&amp;gt; - сложность алгоритма для решения задачи минимальных квадратов. Таким образом в худшем случае сложность будет примерно равна &amp;lt;math&amp;gt;n^2 + X*n + n&amp;lt;/math&amp;gt; операций умножения.&lt;br /&gt;
&lt;br /&gt;
Несмотря на то, что в теории итерации алгоритма можно выполнять параллельно после выполнения алгоритма Арнольди, на практике необходимая точность может быть достигнута раньше чем на n-й итерации, что потребует какого-нибудь способа прервать последующие итерации. Для избегания лишних вычисление возможно оптимально оставить эту часть последовательной.&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Реализации алгоритма GMRES присутствуют во многих программных продуктах как части стандартных библиотек, например Matlab или DEFORM3D. Также существую отдельные библиотеки, например MGMRES для языка С++.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Тыртышников Е. Е. Методы численного анализа — М., Академия, 2007.&lt;br /&gt;
&lt;br /&gt;
[2] М. Дана, А. Г. Зыков, Х. Д. Икрамов Метод минимальных невязок для специального класса линейных систем с нормальными матрицами коэффициентов - Ж. вычисл. матем. и матем. физ., 2005, том 45, номер 11&lt;/div&gt;</summary>
		<author><name>Dan</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:Lvs&amp;diff=16266</id>
		<title>Обсуждение участника:Lvs</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:Lvs&amp;diff=16266"/>
		<updated>2016-11-09T14:48:06Z</updated>

		<summary type="html">&lt;p&gt;Dan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Пункт 1.7 =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- Поплыло форматирование: между рисунками из п.1.7 включается содержимое п.1.8 и далее&lt;br /&gt;
- Необходимо привести описание, что чему соответствует на рисунках, а лучше перерисовать. Пока это нельзя рассматривать как информационный граф.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&#039;&#039;&#039;принято&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
См. именование пункта в шаблоне.&lt;/div&gt;</summary>
		<author><name>Dan</name></author>
	</entry>
</feed>