<?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=Chernyavskiy</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=Chernyavskiy"/>
	<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/Chernyavskiy"/>
	<updated>2026-10-22T15:11:57Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9A%D0%BB%D0%B0%D1%81%D1%81%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D0%BE%D0%B2&amp;diff=23958</id>
		<title>Классификация алгоритмов</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9A%D0%BB%D0%B0%D1%81%D1%81%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D0%BE%D0%B2&amp;diff=23958"/>
		<updated>2017-11-15T12:10:16Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;# &amp;lt;div id=&amp;quot;Векторные операции&amp;quot;&amp;gt;&#039;&#039;&#039;Векторные операции&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
## {{level|Суммирование сдваиванием}}&lt;br /&gt;
### {{level|Нахождение суммы элементов массива сдваиванием}}&lt;br /&gt;
### {{level|Нахождение частных сумм элементов массива сдваиванием}}&lt;br /&gt;
## {{level|Равномерная норма вектора, вещественная версия, последовательно-параллельный вариант}}&lt;br /&gt;
## {{level|Скалярное произведение векторов, вещественная версия, последовательно-параллельный вариант}}&lt;br /&gt;
## {{level|Последовательно-параллельный метод суммирования}}&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Матрично-векторные операции&amp;quot;&amp;gt;&#039;&#039;&#039;Матрично-векторные операции&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
## {{level|Умножение плотной матрицы на вектор}}&lt;br /&gt;
### {{level|Умножение плотной неособенной матрицы на вектор (последовательный вещественный вариант)}}&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Матричные операции&amp;quot;&amp;gt;&#039;&#039;&#039;Матричные операции&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
## {{level|Умножение плотных матриц}}&lt;br /&gt;
### {{level|Перемножение плотных неособенных матриц (последовательный вещественный вариант)}}&lt;br /&gt;
### {{level|Метод Штрассена}}&lt;br /&gt;
# {{level|Разложения матриц}}&lt;br /&gt;
## {{level|Треугольные разложения}}&lt;br /&gt;
### {{level|Метод Гаусса (нахождение LU-разложения)}}&lt;br /&gt;
#### {{level|LU-разложение методом Гаусса без перестановок}}&lt;br /&gt;
##### {{level|LU-разложение методом Гаусса}}&lt;br /&gt;
##### {{level|Компактная схема метода Гаусса и её модификации}}&lt;br /&gt;
###### {{level|Компактная схема метода Гаусса для плотной матрицы}}&lt;br /&gt;
###### {{level|Компактная схема метода Гаусса для трёхдиагональной матрицы и её модификации}}&lt;br /&gt;
####### {{level|Компактная схема метода Гаусса для трёхдиагональной матрицы, последовательный вариант}}&lt;br /&gt;
####### {{level|Алгоритм сдваивания Стоуна для LU-разложения трёхдиагональной матрицы}}&lt;br /&gt;
####### {{level|Последовательно-параллельный алгоритм для LU-разложения трёхдиагональной матрицы}}&lt;br /&gt;
#### {{level|LU-разложение методом Гаусса с перестановками}}&lt;br /&gt;
##### {{level|LU-разложение методом Гаусса с выбором ведущего элемента по столбцу}}&lt;br /&gt;
##### {{level|LU-разложение методом Гаусса с выбором ведущего элемента по строке}}&lt;br /&gt;
##### {{level|LU-разложение методом Гаусса с выбором ведущего элемента по главной диагонали}}&lt;br /&gt;
##### {{level|LU-разложение методом Гаусса с выбором ведущего элемента по всей матрице}}&lt;br /&gt;
### {{level|Метод Холецкого (нахождение симметричного треугольного разложения)}}&lt;br /&gt;
#### {{level|Разложение Холецкого (метод квадратного корня)}} базовый точечный вещественный вариант для плотной симметричной положительно-определённой матрицы&lt;br /&gt;
### {{level|Известные треугольные разложения для матриц специального вида}}&lt;br /&gt;
## {{level|Унитарно-треугольные разложения}}&lt;br /&gt;
### {{level|QR-разложения плотных неособенных матриц}}&lt;br /&gt;
#### {{level|Метод Гивенса (вращений) QR-разложения матрицы}}&lt;br /&gt;
##### {{level|Метод Гивенса (вращений) QR-разложения квадратной матрицы (вещественный точечный вариант)}}&lt;br /&gt;
#### {{level|Метод Хаусхолдера (отражений) QR-разложения матрицы}}&lt;br /&gt;
##### {{level|Метод Хаусхолдера (отражений) QR-разложения квадратной матрицы, вещественный точечный вариант}}&lt;br /&gt;
#### {{level|Метод ортогонализации}}&lt;br /&gt;
##### {{level|Классический метод ортогонализации}}&lt;br /&gt;
##### {{level|Метод ортогонализации с переортогонализацией}}&lt;br /&gt;
#### {{level|Метод треугольного разложения матрицы Грама}}&lt;br /&gt;
### {{level|Методы QR-разложения плотных хессенберговых матриц}}&lt;br /&gt;
#### {{level|Метод Гивенса (вращений) QR-разложения хессенберговой матрицы (вещественный вариант)}}&lt;br /&gt;
## {{level|Подобные разложения}}&lt;br /&gt;
### {{level|Подобные разложения на унитарные и хессенберговы матрицы}}&lt;br /&gt;
#### {{level|Метод Хаусхолдера (отражений) приведения матрицы к хессенберговой (почти треугольной) форме}}&lt;br /&gt;
#### {{level|Метод Гивенса (вращений) приведения матрицы к хессенберговой (почти треугольной) форме}}&lt;br /&gt;
### {{level|Симметричные разложения на унитарные и трёхдиагональные матрицы}}&lt;br /&gt;
#### {{level|Метод Хаусхолдера (отражений) для приведения симметричных матриц к трёхдиагональному виду}}&lt;br /&gt;
#### {{level|Метод Хаусхолдера (отражений) для приведения комплексных эрмитовых матриц к трёхдиагональному симметричному виду}}&lt;br /&gt;
#### {{level|Метод Гивенса (вращений) приведения матрицы к трёхдиагональной форме}}&lt;br /&gt;
### {{level|Спектральное разложение (нахождение собственных значений и векторов)}}&lt;br /&gt;
## {{level|Разложения на унитарные и двухдиагональные матрицы}}&lt;br /&gt;
### {{level|Метод Хаусхолдера (отражений) приведения матрицы к двухдиагональной форме}}&lt;br /&gt;
### {{level|Метод Гивенса (вращений) приведения матрицы к двухдиагональной форме}}&lt;br /&gt;
## {{level|Разложения на унитарные и диагональные матрицы}}&lt;br /&gt;
### {{level|Сингулярное разложение (нахождение сингулярных значений и векторов)}}&lt;br /&gt;
#### {{level|Методы нахождения сингулярных чисел двухдиагональных матриц}}&lt;br /&gt;
##### {{level|Алгоритм dqds нахождения сингулярных чисел двухдиагональной матрицы}}&lt;br /&gt;
###### {{level|Итерация алгоритма dqds}}&lt;br /&gt;
# {{level|Решение систем линейных уравнений}}&lt;br /&gt;
## {{level|Прямые методы решения СЛАУ}}&lt;br /&gt;
### {{level|Linpack benchmark}}&lt;br /&gt;
### {{level|Методы решения СЛАУ с матрицами специального вида}}&lt;br /&gt;
#### {{level|Методы решения СЛАУ с треугольными матрицами}}&lt;br /&gt;
##### {{level|Прямая подстановка (вещественный вариант)|Прямая подстановка}}&lt;br /&gt;
##### {{level|Обратная подстановка (вещественный вариант)|Обратная подстановка}}&lt;br /&gt;
##### {{level|Методы решения СЛАУ с двудиагональными матрицами}}&lt;br /&gt;
###### {{level|Прямая и обратная подстановка в СЛАУ с двухдиагональной матрицей}}&lt;br /&gt;
###### {{level|Метод сдваивания Стоуна для решения двудиагональных СЛАУ}}&lt;br /&gt;
###### {{level|Последовательно-параллельный вариант обратной подстановки}}&lt;br /&gt;
#### {{level|Методы решения СЛАУ с трёхдиагональными матрицами}}&lt;br /&gt;
##### {{level|Методы, основанные на стандартном LU-разложении матрицы}}&lt;br /&gt;
###### {{level|Прогонка}}&lt;br /&gt;
####### {{level|Прогонка, точечный вариант}}&lt;br /&gt;
####### {{level|Классическая монотонная прогонка, повторный вариант}}&lt;br /&gt;
###### {{level|Метод сдваивания Стоуна}}&lt;br /&gt;
####### {{level|Алгоритм сдваивания Стоуна для LU-разложения трёхдиагональной матрицы}}&lt;br /&gt;
####### {{level|Метод сдваивания Стоуна для решения двудиагональных СЛАУ}}&lt;br /&gt;
###### {{level|Последовательно-параллельный вариант решения трёхдиагональной СЛАУ с LU-разложением и обратными подстановками}}&lt;br /&gt;
##### Другие методы&lt;br /&gt;
###### {{level|Метод редукции}}&lt;br /&gt;
####### {{level|Полный метод редукции}}&lt;br /&gt;
####### {{level|Повторный метод редукции для новой правой части}}&lt;br /&gt;
###### {{level|Встречная прогонка}}&lt;br /&gt;
####### {{level|Встречная прогонка, точечный вариант}}&lt;br /&gt;
####### {{level|Повторная встречная прогонка, точечный вариант}}&lt;br /&gt;
###### {{level|Метод циклической редукции}}&lt;br /&gt;
####### {{level|Полный метод циклической редукции}}&lt;br /&gt;
####### {{level|Повторный метод циклической редукции для новой правой части}}&lt;br /&gt;
###### {{level|Метод окаймления}}&lt;br /&gt;
#### Методы решения СЛАУ с блочно-треугольными матрицами&lt;br /&gt;
##### {{level|Блочная прямая подстановка (вещественный вариант)|Блочная прямая подстановка}}&lt;br /&gt;
##### {{level|Блочная обратная подстановка (вещественный вариант)|Блочная обратная подстановка}}&lt;br /&gt;
##### Методы решения СЛАУ с блочно-двухдиагональными матрицами&lt;br /&gt;
###### {{level|Прямая и обратная подстановка в СЛАУ с блочно-двухдиагональной матрицей}}&lt;br /&gt;
###### {{level|Метод сдваивания Стоуна для решения блочно-двухдиагональных СЛАУ}}&lt;br /&gt;
###### {{level|Блочный последовательно-параллельный вариант обратной подстановки для решения блочно-двухдиагональных СЛАУ}}&lt;br /&gt;
#### {{level|Методы решения СЛАУ с блочно-трёхдиагональными матрицами}}&lt;br /&gt;
##### Методы, основанные на стандартном LU-разложении матрицы&lt;br /&gt;
###### {{level|Блочная прогонка}}&lt;br /&gt;
###### {{level|Блочный последовательно-параллельный вариант решения с LU-разложением и обратными подстановками}}&lt;br /&gt;
##### Другие методы&lt;br /&gt;
###### {{level|Встречная прогонка, блочный вариант}}&lt;br /&gt;
###### {{level|Блочный метод циклической редукции}}&lt;br /&gt;
###### {{level|Блочный метод окаймления}}&lt;br /&gt;
### {{level|Решения СЛАУ с матрицами специального вида, имеющими известные обратные матрицы}}&lt;br /&gt;
## Итерационные методы решения СЛАУ&lt;br /&gt;
### {{level|High Performance Conjugate Gradient (HPCG) benchmark}}&lt;br /&gt;
### {{level|Алгоритм_Качмажа}}&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Решения спектральных задач&amp;quot;&amp;gt;&#039;&#039;&#039;Решения спектральных задач&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
## {{level|Спектральное разложение (нахождение собственных значений и векторов)}}&lt;br /&gt;
### {{level|QR-алгоритм}}&lt;br /&gt;
#### {{level|QR-алгоритм, используемый в SCALAPACK}}&lt;br /&gt;
##### {{level|Метод Хаусхолдера (отражений) приведения матрицы к хессенберговой (почти треугольной) форме}}&lt;br /&gt;
##### {{level|QR-алгоритм для хессенберговой матрицы, используемый в SCALAPACK}}&lt;br /&gt;
#### {{level|QR-алгоритм для симметричных матриц, используемый в SCALAPACK}}&lt;br /&gt;
##### {{level|Метод Хаусхолдера (отражений) для приведения симметричных матриц к трёхдиагональному виду}}&lt;br /&gt;
##### {{level|QR-алгоритм для симметричных трёхдиагональных матриц, используемый в SCALAPACK}}&lt;br /&gt;
#### {{level|QR-алгоритм для комплексных эрмитовых матриц, используемый в SCALAPACK}}&lt;br /&gt;
##### {{level|Метод Хаусхолдера (отражений) для приведения комплексных эрмитовых матриц к трёхдиагональному симметричному виду}}&lt;br /&gt;
##### {{level|QR-алгоритм для симметричных трёхдиагональных матриц, используемый в SCALAPACK}}&lt;br /&gt;
### {{level|Метод Якоби (вращений) для решения спектральной задачи у симметричных матриц}}&lt;br /&gt;
#### {{level|Классический метод Якоби (вращений) для симметричных матриц с выбором по всей матрице}}&lt;br /&gt;
#### {{level|Метод Якоби (вращений) для симметричных матриц с циклическим исключением и барьерами}}&lt;br /&gt;
### {{level|Метод Ланцоша}}&lt;br /&gt;
#### {{level|Алгоритм Ланцоша для точной арифметики (без переортогонализации)}}&lt;br /&gt;
## {{level|Частичная спектральная задача}}&lt;br /&gt;
### {{level|Метод бисекций}}&lt;br /&gt;
## {{level|Сингулярное разложение (нахождение сингулярных значений и векторов)}}&lt;br /&gt;
### {{level|Метод Якоби (вращений) для нахождения сингулярных значений неособенных матриц}}&lt;br /&gt;
### {{level|QR-алгоритм в приложении к сингулярному разложению}}&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Тесты производительности компьютеров&amp;quot;&amp;gt;&#039;&#039;&#039;Тесты производительности компьютеров&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
## {{level|High Performance Conjugate Gradient (HPCG) benchmark}}&lt;br /&gt;
## {{level|Linpack benchmark}}&lt;br /&gt;
# {{level|Преобразование Фурье}}&lt;br /&gt;
## {{level|Быстрое преобразование Фурье}}&lt;br /&gt;
### {{level|Быстрое преобразование Фурье для степеней двойки}}&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Алгебра многочленов&amp;quot;&amp;gt;&#039;&#039;&#039;Алгебра многочленов&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
## {{level|Схема Горнера, вещественная версия, последовательный вариант}}&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Численные методы интегрирования&amp;quot;&amp;gt;&#039;&#039;&#039;Численные методы интегрирования&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
## {{level|Квадратурные формулы}}&lt;br /&gt;
## {{level|Квадратурные (кубатурные) методы численного интегрирования по отрезку (многомерному кубу)}}&lt;br /&gt;
### [[Квадратурные_(кубатурные)_методы_численного_интегрирования_по_отрезку_(многомерному_кубу)#Метод прямоугольников|Метод прямоугольников]]&lt;br /&gt;
### [[Квадратурные_(кубатурные)_методы_численного_интегрирования_по_отрезку_(многомерному_кубу)#Метод трапеций|Метод трапеций]]&lt;br /&gt;
### [[Квадратурные_(кубатурные)_методы_численного_интегрирования_по_отрезку_(многомерному_кубу)#Метод парабол (метод Симпсона)|Метод парабол (метод Симпсона)]]&lt;br /&gt;
### [[Квадратурные_(кубатурные)_методы_численного_интегрирования_по_отрезку_(многомерному_кубу)#Метод Гаусса|Метод Гаусса]]&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Алгоритмы на графах&amp;quot;&amp;gt;&#039;&#039;&#039;Алгоритмы на графах&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
## Обход графа&lt;br /&gt;
### {{level|Поиск в ширину (BFS)}}&lt;br /&gt;
### {{level|Поиск в глубину (DFS)}}&lt;br /&gt;
## {{level|Поиск кратчайшего пути от одной вершины (SSSP)}}&lt;br /&gt;
### {{level|Поиск в ширину (BFS)}} (для невзвешенных графов)&lt;br /&gt;
### {{level|Алгоритм Дейкстры}}&lt;br /&gt;
### {{level|Алгоритм Беллмана-Форда}}&lt;br /&gt;
### {{level|Алгоритм Δ-шагания}}&lt;br /&gt;
## {{level|Поиск кратчайшего пути для всех пар вершин (APSP)}}&lt;br /&gt;
### {{level|Алгоритм Джонсона}}&lt;br /&gt;
### {{level|Алгоритм Флойда-Уоршелла}}&lt;br /&gt;
## {{level|Поиск транзитивного замыкания орграфа}}&lt;br /&gt;
### {{level|Алгоритм Пурдома}}&lt;br /&gt;
## {{level|Определение диаметра графа}}&lt;br /&gt;
## {{level|Построение минимального остовного дерева (MST)}}&lt;br /&gt;
### {{level|Алгоритм Борувки}}&lt;br /&gt;
### {{level|Алгоритм Крускала}}&lt;br /&gt;
### {{level|Алгоритм Прима}}&lt;br /&gt;
### {{level|Алгоритм GHS}}&lt;br /&gt;
## {{level|Поиск изоморфных подграфов}}&lt;br /&gt;
### {{level|Алгоритм Ульмана}}&lt;br /&gt;
### {{level|Алгоритм VF2}}&lt;br /&gt;
## {{level|Связность в графах}}&lt;br /&gt;
### {{level|Алгоритм Шилоаха-Вишкина поиска компонент связности}}&lt;br /&gt;
### {{level|Система непересекающихся множеств}}&lt;br /&gt;
### {{level|Алгоритм Тарьяна поиска компонент сильной связности}}&lt;br /&gt;
### {{level|Алгоритм DCSC поиска компонент сильной связности}}&lt;br /&gt;
### {{level|Алгоритм Тарьяна поиска компонент двусвязности}}&lt;br /&gt;
### {{level|Алгоритм Тарьяна-Вишкина поиска компонент двусвязности}}&lt;br /&gt;
### {{level|Алгоритм Тарьяна поиска «мостов» в графе}}&lt;br /&gt;
### {{level|Определение вершинной связности графа}}&lt;br /&gt;
### {{level|Алгоритм Габова определения рёберной связности графа}}&lt;br /&gt;
## {{level|Поиск максимального потока в транспортной сети}}&lt;br /&gt;
### {{level|Алгоритм Форда-Фалкерсона}}&lt;br /&gt;
### {{level|Алгоритм проталкивания предпотока}}&lt;br /&gt;
## {{level|Поиск потока минимальной стоимости в транспортной сети}}&lt;br /&gt;
## {{level|Задача о назначениях}}&lt;br /&gt;
### {{level|Венгерский алгоритм}}&lt;br /&gt;
### {{level|Алгоритм аукциона}}&lt;br /&gt;
### {{level|Алгоритм Гопкрофта-Карпа}}&lt;br /&gt;
## {{level|Вычисление betweenness centrality|Вычисление центральности вершин}}&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Алгоритмы поиска&amp;quot;&amp;gt;&#039;&#039;&#039;Алгоритмы поиска&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
## {{level|Линейный поиск - находит элемент в любом списке|Линейный поиск}}, &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
## {{level|Двоичный поиск - находит элемент в отсортированном списке|Двоичный поиск}}, &amp;lt;math&amp;gt;O(log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Алгоритмы сортировки&amp;quot;&amp;gt;&#039;&#039;&#039;Алгоритмы сортировки&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
## {{level|Сортировка с помощью двоичного дерева}}&lt;br /&gt;
## {{level|Сортировка пузырьком}}&lt;br /&gt;
## {{level|Сортировка слиянием (последовательный и параллельный варианты)}}&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Вычислительная геометрия&amp;quot;&amp;gt;&#039;&#039;&#039;Вычислительная геометрия&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
## {{level|Поиск диаметра множества точек}}&lt;br /&gt;
## {{level|Построение выпуклой оболочки набора точек}}&lt;br /&gt;
## {{level|Триангуляция Делоне}}&lt;br /&gt;
## {{level|Диаграмма Вороного}}&lt;br /&gt;
## {{level|Принадлежность точки многоугольнику}}&lt;br /&gt;
## {{level|Пересечения выпуклых многоугольников}} - трудоёмкость &amp;lt;math&amp;gt;O(n_1 + n_2)&amp;lt;/math&amp;gt;&lt;br /&gt;
## {{level|Пересечение звёздных многоугольников}} - трудоёмкость &amp;lt;math&amp;gt;O(n_1 * n_2)&amp;lt;/math&amp;gt;&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Компьютерная графика&amp;quot;&amp;gt;&#039;&#039;&#039;Компьютерная графика&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
## {{level|Алгоритмы построения отрезка - алгоритмы для аппроксимации отрезка на дискретной графической поверхности}}&lt;br /&gt;
## {{level|Алгоритм определения видимых частей трёхмерной сцены}}&lt;br /&gt;
## {{level|Трассировка лучей - рендеринг реалистичных изображений}}&lt;br /&gt;
## {{level|Глобальное освещение - рассматривает прямое освещение и отражение от других объектов}}&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Криптографические алгоритмы&amp;quot;&amp;gt;&#039;&#039;&#039;Криптографические алгоритмы&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Нейронные сети&amp;quot;&amp;gt;&#039;&#039;&#039;Нейронные сети&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Алгоритмы оптимизации&amp;quot;&amp;gt;&#039;&#039;&#039;Алгоритмы оптимизации&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
## {{level|Линейное программирование}}&lt;br /&gt;
## {{level|Симплекс-метод}}&lt;br /&gt;
## {{level|Метод ветвей и границ (последовательный и параллельный варианты)}}&lt;br /&gt;
## {{level|Генетические алгоритмы}}&lt;br /&gt;
## {{level|Муравьиные алгоритмы}}&lt;br /&gt;
## {{level|Комбинированные алгоритмы}}&lt;br /&gt;
## {{level|Нахождение экстремума функции}}&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Алгоритмы теории игр&amp;quot;&amp;gt;&#039;&#039;&#039;Алгоритмы теории игр&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Алгоритмы моделирования квантовых систем&amp;quot;&amp;gt;&#039;&#039;&#039;Алгоритмы моделирования квантовых систем&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
## &#039;&#039;Алгоритмы моделирования квантовых вычислений&#039;&#039;&lt;br /&gt;
### {{level|Однокубитное преобразование вектора-состояния}}&lt;br /&gt;
### {{level|Двухкубитное преобразование вектора-состояния}}&lt;br /&gt;
### {{level|Моделирование квантового преобразования Фурье}}&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Алгоритмы решения уравнений математической физики&amp;quot;&amp;gt;&#039;&#039;&#039;Алгоритмы решения уравнений математической физики&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
## {{level|Уравнение Пуассона, решение дискретным преобразованием Фурье}}&lt;br /&gt;
# &amp;lt;div id=&amp;quot;Другие алгоритмы&amp;quot;&amp;gt;&#039;&#039;&#039;Другие алгоритмы&#039;&#039;&#039;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[en:Algorithm classification]]&lt;br /&gt;
&lt;br /&gt;
[[Категория:Алгоритмы|*]]&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9F%D0%B5%D0%B9%D0%BB%D0%B8_%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=22606</id>
		<title>Алгоритм Пейли построения матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9F%D0%B5%D0%B9%D0%BB%D0%B8_%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=22606"/>
		<updated>2017-05-03T20:50:37Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Литература */&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(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:Nikita|Иванов Н.В.]] (Разделы 1.1,1.7,1.9,1.10,2.4,2.7), [[Участник:Tsyganov Nikita|Цыганов Н.И.]] (Разделы 1.2,1.3,1.4,1.5,1.6,1.7,1.8,2.4), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (проверка, редактирование),  [[Участник:Sleo|С.Н.Леоненков]] (предварительня проверка), &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;rt&amp;quot;&amp;gt;http://cyberleninka.ru/article/n/matritsy-adamara-nechetnogo-poryadka.pdf&amp;lt;/ref&amp;gt; Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). &amp;lt;ref name=&amp;quot;rt2&amp;quot;&amp;gt;Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&amp;lt;/ref&amp;gt; М&lt;br /&gt;
&lt;br /&gt;
В данном описании рассматривается метод Пейли, основанный на теоретико-числовых принципах и позволяющий строить матрицы Адамара порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для решения поставленной задачи будем использовать метод Пейли.&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p. &lt;br /&gt;
&lt;br /&gt;
Чтобы найти все вычеты по модулю p, достаточно рассмотреть квадраты чисел от &amp;lt;math&amp;gt;1^2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;(p-1)^2&amp;lt;/math&amp;gt;. Но если учесть, что &amp;lt;math&amp;gt;(p-a)^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p = (-a)^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p = a^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p&amp;lt;/math&amp;gt;, то достаточно рассмотреть лишь числа &amp;lt;math&amp;gt;1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod &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;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Все элементы главной диагонали этой матрицы, кроме элемента &amp;lt;math&amp;gt;h_{00}&amp;lt;/math&amp;gt;, равны &amp;lt;math&amp;gt;X(0)-1=-1&amp;lt;/math&amp;gt;. Нетрудно заметить, что данная матрица состоит только лишь из элементов 1 и -1.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&amp;lt;ref name=&amp;quot;rt3&amp;quot;&amp;gt;http://tc.nsu.ru/uploads/codingtheory.pdf&amp;lt;/ref&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;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-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;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&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;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt; vector&amp;lt;int&amp;gt; &amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
    // 1) matrix size changing&lt;br /&gt;
    result.resize(n);&lt;br /&gt;
    for (int i=0; i&amp;lt;n; i++) {&lt;br /&gt;
        result[i].resize(n);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // 2) residue array building&lt;br /&gt;
    int p=n-1;&lt;br /&gt;
    vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
    residues.resize(2*p);&lt;br /&gt;
    for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
        residues[i] = -1;&lt;br /&gt;
    }&lt;br /&gt;
    for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
        residues[i*i % p] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
        residues[i] = residues[i-p];&lt;br /&gt;
    }&lt;br /&gt;
    // 3) Paley matrix building&lt;br /&gt;
    // first line filling&lt;br /&gt;
    for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
        result[0][j] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    // first column filling&lt;br /&gt;
    for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
        result[i][0] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    // others&lt;br /&gt;
    for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
        for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
            result[i][j] = residues[j-i+p];&lt;br /&gt;
        }&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;
Под сложностью будем понимать зависимость числа операций от задаваемого порядка матрицы &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;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&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;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph2.png|600px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания, каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt; соответствует трём последовательным операциям: умножения, взятия остатка по модулю и присваивания, а вершины, окрашенные серым, представляют собой промежуточные точки синхронизации.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph3.jpg|600px|thumb|center|Информационный граф для n=4.]]&lt;br /&gt;
На рисунке приведен информационный граф алгоритма для случая n=4. Вершины графа соответствуют следующим строчкам кода:&lt;br /&gt;
&lt;br /&gt;
a. residues[i] = -1;&lt;br /&gt;
&lt;br /&gt;
b. residues[i*i%p] = 1;&lt;br /&gt;
&lt;br /&gt;
c. residues[i] = residues[i-p];&lt;br /&gt;
&lt;br /&gt;
d. result[0][j] = 1;&lt;br /&gt;
&lt;br /&gt;
e. result[i][0] = 1;&lt;br /&gt;
&lt;br /&gt;
f. result[i][j] = residues[i-j+p];&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа алгоритма, в параллельном варианте необходимо последовательно выполнить следующие блоки:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; участков, состоящих из трёх операций: умножения, взятия остатка и присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из этого можно сделать вывод, что высота ярусно-параллельной формы информационного графа равняется 6 (присваивание, умножение, взятие остатка, присваивание, присваивание, присваивание). Ширина ярусно-параллельной формы равняется &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;, что означает, что при использовании &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; процессоров матрица Адамара будет строиться за 6 операций.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - порядок матрицы Адамара &amp;lt;math&amp;gt;H_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;n&amp;lt;/math&amp;gt; - натуральное;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое.&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &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;H_n&amp;lt;/math&amp;gt; (её элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара размера &amp;lt;math&amp;gt;n*n&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;O(1)&amp;lt;/math&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
Алгоритм является полностью детерминированным. &lt;br /&gt;
&lt;br /&gt;
Для вершин &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt; информационного графа степени исхода являются линейными, что означает, что при возможности на этапе реализации необходимо позаботиться об эффективном доступе к элементам массива &amp;quot;&amp;lt;math&amp;gt;residues&amp;lt;/math&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма построения матрицы Адамара проводилось на суперкомпьютере «Ломоносов». Для этого была исследована собственная реализация алгоритма с использованием средств MPI. В ходе исследования  было произведено множество запусков программы с различными значениями параметра &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (размер матрицы Адамара) и числом процессоров.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма:&lt;br /&gt;
*число процессоров (p): [2,64] с шагом 2;&lt;br /&gt;
*размер матрицы: простые числа в диапазоне [4,10000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон эффективности реализации алгоритма:&lt;br /&gt;
*минимальная эффективность реализации 0.0000036% при n=4, p=2;&lt;br /&gt;
*максимальная эффективность реализации 0.333426% при n=948, p=2.&lt;br /&gt;
&lt;br /&gt;
Ниже представлены графики времени работы, производительности и эффективности данной реализации алгоритма построения матрицы Адамара в зависимости от изменяемых параметров запуска.&lt;br /&gt;
[[Файл:time_graph1.png|500px|thumb|center|Время работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:perform_graph1.png|500px|thumb|center|Изменение производительности параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:efficiency_graph1.png|500px|thumb|center|Эффективность работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/snikersman/Hadamard Исследованная параллельная реализация на языке 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;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм построения матрицы Адамара реализован в различных математических пакетах и библиотеках: &lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория:Статьи в работе]]&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</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:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=22605</id>
		<title>Участник:Nikita/Построение матрицы Адамара</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:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=22605"/>
		<updated>2017-05-03T20:49:59Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Литература */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Sleo}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы статьи: [[Участник:Nikita|Иванов Н.В.]] (1.1,1.7,1.9,1.10,2.4,2.7), [[Участник:Tsyganov Nikita|Цыганов Н.И.]] (1.2,1.3,1.4,1.5,1.6,1.7,1.8,2.4).&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;rt&amp;quot;&amp;gt;http://cyberleninka.ru/article/n/matritsy-adamara-nechetnogo-poryadka.pdf&amp;lt;/ref&amp;gt; Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). &amp;lt;ref name=&amp;quot;rt2&amp;quot;&amp;gt;Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&amp;lt;/ref&amp;gt; Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для решения поставленной задачи будем использовать метод Пейли.&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p. &lt;br /&gt;
&lt;br /&gt;
Чтобы найти все вычеты по модулю p, достаточно рассмотреть квадраты чисел от &amp;lt;math&amp;gt;1^2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;(p-1)^2&amp;lt;/math&amp;gt;. Но если учесть, что &amp;lt;math&amp;gt;(p-a)^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p = (-a)^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p = a^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p&amp;lt;/math&amp;gt;, то достаточно рассмотреть лишь числа &amp;lt;math&amp;gt;1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod &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;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Все элементы главной диагонали этой матрицы, кроме элемента &amp;lt;math&amp;gt;h_{00}&amp;lt;/math&amp;gt;, равны &amp;lt;math&amp;gt;X(0)-1=-1&amp;lt;/math&amp;gt;. Нетрудно заметить, что данная матрица состоит только лишь из элементов 1 и -1.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&amp;lt;ref name=&amp;quot;rt3&amp;quot;&amp;gt;http://tc.nsu.ru/uploads/codingtheory.pdf&amp;lt;/ref&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;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-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;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&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;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt; vector&amp;lt;int&amp;gt; &amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
    // 1) matrix size changing&lt;br /&gt;
    result.resize(n);&lt;br /&gt;
    for (int i=0; i&amp;lt;n; i++) {&lt;br /&gt;
        result[i].resize(n);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // 2) residue array building&lt;br /&gt;
    int p=n-1;&lt;br /&gt;
    vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
    residues.resize(2*p);&lt;br /&gt;
    for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
        residues[i] = -1;&lt;br /&gt;
    }&lt;br /&gt;
    for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
        residues[i*i % p] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
        residues[i] = residues[i-p];&lt;br /&gt;
    }&lt;br /&gt;
    // 3) Paley matrix building&lt;br /&gt;
    // first line filling&lt;br /&gt;
    for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
        result[0][j] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    // first column filling&lt;br /&gt;
    for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
        result[i][0] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    // others&lt;br /&gt;
    for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
        for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
            result[i][j] = residues[j-i+p];&lt;br /&gt;
        }&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;
Под сложностью будем понимать зависимость числа операций от задаваемого порядка матрицы &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;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&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;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph2.png|600px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания, каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt; соответствует трём последовательным операциям: умножения, взятия остатка по модулю и присваивания, а вершины, окрашенные серым, представляют собой промежуточные точки синхронизации.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph3.jpg|600px|thumb|center|Информационный граф для n=4.]]&lt;br /&gt;
На рисунке приведен информационный граф алгоритма для случая n=4. Вершины графа соответствуют следующим строчкам кода:&lt;br /&gt;
&lt;br /&gt;
a. residues[i] = -1;&lt;br /&gt;
&lt;br /&gt;
b. residues[i*i%p] = 1;&lt;br /&gt;
&lt;br /&gt;
c. residues[i] = residues[i-p];&lt;br /&gt;
&lt;br /&gt;
d. result[0][j] = 1;&lt;br /&gt;
&lt;br /&gt;
e. result[i][0] = 1;&lt;br /&gt;
&lt;br /&gt;
f. result[i][j] = residues[i-j+p];&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа алгоритма, в параллельном варианте необходимо последовательно выполнить следующие блоки:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; участков, состоящих из трёх операций: умножения, взятия остатка и присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из этого можно сделать вывод, что высота ярусно-параллельной формы информационного графа равняется 6 (присваивание, умножение, взятие остатка, присваивание, присваивание, присваивание). Ширина ярусно-параллельной формы равняется &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;, что означает, что при использовании &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; процессоров матрица Адамара будет строиться за 6 операций.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - порядок матрицы Адамара &amp;lt;math&amp;gt;H_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;n&amp;lt;/math&amp;gt; - натуральное;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое.&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &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;H_n&amp;lt;/math&amp;gt; (её элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара размера &amp;lt;math&amp;gt;n*n&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;O(1)&amp;lt;/math&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
Алгоритм является полностью детерминированным. &lt;br /&gt;
&lt;br /&gt;
Для вершин &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt; информационного графа степени исхода являются линейными, что означает, что при возможности на этапе реализации необходимо позаботиться об эффективном доступе к элементам массива &amp;quot;&amp;lt;math&amp;gt;residues&amp;lt;/math&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма построения матрицы Адамара проводилось на суперкомпьютере «Ломоносов». Для этого была исследована собственная реализация алгоритма с использованием средств MPI. В ходе исследования  было произведено множество запусков программы с различными значениями параметра &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (размер матрицы Адамара) и числом процессоров.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма:&lt;br /&gt;
*число процессоров (p): [2,64] с шагом 2;&lt;br /&gt;
*размер матрицы: простые числа в диапазоне [4,10000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон эффективности реализации алгоритма:&lt;br /&gt;
*минимальная эффективность реализации 0.0000036% при n=4, p=2;&lt;br /&gt;
*максимальная эффективность реализации 0.333426% при n=948, p=2.&lt;br /&gt;
&lt;br /&gt;
Ниже представлены графики времени работы, производительности и эффективности данной реализации алгоритма построения матрицы Адамара в зависимости от изменяемых параметров запуска.&lt;br /&gt;
[[Файл:time_graph1.png|500px|thumb|center|Время работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:perform_graph1.png|500px|thumb|center|Изменение производительности параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:efficiency_graph1.png|500px|thumb|center|Эффективность работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/snikersman/Hadamard Исследованная параллельная реализация на языке 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;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм построения матрицы Адамара реализован в различных математических пакетах и библиотеках: &lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</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:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=22604</id>
		<title>Участник:Nikita/Построение матрицы Адамара</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:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=22604"/>
		<updated>2017-05-03T20:49:35Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Литература */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Sleo}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы статьи: [[Участник:Nikita|Иванов Н.В.]] (1.1,1.7,1.9,1.10,2.4,2.7), [[Участник:Tsyganov Nikita|Цыганов Н.И.]] (1.2,1.3,1.4,1.5,1.6,1.7,1.8,2.4).&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;rt&amp;quot;&amp;gt;http://cyberleninka.ru/article/n/matritsy-adamara-nechetnogo-poryadka.pdf&amp;lt;/ref&amp;gt; Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). &amp;lt;ref name=&amp;quot;rt2&amp;quot;&amp;gt;Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&amp;lt;/ref&amp;gt; Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для решения поставленной задачи будем использовать метод Пейли.&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p. &lt;br /&gt;
&lt;br /&gt;
Чтобы найти все вычеты по модулю p, достаточно рассмотреть квадраты чисел от &amp;lt;math&amp;gt;1^2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;(p-1)^2&amp;lt;/math&amp;gt;. Но если учесть, что &amp;lt;math&amp;gt;(p-a)^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p = (-a)^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p = a^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p&amp;lt;/math&amp;gt;, то достаточно рассмотреть лишь числа &amp;lt;math&amp;gt;1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod &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;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Все элементы главной диагонали этой матрицы, кроме элемента &amp;lt;math&amp;gt;h_{00}&amp;lt;/math&amp;gt;, равны &amp;lt;math&amp;gt;X(0)-1=-1&amp;lt;/math&amp;gt;. Нетрудно заметить, что данная матрица состоит только лишь из элементов 1 и -1.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&amp;lt;ref name=&amp;quot;rt3&amp;quot;&amp;gt;http://tc.nsu.ru/uploads/codingtheory.pdf&amp;lt;/ref&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;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-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;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&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;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt; vector&amp;lt;int&amp;gt; &amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
    // 1) matrix size changing&lt;br /&gt;
    result.resize(n);&lt;br /&gt;
    for (int i=0; i&amp;lt;n; i++) {&lt;br /&gt;
        result[i].resize(n);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // 2) residue array building&lt;br /&gt;
    int p=n-1;&lt;br /&gt;
    vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
    residues.resize(2*p);&lt;br /&gt;
    for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
        residues[i] = -1;&lt;br /&gt;
    }&lt;br /&gt;
    for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
        residues[i*i % p] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
        residues[i] = residues[i-p];&lt;br /&gt;
    }&lt;br /&gt;
    // 3) Paley matrix building&lt;br /&gt;
    // first line filling&lt;br /&gt;
    for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
        result[0][j] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    // first column filling&lt;br /&gt;
    for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
        result[i][0] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    // others&lt;br /&gt;
    for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
        for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
            result[i][j] = residues[j-i+p];&lt;br /&gt;
        }&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;
Под сложностью будем понимать зависимость числа операций от задаваемого порядка матрицы &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;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&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;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph2.png|600px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания, каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt; соответствует трём последовательным операциям: умножения, взятия остатка по модулю и присваивания, а вершины, окрашенные серым, представляют собой промежуточные точки синхронизации.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph3.jpg|600px|thumb|center|Информационный граф для n=4.]]&lt;br /&gt;
На рисунке приведен информационный граф алгоритма для случая n=4. Вершины графа соответствуют следующим строчкам кода:&lt;br /&gt;
&lt;br /&gt;
a. residues[i] = -1;&lt;br /&gt;
&lt;br /&gt;
b. residues[i*i%p] = 1;&lt;br /&gt;
&lt;br /&gt;
c. residues[i] = residues[i-p];&lt;br /&gt;
&lt;br /&gt;
d. result[0][j] = 1;&lt;br /&gt;
&lt;br /&gt;
e. result[i][0] = 1;&lt;br /&gt;
&lt;br /&gt;
f. result[i][j] = residues[i-j+p];&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа алгоритма, в параллельном варианте необходимо последовательно выполнить следующие блоки:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; участков, состоящих из трёх операций: умножения, взятия остатка и присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из этого можно сделать вывод, что высота ярусно-параллельной формы информационного графа равняется 6 (присваивание, умножение, взятие остатка, присваивание, присваивание, присваивание). Ширина ярусно-параллельной формы равняется &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;, что означает, что при использовании &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; процессоров матрица Адамара будет строиться за 6 операций.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - порядок матрицы Адамара &amp;lt;math&amp;gt;H_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;n&amp;lt;/math&amp;gt; - натуральное;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое.&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &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;H_n&amp;lt;/math&amp;gt; (её элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара размера &amp;lt;math&amp;gt;n*n&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;O(1)&amp;lt;/math&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
Алгоритм является полностью детерминированным. &lt;br /&gt;
&lt;br /&gt;
Для вершин &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt; информационного графа степени исхода являются линейными, что означает, что при возможности на этапе реализации необходимо позаботиться об эффективном доступе к элементам массива &amp;quot;&amp;lt;math&amp;gt;residues&amp;lt;/math&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма построения матрицы Адамара проводилось на суперкомпьютере «Ломоносов». Для этого была исследована собственная реализация алгоритма с использованием средств MPI. В ходе исследования  было произведено множество запусков программы с различными значениями параметра &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (размер матрицы Адамара) и числом процессоров.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма:&lt;br /&gt;
*число процессоров (p): [2,64] с шагом 2;&lt;br /&gt;
*размер матрицы: простые числа в диапазоне [4,10000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон эффективности реализации алгоритма:&lt;br /&gt;
*минимальная эффективность реализации 0.0000036% при n=4, p=2;&lt;br /&gt;
*максимальная эффективность реализации 0.333426% при n=948, p=2.&lt;br /&gt;
&lt;br /&gt;
Ниже представлены графики времени работы, производительности и эффективности данной реализации алгоритма построения матрицы Адамара в зависимости от изменяемых параметров запуска.&lt;br /&gt;
[[Файл:time_graph1.png|500px|thumb|center|Время работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:perform_graph1.png|500px|thumb|center|Изменение производительности параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:efficiency_graph1.png|500px|thumb|center|Эффективность работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/snikersman/Hadamard Исследованная параллельная реализация на языке 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;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм построения матрицы Адамара реализован в различных математических пакетах и библиотеках: &lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория:Статьи в работе]]&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BF%D0%BE%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D1%81%D1%82%D0%B5%D0%BF%D0%B5%D0%BD%D0%B8_2&amp;diff=22603</id>
		<title>Алгоритм поэлементного построения матрицы Адамара размерности степени 2</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BF%D0%BE%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D1%81%D1%82%D0%B5%D0%BF%D0%B5%D0%BD%D0%B8_2&amp;diff=22603"/>
		<updated>2017-05-03T20:49:04Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[U:Бугаков Юрий|Ю.Бугаков]], Е. Кужамалиев, [[Участник:Chernyavskiy|А.Ю.Чернявский]] (редактирование), С.Н. Леоненков (предварительная проверка)&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O( \left[ \frac{n}{4}\right]\,2^{2n})&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(2^{2n})&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;2^{2n}&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;
Важную роль в алгебре и комбинаторике играют матрицы Адамара, которые впервые были введены в математический обиход в конце прошлого века одним из крупнейших французских математиков [https://ru.wikipedia.org/wiki/%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80,_%D0%96%D0%B0%D0%BA Жаком Адамаром (1865-1963)]. Их применение в науке и технике посвящены тысячи публикаций. Они предоставляют эффективные возможности для организации хранения, обработки и передачи информации.&lt;br /&gt;
&lt;br /&gt;
Квадратная матрица Н порядка &#039;&#039;m&#039;&#039; с элементами ±1 называется матрицей Адамара, если выполняется условие&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt; H_m\,H_m^T = m\,E_m &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нетрудно заметить, что различные строки матрицы Адамара попарно ортогональны &amp;lt;ref&amp;gt;Мак-Вильямс Ф.Дж., Слоэн Н.Дж.А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — 744 с.&amp;lt;/ref&amp;gt;. Также, можно увидеть из определения, что m четно и&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
H_{2m} =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
H_{m} &amp;amp;  H_{m}\\&lt;br /&gt;
H_{m} &amp;amp; -H_{m}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
С матрицами Адамара связан ряд нерешенных проблем, одна из которых состоит в следующем. Мы уже видели, что порядок &#039;&#039;m&#039;&#039; матрицы Адамара при &#039;&#039;m&#039;&#039; ≥ 3 может быть лишь четным. Более того, при &#039;&#039;m&#039;&#039; ≥ 4 порядок обязан делиться на 4. До сих пор остается открытым вопрос: для любого ли &#039;&#039;m&#039;&#039;, кратного 4, существует матрица Адамара порядка m? Неизвестно, в частности, существует ли матрица Адамара порядка 268 (это наименьший порядок, кратный 4, для которого матрица Адамара еще не построена).&lt;br /&gt;
&lt;br /&gt;
Часто матрицу Адамара нормализуют и рассматривают размерности степени 2 &amp;lt;ref&amp;gt;Кронберг, Ю.И. Ожигов, А.Ю. Чернявский — Алгебраический аппарат квантовой информатики 2&amp;lt;/ref&amp;gt;&amp;lt;ref name=&amp;quot;kunz&amp;quot;&amp;gt; Kunz H.O.. On the Equivalence Between One-Dimensional Discrete Walsh-Hadamard and Multidimensional Discrete Fourier Transforms. IEEE Transactions on Computers. 28 (3): 267–8. [https://en.wikipedia.org/wiki/Digital_object_identifier doi]:[http://ieeexplore.ieee.org/document/1675334/ 10.1109/TC.1979.1675334]&amp;lt;/ref&amp;gt;&amp;lt;ref name=&amp;quot;wiki&amp;quot;&amp;gt;Википедия – свободная энциклопедия [Электронный ресурс]. -  https://en.wikipedia.org/wiki/Hadamard_transform. - (дата обращения: 15.10.2016).&amp;lt;/ref&amp;gt;). В дальнейшем будем рассматривать только такие случаи. Переопределим матрицу Адамара следующим образом:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Матрица Адамара &#039;&#039;H&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sub&amp;gt;  - это матрица размера 2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;times;&amp;amp;nbsp;2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;, для которой справедливо равенство&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;H_n = H_{1} \otimes H_{n-1}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  H_1 = \frac{1}{\sqrt2}&lt;br /&gt;
   &amp;amp;\begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&#039;&#039;&#039;где &amp;lt;math&amp;gt; \otimes &amp;lt;/math&amp;gt; представляет собой [https://ru.wikipedia.org/wiki/%D0%A2%D0%B5%D0%BD%D0%B7%D0%BE%D1%80%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5 тензорное произведение].&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Представим некоторые частные примеры матриц Адамара:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_0 = +1,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_1 = \frac{1}{\sqrt2}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_2 = \frac{1}{2}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1&lt;br /&gt;
    \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_3 = \frac{1}{2^{\frac{3}{2}}}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rrrrrrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1 &amp;amp; 1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    \end{array}\end{pmatrix}&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;H_n&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;2^n\times 2^n&amp;lt;/math&amp;gt; можно вычислить поэлементно&amp;lt;ref name=&amp;quot;kunz&amp;quot;/&amp;gt;&amp;lt;ref name=&amp;quot;wiki&amp;quot;/&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{k,l} = \frac{1}{2^\frac{n}{2}} (-1)^{\sum_j k_j l_j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
где &#039;&#039;k&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;j&#039;&#039;&amp;lt;/sub&amp;gt; и &#039;&#039;l&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;j&#039;&#039;&amp;lt;/sub&amp;gt; коэффициенты двоичного разложения чисел &#039;&#039;k&#039;&#039; и &#039;&#039;l&#039;&#039; (1 или 0):&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;k = \sum^{n}_{i=0} {k_i 2^i} = k_{n} 2^{n} + k_{n-1} 2^{n-1} + \cdots + k_1 2 + k_0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и&lt;br /&gt;
: &amp;lt;math&amp;gt;l = \sum^{n}_{i=0} {l_i 2^i} = l_{n} 2^{n} + l_{n-1} 2^{n-1} + \cdots + l_1 2 + l_0&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;h_{k,l} = \frac{1}{2^\frac{n}{2}} (-1)^{\sum_j k_j l_j}&amp;lt;/math&amp;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;\sum_{j=0}^n k_j l_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Как видно по формуле, получаемое значение равна количеству единиц в двоичной записи результата побитового умножения &#039;&#039;k&#039;&#039; и &#039;&#039;l&#039;&#039;. Существует эффективный метод вычисления количества единиц , сложность которого равна &#039;&#039;m&#039;&#039; операций вычитания и &#039;&#039;m&#039;&#039; операций побитового умножения, где &#039;&#039;m&#039;&#039;-искомое количество единиц.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. Побитовое умножение &amp;lt;math&amp;gt;k\&amp;amp;l&amp;lt;/math&amp;gt;;  &lt;br /&gt;
&lt;br /&gt;
2. Вычисление количества единиц двоичной записи;&lt;br /&gt;
&lt;br /&gt;
3. Определение знака элемента по степени.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения матрицы Адамара порядка &amp;lt;math&amp;gt;N=2^n&amp;lt;/math&amp;gt; в первом шаге потребуется &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt; побитовых умножений &#039;&#039;k&amp;amp;l&#039;&#039;.&lt;br /&gt;
Во втором шаге, как говорилось выше, сложность метода вычисления количества единиц  числа в двоичном представлении равна удвоенному количеству единиц. В наихудшем случае сложность равна &amp;lt;math&amp;gt;2log_2N&amp;lt;/math&amp;gt;, при &#039;&#039;k=l=N-1&#039;&#039;, а в наилучшем 0. Для нахождения  степени всех элементов матрицы потребуются &amp;lt;math&amp;gt; 2N^2\left[\frac{log_2N}{4}\right]&amp;lt;/math&amp;gt; операций. В третьем шаге для определения знака потребуется &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt; операций, то есть сложность алгоритма &amp;lt;math&amp;gt; T(n) = 2\,(1+\left[\frac{n}{4}\right])\,2^{2n}. &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
На рисунке ниже изображен информационный граф &amp;lt;ref&amp;gt;Воеводин В.В.. Воеводин Вл.В. Параллельные вычисления. - СПб.: БХВ-Петербург, 2002. - 608 с.&amp;lt;/ref&amp;gt; алгоритма.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;k\&amp;amp;l&amp;lt;/math&amp;gt; - операция побитового умножения, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; соответствующие координаты элемента &amp;lt;math&amp;gt;h_{kl}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* OP - вычисление количества единиц числа в двоичной системе. Состоит из последовательного применения операций вычитания и побитового умножения;&lt;br /&gt;
* SGN - определение знака соответствующего элемента. Если результат предыдущего шага четное, то знак положительный, иначе отрицательный.  &lt;br /&gt;
&lt;br /&gt;
[[file:Hadamar.png|thumb|center|1400px|Рисунок 1. Граф алгоритма.]]&lt;br /&gt;
[[file:OP3.png|thumb|center|1400px|Рисунок 2. Граф OP.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения матрицы порядка &amp;lt;math&amp;gt;N=2^n&amp;lt;/math&amp;gt; требуется последовательно выполнить следующие шаги:&lt;br /&gt;
* &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt;  вычислений побитового умножения,&lt;br /&gt;
* для каждого элемента от &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций вычитания и побитового умножения, в зависимости от результата предыдущего шага,&lt;br /&gt;
* &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt;  для определения знака значения элемента.&lt;br /&gt;
 &lt;br /&gt;
Таким образом для построения необходимы лишь простые операции вычитания и побитового умножения выполняемые с целыми положительными числами. Стоит заметить что вычисления для каждого элемента не зависят друг от друга. Также можно воспользоваться либо симметричностью матрицы Адамара либо закономерностью областей показанная в пункте 1.1.&lt;br /&gt;
Таким образом, основной вклад в высотe ЯПФ вносит операция вычисления количества единиц. Ширина ЯПФ будет равна &amp;lt;math&amp;gt;O(2^{2n})&amp;lt;/math&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; n \in \N &amp;lt;/math&amp;gt; - размерность матрицы Адамара &amp;lt;math&amp;gt;H_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: 1 (натуральное число &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;H_n&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;2^n\times 2^n&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2^{2n}&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;
Одним из трудных мест параллельной реализации является правильный выбор количества процессов. Рассматривается некоторое фиксированное число процессов &amp;lt;math&amp;gt;P\in \mathbb{N}&amp;lt;/math&amp;gt;. Считается, что каждый процесс &#039;&#039;P&#039;&#039; обрабатывает не более чем &amp;lt;math&amp;gt;\left[\frac{2^{2n}}{P}\right]\geq 1&amp;lt;/math&amp;gt; элементов. Тогда качественная формула может быть записана таким образом: &amp;lt;math&amp;gt;T(n,P)=2\,(1+\left[ \frac{n}{4} \right])\,\frac{2^{2n}}{P}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Неравенство &amp;lt;math&amp;gt;\left[\frac{2^{2n}}{P}\right]\geq 1&amp;lt;/math&amp;gt; можно переписать, как &amp;lt;math&amp;gt;log_2\,\sqrt{P}\leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Легко увидеть, что минимум функции &#039;&#039;T(n,P)&#039;&#039; будет при максимально возможном &#039;&#039;P&#039;&#039; : &amp;lt;math&amp;gt;log_2\,\sqrt{P}\leq n&amp;lt;/math&amp;gt;. Такое &#039;&#039;P&#039;&#039; будет оптимальным числом процессов для алгоритма. В частности, для &amp;lt;math&amp;gt;P=2^p,\,p\in\mathbb{N}&amp;lt;/math&amp;gt; оптимальное &amp;lt;math&amp;gt;P = 2^{2n}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:&amp;lt;math&amp;gt;\frac{T(n)}{T(n,P)}=P&amp;lt;/math&amp;gt;.&lt;br /&gt;
То есть, отношение последовательной и параллельной сложности будет &#039;&#039;линейно&#039;&#039; зависеть от &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Вычислительная мощность&#039;&#039; алгоритма построения матрицы Адамара, как отношение числа операций к суммарному объему входных и выходных данных: &lt;br /&gt;
:&amp;lt;math&amp;gt;\,\frac{2^{2n}(2+[\frac{n}{4}])}{1+2^{2n}}\left( \sim [\frac{n}{4}],\,n\to+\infty \right)&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* Алгоритм построения матрицы Адамара является &#039;&#039;не детерминированным&#039;&#039;, так как число операций меняется в зависимости от входных данных (числа n, которое формирует матрицу размера 2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;times;&amp;amp;nbsp;2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
* Степень исхода вершины информационного графа равна 1;&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;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar(int** H, int n) // N = 2^n - размерность матрицы&lt;br /&gt;
{     &lt;br /&gt;
    int i,j,N;&lt;br /&gt;
    float h;&lt;br /&gt;
    h = pow(1/2,n/2); // h - нормализующий множитель&lt;br /&gt;
    N = pow(2,n);&lt;br /&gt;
&lt;br /&gt;
    for(i=0;i&amp;lt;N;++i) &lt;br /&gt;
    {&lt;br /&gt;
	for(j=0;j&amp;lt;N;++j)&lt;br /&gt;
	{&lt;br /&gt;
		ij = i &amp;amp; j;&lt;br /&gt;
    		for (l=0;ij;++l) ij&amp;amp;=ij-1; // l - количество единиц бинарного представления ij&lt;br /&gt;
		if(l%2==0) H[i][j] = h;&lt;br /&gt;
		else H[i][j] = -h;&lt;br /&gt;
	}&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;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar_recursion(int** H, int N, int i, int j, int h) // h - нормализующий множитель&lt;br /&gt;
{&lt;br /&gt;
    if(n==1) H[i][j] = h;&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        adamar(H, N/2, i, j, h);&lt;br /&gt;
        adamar(H, N/2, i, N/2+j, h);&lt;br /&gt;
        adamar(H, N/2, N/2+i, j, h);&lt;br /&gt;
        adamar(H, N/2, N/2+i, N/2+j, -h);&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;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar_not_recursion(int** H, int n) // N = 2^n - размерность матрицы&lt;br /&gt;
{     &lt;br /&gt;
    int i,j,N;&lt;br /&gt;
    float h;&lt;br /&gt;
    h = pow(1/2,n/2);&lt;br /&gt;
    N = pow(2,n);&lt;br /&gt;
    k=2;&lt;br /&gt;
    H[0][0] = h;&lt;br /&gt;
	&lt;br /&gt;
    while(k&amp;lt;=N)&lt;br /&gt;
    {&lt;br /&gt;
	for (i=0; i&amp;lt;k; ++i)&lt;br /&gt;
	{&lt;br /&gt;
		for (j=0; j&amp;lt;k; ++j)&lt;br /&gt;
		{&lt;br /&gt;
			if (i&amp;lt;k/2 &amp;amp;&amp;amp; j&amp;lt;k/2)&lt;br /&gt;
			{&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				if(i&amp;gt;=k/2 &amp;amp;&amp;amp; j&amp;gt;=k/2)&lt;br /&gt;
				{&lt;br /&gt;
					H[i][j] = -(H[i-k/2][j-k/2]);&lt;br /&gt;
				}&lt;br /&gt;
				else&lt;br /&gt;
				{&lt;br /&gt;
					if (i&amp;gt;j)&lt;br /&gt;
					{&lt;br /&gt;
						H[i][j] = H[i-k/2][j];&lt;br /&gt;
					}&lt;br /&gt;
					else&lt;br /&gt;
					{&lt;br /&gt;
						H[i][j] = H[i][j-k/2];&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
		&lt;br /&gt;
        k=k*2;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для данного случая, рекурсия является менее эффективной для генерации матрицы Адамара ([https://habrahabr.ru/post/256351/ Хабрахабр. О бедной рекурсии замолвите слово, или всё, что вы не знали и не хотите о ней знать.]). С точки зрения последовательной реализации, генерация матрицы Адамара с помощью adamar_not_recursion будет выигрывать у adamar, так как adamar_not_recursion будет выполнять меньшее количество операций. С точки зрения параллельной реализации adamar имеет 100% парализацию и при определенных условиях будет выигрывать по времени у распараллелинной adamar_not_recursion (пусть в adamar и будет выполняться большее количество операций, но они являются [https://ru.wikipedia.org/wiki/%D0%91%D0%B8%D1%82%D0%BE%D0%B2%D1%8B%D0%B5_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B8 битовыми операциями]).&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Blue Gene&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых  параметров запуска реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1, 2, 4, 8,..., 1024] ;&lt;br /&gt;
*	размер матрицы [2, 4, 8,..., 2048].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон эффективности реализации алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.0121%;&lt;br /&gt;
*	максимальная эффективность реализации 3.3003%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации построение матрицы Адамара в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:Prois1.jpg|thumb|center|700px|Рис.5 Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:Effec1.jpg|thumb|center|700px|Рис.5 Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Построим оценки масштабируемости выбранной реализации:&lt;br /&gt;
* При увеличении числа процессов производительность на рассмотренной области изменений параметров запуска увеличивается практически линейно. В следствии этого эффективность реализации, как видно по графику, перестает изменяться при увеличении числа процессоров и равна примерно 1,7%.&lt;br /&gt;
* При увеличении размера матрицы производительность на рассмотренной области изменений параметров запуска увеличивается логарифмически. Это связанно с тем, что количество операций зависит от количества единиц после бинарного произведения. Поэтому наиболее влияет порядок степени &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; размера матрицы &amp;lt;math&amp;gt;N=2^{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;
# [http://www.exponenta.ru/soft/matlab/potemkin/book2/chapter5/hadamard.asp MATLAB];&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/HadamardMatrix.html WOLFRAM];&lt;br /&gt;
# [http://pydoc.net/Python/rogues/0.3.0/rogues.matrices.hadamard/ Python];&lt;br /&gt;
# [http://www.obihiro.ac.jp/~suzukim/masuda/octave/html3/octave_97.html Octave].&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что во многих вычислительных пакетах встроена операция тензорного произведения матриц, которая позволяет строить матрицу Адамара по определению. Этот факт позволяет использовать матрицу Адамара в этих вычислительных пакетах: &lt;br /&gt;
# [https://ru.wikipedia.org/wiki/Maple MAPLE];&lt;br /&gt;
# [https://ru.wikipedia.org/wiki/Mathcad MATCATH].&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория:Статьи в работе]]&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BF%D0%BE%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D1%81%D1%82%D0%B5%D0%BF%D0%B5%D0%BD%D0%B8_2&amp;diff=22602</id>
		<title>Алгоритм поэлементного построения матрицы Адамара размерности степени 2</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BF%D0%BE%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D1%81%D1%82%D0%B5%D0%BF%D0%B5%D0%BD%D0%B8_2&amp;diff=22602"/>
		<updated>2017-05-03T20:47:53Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Литература */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[U:Бугаков Юрий|Ю.Бугаков]], Е. Кужамалиев, [[Участник:Chernyavskiy|А.Ю.Чернявский]] (редактирование), С.Н. Леоненков (предварительная проверка)&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O( \left[ \frac{n}{4}\right]\,2^{2n})&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(2^{2n})&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;2^{2n}&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;
Важную роль в алгебре и комбинаторике играют матрицы Адамара, которые впервые были введены в математический обиход в конце прошлого века одним из крупнейших французских математиков [https://ru.wikipedia.org/wiki/%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80,_%D0%96%D0%B0%D0%BA Жаком Адамаром (1865-1963)]. Их применение в науке и технике посвящены тысячи публикаций. Они предоставляют эффективные возможности для организации хранения, обработки и передачи информации.&lt;br /&gt;
&lt;br /&gt;
Квадратная матрица Н порядка &#039;&#039;m&#039;&#039; с элементами ±1 называется матрицей Адамара, если выполняется условие&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt; H_m\,H_m^T = m\,E_m &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нетрудно заметить, что различные строки матрицы Адамара попарно ортогональны &amp;lt;ref&amp;gt;Мак-Вильямс Ф.Дж., Слоэн Н.Дж.А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — 744 с.&amp;lt;/ref&amp;gt;. Также, можно увидеть из определения, что m четно и&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
H_{2m} =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
H_{m} &amp;amp;  H_{m}\\&lt;br /&gt;
H_{m} &amp;amp; -H_{m}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
С матрицами Адамара связан ряд нерешенных проблем, одна из которых состоит в следующем. Мы уже видели, что порядок &#039;&#039;m&#039;&#039; матрицы Адамара при &#039;&#039;m&#039;&#039; ≥ 3 может быть лишь четным. Более того, при &#039;&#039;m&#039;&#039; ≥ 4 порядок обязан делиться на 4. До сих пор остается открытым вопрос: для любого ли &#039;&#039;m&#039;&#039;, кратного 4, существует матрица Адамара порядка m? Неизвестно, в частности, существует ли матрица Адамара порядка 268 (это наименьший порядок, кратный 4, для которого матрица Адамара еще не построена).&lt;br /&gt;
&lt;br /&gt;
Часто матрицу Адамара нормализуют и рассматривают размерности степени 2 &amp;lt;ref&amp;gt;Кронберг, Ю.И. Ожигов, А.Ю. Чернявский — Алгебраический аппарат квантовой информатики 2&amp;lt;/ref&amp;gt;&amp;lt;ref name=&amp;quot;kunz&amp;quot;&amp;gt; Kunz H.O.. On the Equivalence Between One-Dimensional Discrete Walsh-Hadamard and Multidimensional Discrete Fourier Transforms. IEEE Transactions on Computers. 28 (3): 267–8. [https://en.wikipedia.org/wiki/Digital_object_identifier doi]:[http://ieeexplore.ieee.org/document/1675334/ 10.1109/TC.1979.1675334]&amp;lt;/ref&amp;gt;&amp;lt;ref name=&amp;quot;wiki&amp;quot;&amp;gt;Википедия – свободная энциклопедия [Электронный ресурс]. -  https://en.wikipedia.org/wiki/Hadamard_transform. - (дата обращения: 15.10.2016).&amp;lt;/ref&amp;gt;). В дальнейшем будем рассматривать только такие случаи. Переопределим матрицу Адамара следующим образом:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Матрица Адамара &#039;&#039;H&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sub&amp;gt;  - это матрица размера 2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;times;&amp;amp;nbsp;2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;, для которой справедливо равенство&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;H_n = H_{1} \otimes H_{n-1}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  H_1 = \frac{1}{\sqrt2}&lt;br /&gt;
   &amp;amp;\begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&#039;&#039;&#039;где &amp;lt;math&amp;gt; \otimes &amp;lt;/math&amp;gt; представляет собой [https://ru.wikipedia.org/wiki/%D0%A2%D0%B5%D0%BD%D0%B7%D0%BE%D1%80%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5 тензорное произведение].&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Представим некоторые частные примеры матриц Адамара:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_0 = +1,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_1 = \frac{1}{\sqrt2}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_2 = \frac{1}{2}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1&lt;br /&gt;
    \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_3 = \frac{1}{2^{\frac{3}{2}}}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rrrrrrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1 &amp;amp; 1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    \end{array}\end{pmatrix}&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;H_n&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;2^n\times 2^n&amp;lt;/math&amp;gt; можно вычислить поэлементно&amp;lt;ref name=&amp;quot;kunz&amp;quot;/&amp;gt;&amp;lt;ref name=&amp;quot;wiki&amp;quot;/&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{k,l} = \frac{1}{2^\frac{n}{2}} (-1)^{\sum_j k_j l_j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
где &#039;&#039;k&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;j&#039;&#039;&amp;lt;/sub&amp;gt; и &#039;&#039;l&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;j&#039;&#039;&amp;lt;/sub&amp;gt; коэффициенты двоичного разложения чисел &#039;&#039;k&#039;&#039; и &#039;&#039;l&#039;&#039; (1 или 0):&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;k = \sum^{n}_{i=0} {k_i 2^i} = k_{n} 2^{n} + k_{n-1} 2^{n-1} + \cdots + k_1 2 + k_0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и&lt;br /&gt;
: &amp;lt;math&amp;gt;l = \sum^{n}_{i=0} {l_i 2^i} = l_{n} 2^{n} + l_{n-1} 2^{n-1} + \cdots + l_1 2 + l_0&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;h_{k,l} = \frac{1}{2^\frac{n}{2}} (-1)^{\sum_j k_j l_j}&amp;lt;/math&amp;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;\sum_{j=0}^n k_j l_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Как видно по формуле, получаемое значение равна количеству единиц в двоичной записи результата побитового умножения &#039;&#039;k&#039;&#039; и &#039;&#039;l&#039;&#039;. Существует эффективный метод вычисления количества единиц , сложность которого равна &#039;&#039;m&#039;&#039; операций вычитания и &#039;&#039;m&#039;&#039; операций побитового умножения, где &#039;&#039;m&#039;&#039;-искомое количество единиц.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. Побитовое умножение &amp;lt;math&amp;gt;k\&amp;amp;l&amp;lt;/math&amp;gt;;  &lt;br /&gt;
&lt;br /&gt;
2. Вычисление количества единиц двоичной записи;&lt;br /&gt;
&lt;br /&gt;
3. Определение знака элемента по степени.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения матрицы Адамара порядка &amp;lt;math&amp;gt;N=2^n&amp;lt;/math&amp;gt; в первом шаге потребуется &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt; побитовых умножений &#039;&#039;k&amp;amp;l&#039;&#039;.&lt;br /&gt;
Во втором шаге, как говорилось выше, сложность метода вычисления количества единиц  числа в двоичном представлении равна удвоенному количеству единиц. В наихудшем случае сложность равна &amp;lt;math&amp;gt;2log_2N&amp;lt;/math&amp;gt;, при &#039;&#039;k=l=N-1&#039;&#039;, а в наилучшем 0. Для нахождения  степени всех элементов матрицы потребуются &amp;lt;math&amp;gt; 2N^2\left[\frac{log_2N}{4}\right]&amp;lt;/math&amp;gt; операций. В третьем шаге для определения знака потребуется &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt; операций, то есть сложность алгоритма &amp;lt;math&amp;gt; T(n) = 2\,(1+\left[\frac{n}{4}\right])\,2^{2n}. &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
На рисунке ниже изображен информационный граф &amp;lt;ref&amp;gt;Воеводин В.В.. Воеводин Вл.В. Параллельные вычисления. - СПб.: БХВ-Петербург, 2002. - 608 с.&amp;lt;/ref&amp;gt; алгоритма.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;k\&amp;amp;l&amp;lt;/math&amp;gt; - операция побитового умножения, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; соответствующие координаты элемента &amp;lt;math&amp;gt;h_{kl}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* OP - вычисление количества единиц числа в двоичной системе. Состоит из последовательного применения операций вычитания и побитового умножения;&lt;br /&gt;
* SGN - определение знака соответствующего элемента. Если результат предыдущего шага четное, то знак положительный, иначе отрицательный.  &lt;br /&gt;
&lt;br /&gt;
[[file:Hadamar.png|thumb|center|1400px|Рисунок 1. Граф алгоритма.]]&lt;br /&gt;
[[file:OP3.png|thumb|center|1400px|Рисунок 2. Граф OP.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения матрицы порядка &amp;lt;math&amp;gt;N=2^n&amp;lt;/math&amp;gt; требуется последовательно выполнить следующие шаги:&lt;br /&gt;
* &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt;  вычислений побитового умножения,&lt;br /&gt;
* для каждого элемента от &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций вычитания и побитового умножения, в зависимости от результата предыдущего шага,&lt;br /&gt;
* &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt;  для определения знака значения элемента.&lt;br /&gt;
 &lt;br /&gt;
Таким образом для построения необходимы лишь простые операции вычитания и побитового умножения выполняемые с целыми положительными числами. Стоит заметить что вычисления для каждого элемента не зависят друг от друга. Также можно воспользоваться либо симметричностью матрицы Адамара либо закономерностью областей показанная в пункте 1.1.&lt;br /&gt;
Таким образом, основной вклад в высотe ЯПФ вносит операция вычисления количества единиц. Ширина ЯПФ будет равна &amp;lt;math&amp;gt;O(2^{2n})&amp;lt;/math&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; n \in \N &amp;lt;/math&amp;gt; - размерность матрицы Адамара &amp;lt;math&amp;gt;H_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: 1 (натуральное число &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;H_n&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;2^n\times 2^n&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2^{2n}&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;
Одним из трудных мест параллельной реализации является правильный выбор количества процессов. Рассматривается некоторое фиксированное число процессов &amp;lt;math&amp;gt;P\in \mathbb{N}&amp;lt;/math&amp;gt;. Считается, что каждый процесс &#039;&#039;P&#039;&#039; обрабатывает не более чем &amp;lt;math&amp;gt;\left[\frac{2^{2n}}{P}\right]\geq 1&amp;lt;/math&amp;gt; элементов. Тогда качественная формула может быть записана таким образом: &amp;lt;math&amp;gt;T(n,P)=2\,(1+\left[ \frac{n}{4} \right])\,\frac{2^{2n}}{P}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Неравенство &amp;lt;math&amp;gt;\left[\frac{2^{2n}}{P}\right]\geq 1&amp;lt;/math&amp;gt; можно переписать, как &amp;lt;math&amp;gt;log_2\,\sqrt{P}\leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Легко увидеть, что минимум функции &#039;&#039;T(n,P)&#039;&#039; будет при максимально возможном &#039;&#039;P&#039;&#039; : &amp;lt;math&amp;gt;log_2\,\sqrt{P}\leq n&amp;lt;/math&amp;gt;. Такое &#039;&#039;P&#039;&#039; будет оптимальным числом процессов для алгоритма. В частности, для &amp;lt;math&amp;gt;P=2^p,\,p\in\mathbb{N}&amp;lt;/math&amp;gt; оптимальное &amp;lt;math&amp;gt;P = 2^{2n}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:&amp;lt;math&amp;gt;\frac{T(n)}{T(n,P)}=P&amp;lt;/math&amp;gt;.&lt;br /&gt;
То есть, отношение последовательной и параллельной сложности будет &#039;&#039;линейно&#039;&#039; зависеть от &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Вычислительная мощность&#039;&#039; алгоритма построения матрицы Адамара, как отношение числа операций к суммарному объему входных и выходных данных: &lt;br /&gt;
:&amp;lt;math&amp;gt;\,\frac{2^{2n}(2+[\frac{n}{4}])}{1+2^{2n}}\left( \sim [\frac{n}{4}],\,n\to+\infty \right)&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* Алгоритм построения матрицы Адамара является &#039;&#039;не детерминированным&#039;&#039;, так как число операций меняется в зависимости от входных данных (числа n, которое формирует матрицу размера 2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;times;&amp;amp;nbsp;2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
* Степень исхода вершины информационного графа равна 1;&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;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar(int** H, int n) // N = 2^n - размерность матрицы&lt;br /&gt;
{     &lt;br /&gt;
    int i,j,N;&lt;br /&gt;
    float h;&lt;br /&gt;
    h = pow(1/2,n/2); // h - нормализующий множитель&lt;br /&gt;
    N = pow(2,n);&lt;br /&gt;
&lt;br /&gt;
    for(i=0;i&amp;lt;N;++i) &lt;br /&gt;
    {&lt;br /&gt;
	for(j=0;j&amp;lt;N;++j)&lt;br /&gt;
	{&lt;br /&gt;
		ij = i &amp;amp; j;&lt;br /&gt;
    		for (l=0;ij;++l) ij&amp;amp;=ij-1; // l - количество единиц бинарного представления ij&lt;br /&gt;
		if(l%2==0) H[i][j] = h;&lt;br /&gt;
		else H[i][j] = -h;&lt;br /&gt;
	}&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;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar_recursion(int** H, int N, int i, int j, int h) // h - нормализующий множитель&lt;br /&gt;
{&lt;br /&gt;
    if(n==1) H[i][j] = h;&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        adamar(H, N/2, i, j, h);&lt;br /&gt;
        adamar(H, N/2, i, N/2+j, h);&lt;br /&gt;
        adamar(H, N/2, N/2+i, j, h);&lt;br /&gt;
        adamar(H, N/2, N/2+i, N/2+j, -h);&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;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar_not_recursion(int** H, int n) // N = 2^n - размерность матрицы&lt;br /&gt;
{     &lt;br /&gt;
    int i,j,N;&lt;br /&gt;
    float h;&lt;br /&gt;
    h = pow(1/2,n/2);&lt;br /&gt;
    N = pow(2,n);&lt;br /&gt;
    k=2;&lt;br /&gt;
    H[0][0] = h;&lt;br /&gt;
	&lt;br /&gt;
    while(k&amp;lt;=N)&lt;br /&gt;
    {&lt;br /&gt;
	for (i=0; i&amp;lt;k; ++i)&lt;br /&gt;
	{&lt;br /&gt;
		for (j=0; j&amp;lt;k; ++j)&lt;br /&gt;
		{&lt;br /&gt;
			if (i&amp;lt;k/2 &amp;amp;&amp;amp; j&amp;lt;k/2)&lt;br /&gt;
			{&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				if(i&amp;gt;=k/2 &amp;amp;&amp;amp; j&amp;gt;=k/2)&lt;br /&gt;
				{&lt;br /&gt;
					H[i][j] = -(H[i-k/2][j-k/2]);&lt;br /&gt;
				}&lt;br /&gt;
				else&lt;br /&gt;
				{&lt;br /&gt;
					if (i&amp;gt;j)&lt;br /&gt;
					{&lt;br /&gt;
						H[i][j] = H[i-k/2][j];&lt;br /&gt;
					}&lt;br /&gt;
					else&lt;br /&gt;
					{&lt;br /&gt;
						H[i][j] = H[i][j-k/2];&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
		&lt;br /&gt;
        k=k*2;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для данного случая, рекурсия является менее эффективной для генерации матрицы Адамара ([https://habrahabr.ru/post/256351/ Хабрахабр. О бедной рекурсии замолвите слово, или всё, что вы не знали и не хотите о ней знать.]). С точки зрения последовательной реализации, генерация матрицы Адамара с помощью adamar_not_recursion будет выигрывать у adamar, так как adamar_not_recursion будет выполнять меньшее количество операций. С точки зрения параллельной реализации adamar имеет 100% парализацию и при определенных условиях будет выигрывать по времени у распараллелинной adamar_not_recursion (пусть в adamar и будет выполняться большее количество операций, но они являются [https://ru.wikipedia.org/wiki/%D0%91%D0%B8%D1%82%D0%BE%D0%B2%D1%8B%D0%B5_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B8 битовыми операциями]).&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Blue Gene&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых  параметров запуска реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1, 2, 4, 8,..., 1024] ;&lt;br /&gt;
*	размер матрицы [2, 4, 8,..., 2048].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон эффективности реализации алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.0121%;&lt;br /&gt;
*	максимальная эффективность реализации 3.3003%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации построение матрицы Адамара в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:Prois1.jpg|thumb|center|700px|Рис.5 Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:Effec1.jpg|thumb|center|700px|Рис.5 Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Построим оценки масштабируемости выбранной реализации:&lt;br /&gt;
* При увеличении числа процессов производительность на рассмотренной области изменений параметров запуска увеличивается практически линейно. В следствии этого эффективность реализации, как видно по графику, перестает изменяться при увеличении числа процессоров и равна примерно 1,7%.&lt;br /&gt;
* При увеличении размера матрицы производительность на рассмотренной области изменений параметров запуска увеличивается логарифмически. Это связанно с тем, что количество операций зависит от количества единиц после бинарного произведения. Поэтому наиболее влияет порядок степени &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; размера матрицы &amp;lt;math&amp;gt;N=2^{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;
# [http://www.exponenta.ru/soft/matlab/potemkin/book2/chapter5/hadamard.asp MATLAB];&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/HadamardMatrix.html WOLFRAM];&lt;br /&gt;
# [http://pydoc.net/Python/rogues/0.3.0/rogues.matrices.hadamard/ Python];&lt;br /&gt;
# [http://www.obihiro.ac.jp/~suzukim/masuda/octave/html3/octave_97.html Octave].&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что во многих вычислительных пакетах встроена операция тензорного произведения матриц, которая позволяет строить матрицу Адамара по определению. Этот факт позволяет использовать матрицу Адамара в этих вычислительных пакетах: &lt;br /&gt;
# [https://ru.wikipedia.org/wiki/Maple MAPLE];&lt;br /&gt;
# [https://ru.wikipedia.org/wiki/Mathcad MATCATH].&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BF%D0%BE%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D1%81%D1%82%D0%B5%D0%BF%D0%B5%D0%BD%D0%B8_2&amp;diff=22601</id>
		<title>Алгоритм поэлементного построения матрицы Адамара размерности степени 2</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BF%D0%BE%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D1%81%D1%82%D0%B5%D0%BF%D0%B5%D0%BD%D0%B8_2&amp;diff=22601"/>
		<updated>2017-05-03T20:47:32Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[U:Бугаков Юрий|Ю.Бугаков]], Е. Кужамалиев, [[Участник:Chernyavskiy|А.Ю.Чернявский]] (редактирование), С.Н. Леоненков (предварительная проверка)&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O( \left[ \frac{n}{4}\right]\,2^{2n})&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(2^{2n})&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;2^{2n}&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;
Важную роль в алгебре и комбинаторике играют матрицы Адамара, которые впервые были введены в математический обиход в конце прошлого века одним из крупнейших французских математиков [https://ru.wikipedia.org/wiki/%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80,_%D0%96%D0%B0%D0%BA Жаком Адамаром (1865-1963)]. Их применение в науке и технике посвящены тысячи публикаций. Они предоставляют эффективные возможности для организации хранения, обработки и передачи информации.&lt;br /&gt;
&lt;br /&gt;
Квадратная матрица Н порядка &#039;&#039;m&#039;&#039; с элементами ±1 называется матрицей Адамара, если выполняется условие&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt; H_m\,H_m^T = m\,E_m &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нетрудно заметить, что различные строки матрицы Адамара попарно ортогональны &amp;lt;ref&amp;gt;Мак-Вильямс Ф.Дж., Слоэн Н.Дж.А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — 744 с.&amp;lt;/ref&amp;gt;. Также, можно увидеть из определения, что m четно и&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
H_{2m} =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
H_{m} &amp;amp;  H_{m}\\&lt;br /&gt;
H_{m} &amp;amp; -H_{m}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
С матрицами Адамара связан ряд нерешенных проблем, одна из которых состоит в следующем. Мы уже видели, что порядок &#039;&#039;m&#039;&#039; матрицы Адамара при &#039;&#039;m&#039;&#039; ≥ 3 может быть лишь четным. Более того, при &#039;&#039;m&#039;&#039; ≥ 4 порядок обязан делиться на 4. До сих пор остается открытым вопрос: для любого ли &#039;&#039;m&#039;&#039;, кратного 4, существует матрица Адамара порядка m? Неизвестно, в частности, существует ли матрица Адамара порядка 268 (это наименьший порядок, кратный 4, для которого матрица Адамара еще не построена).&lt;br /&gt;
&lt;br /&gt;
Часто матрицу Адамара нормализуют и рассматривают размерности степени 2 &amp;lt;ref&amp;gt;Кронберг, Ю.И. Ожигов, А.Ю. Чернявский — Алгебраический аппарат квантовой информатики 2&amp;lt;/ref&amp;gt;&amp;lt;ref name=&amp;quot;kunz&amp;quot;&amp;gt; Kunz H.O.. On the Equivalence Between One-Dimensional Discrete Walsh-Hadamard and Multidimensional Discrete Fourier Transforms. IEEE Transactions on Computers. 28 (3): 267–8. [https://en.wikipedia.org/wiki/Digital_object_identifier doi]:[http://ieeexplore.ieee.org/document/1675334/ 10.1109/TC.1979.1675334]&amp;lt;/ref&amp;gt;&amp;lt;ref name=&amp;quot;wiki&amp;quot;&amp;gt;Википедия – свободная энциклопедия [Электронный ресурс]. -  https://en.wikipedia.org/wiki/Hadamard_transform. - (дата обращения: 15.10.2016).&amp;lt;/ref&amp;gt;). В дальнейшем будем рассматривать только такие случаи. Переопределим матрицу Адамара следующим образом:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Матрица Адамара &#039;&#039;H&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sub&amp;gt;  - это матрица размера 2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;times;&amp;amp;nbsp;2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;, для которой справедливо равенство&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;H_n = H_{1} \otimes H_{n-1}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  H_1 = \frac{1}{\sqrt2}&lt;br /&gt;
   &amp;amp;\begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&#039;&#039;&#039;где &amp;lt;math&amp;gt; \otimes &amp;lt;/math&amp;gt; представляет собой [https://ru.wikipedia.org/wiki/%D0%A2%D0%B5%D0%BD%D0%B7%D0%BE%D1%80%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5 тензорное произведение].&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Представим некоторые частные примеры матриц Адамара:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_0 = +1,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_1 = \frac{1}{\sqrt2}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_2 = \frac{1}{2}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1&lt;br /&gt;
    \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_3 = \frac{1}{2^{\frac{3}{2}}}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rrrrrrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1 &amp;amp; 1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    \end{array}\end{pmatrix}&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;H_n&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;2^n\times 2^n&amp;lt;/math&amp;gt; можно вычислить поэлементно&amp;lt;ref name=&amp;quot;kunz&amp;quot;/&amp;gt;&amp;lt;ref name=&amp;quot;wiki&amp;quot;/&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{k,l} = \frac{1}{2^\frac{n}{2}} (-1)^{\sum_j k_j l_j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
где &#039;&#039;k&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;j&#039;&#039;&amp;lt;/sub&amp;gt; и &#039;&#039;l&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;j&#039;&#039;&amp;lt;/sub&amp;gt; коэффициенты двоичного разложения чисел &#039;&#039;k&#039;&#039; и &#039;&#039;l&#039;&#039; (1 или 0):&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;k = \sum^{n}_{i=0} {k_i 2^i} = k_{n} 2^{n} + k_{n-1} 2^{n-1} + \cdots + k_1 2 + k_0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и&lt;br /&gt;
: &amp;lt;math&amp;gt;l = \sum^{n}_{i=0} {l_i 2^i} = l_{n} 2^{n} + l_{n-1} 2^{n-1} + \cdots + l_1 2 + l_0&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;h_{k,l} = \frac{1}{2^\frac{n}{2}} (-1)^{\sum_j k_j l_j}&amp;lt;/math&amp;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;\sum_{j=0}^n k_j l_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Как видно по формуле, получаемое значение равна количеству единиц в двоичной записи результата побитового умножения &#039;&#039;k&#039;&#039; и &#039;&#039;l&#039;&#039;. Существует эффективный метод вычисления количества единиц , сложность которого равна &#039;&#039;m&#039;&#039; операций вычитания и &#039;&#039;m&#039;&#039; операций побитового умножения, где &#039;&#039;m&#039;&#039;-искомое количество единиц.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. Побитовое умножение &amp;lt;math&amp;gt;k\&amp;amp;l&amp;lt;/math&amp;gt;;  &lt;br /&gt;
&lt;br /&gt;
2. Вычисление количества единиц двоичной записи;&lt;br /&gt;
&lt;br /&gt;
3. Определение знака элемента по степени.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения матрицы Адамара порядка &amp;lt;math&amp;gt;N=2^n&amp;lt;/math&amp;gt; в первом шаге потребуется &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt; побитовых умножений &#039;&#039;k&amp;amp;l&#039;&#039;.&lt;br /&gt;
Во втором шаге, как говорилось выше, сложность метода вычисления количества единиц  числа в двоичном представлении равна удвоенному количеству единиц. В наихудшем случае сложность равна &amp;lt;math&amp;gt;2log_2N&amp;lt;/math&amp;gt;, при &#039;&#039;k=l=N-1&#039;&#039;, а в наилучшем 0. Для нахождения  степени всех элементов матрицы потребуются &amp;lt;math&amp;gt; 2N^2\left[\frac{log_2N}{4}\right]&amp;lt;/math&amp;gt; операций. В третьем шаге для определения знака потребуется &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt; операций, то есть сложность алгоритма &amp;lt;math&amp;gt; T(n) = 2\,(1+\left[\frac{n}{4}\right])\,2^{2n}. &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
На рисунке ниже изображен информационный граф &amp;lt;ref&amp;gt;Воеводин В.В.. Воеводин Вл.В. Параллельные вычисления. - СПб.: БХВ-Петербург, 2002. - 608 с.&amp;lt;/ref&amp;gt; алгоритма.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;k\&amp;amp;l&amp;lt;/math&amp;gt; - операция побитового умножения, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; соответствующие координаты элемента &amp;lt;math&amp;gt;h_{kl}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* OP - вычисление количества единиц числа в двоичной системе. Состоит из последовательного применения операций вычитания и побитового умножения;&lt;br /&gt;
* SGN - определение знака соответствующего элемента. Если результат предыдущего шага четное, то знак положительный, иначе отрицательный.  &lt;br /&gt;
&lt;br /&gt;
[[file:Hadamar.png|thumb|center|1400px|Рисунок 1. Граф алгоритма.]]&lt;br /&gt;
[[file:OP3.png|thumb|center|1400px|Рисунок 2. Граф OP.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения матрицы порядка &amp;lt;math&amp;gt;N=2^n&amp;lt;/math&amp;gt; требуется последовательно выполнить следующие шаги:&lt;br /&gt;
* &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt;  вычислений побитового умножения,&lt;br /&gt;
* для каждого элемента от &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций вычитания и побитового умножения, в зависимости от результата предыдущего шага,&lt;br /&gt;
* &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt;  для определения знака значения элемента.&lt;br /&gt;
 &lt;br /&gt;
Таким образом для построения необходимы лишь простые операции вычитания и побитового умножения выполняемые с целыми положительными числами. Стоит заметить что вычисления для каждого элемента не зависят друг от друга. Также можно воспользоваться либо симметричностью матрицы Адамара либо закономерностью областей показанная в пункте 1.1.&lt;br /&gt;
Таким образом, основной вклад в высотe ЯПФ вносит операция вычисления количества единиц. Ширина ЯПФ будет равна &amp;lt;math&amp;gt;O(2^{2n})&amp;lt;/math&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; n \in \N &amp;lt;/math&amp;gt; - размерность матрицы Адамара &amp;lt;math&amp;gt;H_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: 1 (натуральное число &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;H_n&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;2^n\times 2^n&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2^{2n}&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;
Одним из трудных мест параллельной реализации является правильный выбор количества процессов. Рассматривается некоторое фиксированное число процессов &amp;lt;math&amp;gt;P\in \mathbb{N}&amp;lt;/math&amp;gt;. Считается, что каждый процесс &#039;&#039;P&#039;&#039; обрабатывает не более чем &amp;lt;math&amp;gt;\left[\frac{2^{2n}}{P}\right]\geq 1&amp;lt;/math&amp;gt; элементов. Тогда качественная формула может быть записана таким образом: &amp;lt;math&amp;gt;T(n,P)=2\,(1+\left[ \frac{n}{4} \right])\,\frac{2^{2n}}{P}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Неравенство &amp;lt;math&amp;gt;\left[\frac{2^{2n}}{P}\right]\geq 1&amp;lt;/math&amp;gt; можно переписать, как &amp;lt;math&amp;gt;log_2\,\sqrt{P}\leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Легко увидеть, что минимум функции &#039;&#039;T(n,P)&#039;&#039; будет при максимально возможном &#039;&#039;P&#039;&#039; : &amp;lt;math&amp;gt;log_2\,\sqrt{P}\leq n&amp;lt;/math&amp;gt;. Такое &#039;&#039;P&#039;&#039; будет оптимальным числом процессов для алгоритма. В частности, для &amp;lt;math&amp;gt;P=2^p,\,p\in\mathbb{N}&amp;lt;/math&amp;gt; оптимальное &amp;lt;math&amp;gt;P = 2^{2n}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:&amp;lt;math&amp;gt;\frac{T(n)}{T(n,P)}=P&amp;lt;/math&amp;gt;.&lt;br /&gt;
То есть, отношение последовательной и параллельной сложности будет &#039;&#039;линейно&#039;&#039; зависеть от &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Вычислительная мощность&#039;&#039; алгоритма построения матрицы Адамара, как отношение числа операций к суммарному объему входных и выходных данных: &lt;br /&gt;
:&amp;lt;math&amp;gt;\,\frac{2^{2n}(2+[\frac{n}{4}])}{1+2^{2n}}\left( \sim [\frac{n}{4}],\,n\to+\infty \right)&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* Алгоритм построения матрицы Адамара является &#039;&#039;не детерминированным&#039;&#039;, так как число операций меняется в зависимости от входных данных (числа n, которое формирует матрицу размера 2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;times;&amp;amp;nbsp;2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
* Степень исхода вершины информационного графа равна 1;&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;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar(int** H, int n) // N = 2^n - размерность матрицы&lt;br /&gt;
{     &lt;br /&gt;
    int i,j,N;&lt;br /&gt;
    float h;&lt;br /&gt;
    h = pow(1/2,n/2); // h - нормализующий множитель&lt;br /&gt;
    N = pow(2,n);&lt;br /&gt;
&lt;br /&gt;
    for(i=0;i&amp;lt;N;++i) &lt;br /&gt;
    {&lt;br /&gt;
	for(j=0;j&amp;lt;N;++j)&lt;br /&gt;
	{&lt;br /&gt;
		ij = i &amp;amp; j;&lt;br /&gt;
    		for (l=0;ij;++l) ij&amp;amp;=ij-1; // l - количество единиц бинарного представления ij&lt;br /&gt;
		if(l%2==0) H[i][j] = h;&lt;br /&gt;
		else H[i][j] = -h;&lt;br /&gt;
	}&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;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar_recursion(int** H, int N, int i, int j, int h) // h - нормализующий множитель&lt;br /&gt;
{&lt;br /&gt;
    if(n==1) H[i][j] = h;&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        adamar(H, N/2, i, j, h);&lt;br /&gt;
        adamar(H, N/2, i, N/2+j, h);&lt;br /&gt;
        adamar(H, N/2, N/2+i, j, h);&lt;br /&gt;
        adamar(H, N/2, N/2+i, N/2+j, -h);&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;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar_not_recursion(int** H, int n) // N = 2^n - размерность матрицы&lt;br /&gt;
{     &lt;br /&gt;
    int i,j,N;&lt;br /&gt;
    float h;&lt;br /&gt;
    h = pow(1/2,n/2);&lt;br /&gt;
    N = pow(2,n);&lt;br /&gt;
    k=2;&lt;br /&gt;
    H[0][0] = h;&lt;br /&gt;
	&lt;br /&gt;
    while(k&amp;lt;=N)&lt;br /&gt;
    {&lt;br /&gt;
	for (i=0; i&amp;lt;k; ++i)&lt;br /&gt;
	{&lt;br /&gt;
		for (j=0; j&amp;lt;k; ++j)&lt;br /&gt;
		{&lt;br /&gt;
			if (i&amp;lt;k/2 &amp;amp;&amp;amp; j&amp;lt;k/2)&lt;br /&gt;
			{&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				if(i&amp;gt;=k/2 &amp;amp;&amp;amp; j&amp;gt;=k/2)&lt;br /&gt;
				{&lt;br /&gt;
					H[i][j] = -(H[i-k/2][j-k/2]);&lt;br /&gt;
				}&lt;br /&gt;
				else&lt;br /&gt;
				{&lt;br /&gt;
					if (i&amp;gt;j)&lt;br /&gt;
					{&lt;br /&gt;
						H[i][j] = H[i-k/2][j];&lt;br /&gt;
					}&lt;br /&gt;
					else&lt;br /&gt;
					{&lt;br /&gt;
						H[i][j] = H[i][j-k/2];&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
		&lt;br /&gt;
        k=k*2;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для данного случая, рекурсия является менее эффективной для генерации матрицы Адамара ([https://habrahabr.ru/post/256351/ Хабрахабр. О бедной рекурсии замолвите слово, или всё, что вы не знали и не хотите о ней знать.]). С точки зрения последовательной реализации, генерация матрицы Адамара с помощью adamar_not_recursion будет выигрывать у adamar, так как adamar_not_recursion будет выполнять меньшее количество операций. С точки зрения параллельной реализации adamar имеет 100% парализацию и при определенных условиях будет выигрывать по времени у распараллелинной adamar_not_recursion (пусть в adamar и будет выполняться большее количество операций, но они являются [https://ru.wikipedia.org/wiki/%D0%91%D0%B8%D1%82%D0%BE%D0%B2%D1%8B%D0%B5_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B8 битовыми операциями]).&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Blue Gene&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых  параметров запуска реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1, 2, 4, 8,..., 1024] ;&lt;br /&gt;
*	размер матрицы [2, 4, 8,..., 2048].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон эффективности реализации алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.0121%;&lt;br /&gt;
*	максимальная эффективность реализации 3.3003%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации построение матрицы Адамара в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:Prois1.jpg|thumb|center|700px|Рис.5 Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:Effec1.jpg|thumb|center|700px|Рис.5 Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Построим оценки масштабируемости выбранной реализации:&lt;br /&gt;
* При увеличении числа процессов производительность на рассмотренной области изменений параметров запуска увеличивается практически линейно. В следствии этого эффективность реализации, как видно по графику, перестает изменяться при увеличении числа процессоров и равна примерно 1,7%.&lt;br /&gt;
* При увеличении размера матрицы производительность на рассмотренной области изменений параметров запуска увеличивается логарифмически. Это связанно с тем, что количество операций зависит от количества единиц после бинарного произведения. Поэтому наиболее влияет порядок степени &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; размера матрицы &amp;lt;math&amp;gt;N=2^{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;
# [http://www.exponenta.ru/soft/matlab/potemkin/book2/chapter5/hadamard.asp MATLAB];&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/HadamardMatrix.html WOLFRAM];&lt;br /&gt;
# [http://pydoc.net/Python/rogues/0.3.0/rogues.matrices.hadamard/ Python];&lt;br /&gt;
# [http://www.obihiro.ac.jp/~suzukim/masuda/octave/html3/octave_97.html Octave].&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что во многих вычислительных пакетах встроена операция тензорного произведения матриц, которая позволяет строить матрицу Адамара по определению. Этот факт позволяет использовать матрицу Адамара в этих вычислительных пакетах: &lt;br /&gt;
# [https://ru.wikipedia.org/wiki/Maple MAPLE];&lt;br /&gt;
# [https://ru.wikipedia.org/wiki/Mathcad MATCATH].&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Мак-Вильямс Ф.Дж., Слоэн Н.Дж.А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — 744 с.&lt;br /&gt;
&lt;br /&gt;
[2] Кронберг, Ю.И. Ожигов, А.Ю. Чернявский — Алгебраический аппарат квантовой информатики 2&lt;br /&gt;
&lt;br /&gt;
[3] Kunz H.O.. On the Equivalence Between One-Dimensional Discrete Walsh-Hadamard and Multidimensional Discrete Fourier Transforms. IEEE Transactions on Computers. 28 (3): 267–8. [https://en.wikipedia.org/wiki/Digital_object_identifier doi]:[http://ieeexplore.ieee.org/document/1675334/ 10.1109/TC.1979.1675334]&lt;br /&gt;
&lt;br /&gt;
[4] Википедия – свободная энциклопедия [Электронный ресурс]. -  https://en.wikipedia.org/wiki/Hadamard_transform. - (дата обращения: 15.10.2016).&lt;br /&gt;
&lt;br /&gt;
[5] Воеводин В.В.. Воеводин Вл.В. Параллельные вычисления. - СПб.: БХВ-Петербург, 2002. - 608 с.&lt;br /&gt;
&lt;br /&gt;
[6] Воронцов К.В.. Математические методы обучения по прецедентам (теория обучения машин)&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BF%D0%BE%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D1%81%D1%82%D0%B5%D0%BF%D0%B5%D0%BD%D0%B8_2&amp;diff=22600</id>
		<title>Алгоритм поэлементного построения матрицы Адамара размерности степени 2</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BF%D0%BE%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0_%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D1%81%D1%82%D0%B5%D0%BF%D0%B5%D0%BD%D0%B8_2&amp;diff=22600"/>
		<updated>2017-05-03T20:45:10Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: Новая страница: «Основные авторы описания: Ю.Бугаков, Е. Кужамалиев, Участник:Chernyavskiy|А.Ю.…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[U:Бугаков Юрий|Ю.Бугаков]], Е. Кужамалиев, [[Участник:Chernyavskiy|А.Ю.Чернявский]] (редактирование), С.Н. Леоненков (предварительная проверка)&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O( \left[ \frac{n}{4}\right]\,2^{2n})&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(2^{2n})&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;2^{2n}&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;
Важную роль в алгебре и комбинаторике играют матрицы Адамара, которые впервые были введены в математический обиход в конце прошлого века одним из крупнейших французских математиков [https://ru.wikipedia.org/wiki/%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80,_%D0%96%D0%B0%D0%BA Жаком Адамаром (1865-1963)]. Их применение в науке и технике посвящены тысячи публикаций. Они предоставляют эффективные возможности для организации хранения, обработки и передачи информации.&lt;br /&gt;
&lt;br /&gt;
Квадратная матрица Н порядка &#039;&#039;m&#039;&#039; с элементами ±1 называется матрицей Адамара, если выполняется условие&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt; H_m\,H_m^T = m\,E_m &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Нетрудно заметить, что различные строки матрицы Адамара попарно ортогональны &amp;lt;ref&amp;gt;Мак-Вильямс Ф.Дж., Слоэн Н.Дж.А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — 744 с.&amp;lt;/ref&amp;gt;. Также, можно увидеть из определения, что m четно и&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
H_{2m} =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
H_{m} &amp;amp;  H_{m}\\&lt;br /&gt;
H_{m} &amp;amp; -H_{m}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
С матрицами Адамара связан ряд нерешенных проблем, одна из которых состоит в следующем. Мы уже видели, что порядок &#039;&#039;m&#039;&#039; матрицы Адамара при &#039;&#039;m&#039;&#039; ≥ 3 может быть лишь четным. Более того, при &#039;&#039;m&#039;&#039; ≥ 4 порядок обязан делиться на 4. До сих пор остается открытым вопрос: для любого ли &#039;&#039;m&#039;&#039;, кратного 4, существует матрица Адамара порядка m? Неизвестно, в частности, существует ли матрица Адамара порядка 268 (это наименьший порядок, кратный 4, для которого матрица Адамара еще не построена).&lt;br /&gt;
&lt;br /&gt;
Часто матрицу Адамара нормализуют и рассматривают размерности степени 2 &amp;lt;ref&amp;gt;Кронберг, Ю.И. Ожигов, А.Ю. Чернявский — Алгебраический аппарат квантовой информатики 2&amp;lt;/ref&amp;gt;&amp;lt;ref name=&amp;quot;kunz&amp;quot;&amp;gt; Kunz H.O.. On the Equivalence Between One-Dimensional Discrete Walsh-Hadamard and Multidimensional Discrete Fourier Transforms. IEEE Transactions on Computers. 28 (3): 267–8. [https://en.wikipedia.org/wiki/Digital_object_identifier doi]:[http://ieeexplore.ieee.org/document/1675334/ 10.1109/TC.1979.1675334]&amp;lt;/ref&amp;gt;&amp;lt;ref name=&amp;quot;wiki&amp;quot;&amp;gt;Википедия – свободная энциклопедия [Электронный ресурс]. -  https://en.wikipedia.org/wiki/Hadamard_transform. - (дата обращения: 15.10.2016).&amp;lt;/ref&amp;gt;). В дальнейшем будем рассматривать только такие случаи. Переопределим матрицу Адамара следующим образом:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Матрица Адамара &#039;&#039;H&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sub&amp;gt;  - это матрица размера 2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;times;&amp;amp;nbsp;2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;, для которой справедливо равенство&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;H_n = H_{1} \otimes H_{n-1}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\begin{align}&lt;br /&gt;
  H_1 = \frac{1}{\sqrt2}&lt;br /&gt;
   &amp;amp;\begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
\end{align}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&#039;&#039;&#039;где &amp;lt;math&amp;gt; \otimes &amp;lt;/math&amp;gt; представляет собой [https://ru.wikipedia.org/wiki/%D0%A2%D0%B5%D0%BD%D0%B7%D0%BE%D1%80%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5 тензорное произведение].&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Представим некоторые частные примеры матриц Адамара:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
    H_0 = +1,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_1 = \frac{1}{\sqrt2}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rr}&lt;br /&gt;
    1 &amp;amp; 1\\&lt;br /&gt;
    1 &amp;amp; -1&lt;br /&gt;
   \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_2 = \frac{1}{2}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1&lt;br /&gt;
    \end{array}\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
  H_3 = \frac{1}{2^{\frac{3}{2}}}&lt;br /&gt;
   \begin{pmatrix}\begin{array}{rrrrrrrr}&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1 &amp;amp; 1 &amp;amp;  1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp;  1 &amp;amp; -1 &amp;amp;  1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1\\&lt;br /&gt;
    1 &amp;amp; -1 &amp;amp; -1 &amp;amp;  -1 &amp;amp; -1 &amp;amp;  1 &amp;amp;  1 &amp;amp; -1\\&lt;br /&gt;
    \end{array}\end{pmatrix}&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;H_n&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;2^n\times 2^n&amp;lt;/math&amp;gt; можно вычислить поэлементно&amp;lt;ref name=&amp;quot;kunz&amp;quot;/&amp;gt;&amp;lt;ref name=&amp;quot;wiki&amp;quot;/&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{k,l} = \frac{1}{2^\frac{n}{2}} (-1)^{\sum_j k_j l_j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
где &#039;&#039;k&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;j&#039;&#039;&amp;lt;/sub&amp;gt; и &#039;&#039;l&#039;&#039;&amp;lt;sub&amp;gt;&#039;&#039;j&#039;&#039;&amp;lt;/sub&amp;gt; коэффициенты двоичного разложения чисел &#039;&#039;k&#039;&#039; и &#039;&#039;l&#039;&#039; (1 или 0):&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;math&amp;gt;k = \sum^{n}_{i=0} {k_i 2^i} = k_{n} 2^{n} + k_{n-1} 2^{n-1} + \cdots + k_1 2 + k_0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
и&lt;br /&gt;
: &amp;lt;math&amp;gt;l = \sum^{n}_{i=0} {l_i 2^i} = l_{n} 2^{n} + l_{n-1} 2^{n-1} + \cdots + l_1 2 + l_0&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;h_{k,l} = \frac{1}{2^\frac{n}{2}} (-1)^{\sum_j k_j l_j}&amp;lt;/math&amp;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;\sum_{j=0}^n k_j l_j&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Как видно по формуле, получаемое значение равна количеству единиц в двоичной записи результата побитового умножения &#039;&#039;k&#039;&#039; и &#039;&#039;l&#039;&#039;. Существует эффективный метод вычисления количества единиц , сложность которого равна &#039;&#039;m&#039;&#039; операций вычитания и &#039;&#039;m&#039;&#039; операций побитового умножения, где &#039;&#039;m&#039;&#039;-искомое количество единиц.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Последовательность исполнения метода следующая:&lt;br /&gt;
&lt;br /&gt;
1. Побитовое умножение &amp;lt;math&amp;gt;k\&amp;amp;l&amp;lt;/math&amp;gt;;  &lt;br /&gt;
&lt;br /&gt;
2. Вычисление количества единиц двоичной записи;&lt;br /&gt;
&lt;br /&gt;
3. Определение знака элемента по степени.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения матрицы Адамара порядка &amp;lt;math&amp;gt;N=2^n&amp;lt;/math&amp;gt; в первом шаге потребуется &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt; побитовых умножений &#039;&#039;k&amp;amp;l&#039;&#039;.&lt;br /&gt;
Во втором шаге, как говорилось выше, сложность метода вычисления количества единиц  числа в двоичном представлении равна удвоенному количеству единиц. В наихудшем случае сложность равна &amp;lt;math&amp;gt;2log_2N&amp;lt;/math&amp;gt;, при &#039;&#039;k=l=N-1&#039;&#039;, а в наилучшем 0. Для нахождения  степени всех элементов матрицы потребуются &amp;lt;math&amp;gt; 2N^2\left[\frac{log_2N}{4}\right]&amp;lt;/math&amp;gt; операций. В третьем шаге для определения знака потребуется &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt; операций, то есть сложность алгоритма &amp;lt;math&amp;gt; T(n) = 2\,(1+\left[\frac{n}{4}\right])\,2^{2n}. &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;k\&amp;amp;l&amp;lt;/math&amp;gt; - операция побитового умножения, где &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; соответствующие координаты элемента &amp;lt;math&amp;gt;h_{kl}&amp;lt;/math&amp;gt;;&lt;br /&gt;
* OP - вычисление количества единиц числа в двоичной системе. Состоит из последовательного применения операций вычитания и побитового умножения;&lt;br /&gt;
* SGN - определение знака соответствующего элемента. Если результат предыдущего шага четное, то знак положительный, иначе отрицательный.  &lt;br /&gt;
&lt;br /&gt;
[[file:Hadamar.png|thumb|center|1400px|Рисунок 1. Граф алгоритма.]]&lt;br /&gt;
[[file:OP3.png|thumb|center|1400px|Рисунок 2. Граф OP.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для построения матрицы порядка &amp;lt;math&amp;gt;N=2^n&amp;lt;/math&amp;gt; требуется последовательно выполнить следующие шаги:&lt;br /&gt;
* &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt;  вычислений побитового умножения,&lt;br /&gt;
* для каждого элемента от &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций вычитания и побитового умножения, в зависимости от результата предыдущего шага,&lt;br /&gt;
* &amp;lt;math&amp;gt;N^2&amp;lt;/math&amp;gt;  для определения знака значения элемента.&lt;br /&gt;
 &lt;br /&gt;
Таким образом для построения необходимы лишь простые операции вычитания и побитового умножения выполняемые с целыми положительными числами. Стоит заметить что вычисления для каждого элемента не зависят друг от друга. Также можно воспользоваться либо симметричностью матрицы Адамара либо закономерностью областей показанная в пункте 1.1.&lt;br /&gt;
Таким образом, основной вклад в высотe ЯПФ вносит операция вычисления количества единиц. Ширина ЯПФ будет равна &amp;lt;math&amp;gt;O(2^{2n})&amp;lt;/math&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; n \in \N &amp;lt;/math&amp;gt; - размерность матрицы Адамара &amp;lt;math&amp;gt;H_n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: 1 (натуральное число &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;H_n&amp;lt;/math&amp;gt; размера &amp;lt;math&amp;gt;2^n\times 2^n&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2^{2n}&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;
Одним из трудных мест параллельной реализации является правильный выбор количества процессов. Рассматривается некоторое фиксированное число процессов &amp;lt;math&amp;gt;P\in \mathbb{N}&amp;lt;/math&amp;gt;. Считается, что каждый процесс &#039;&#039;P&#039;&#039; обрабатывает не более чем &amp;lt;math&amp;gt;\left[\frac{2^{2n}}{P}\right]\geq 1&amp;lt;/math&amp;gt; элементов. Тогда качественная формула может быть записана таким образом: &amp;lt;math&amp;gt;T(n,P)=2\,(1+\left[ \frac{n}{4} \right])\,\frac{2^{2n}}{P}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Неравенство &amp;lt;math&amp;gt;\left[\frac{2^{2n}}{P}\right]\geq 1&amp;lt;/math&amp;gt; можно переписать, как &amp;lt;math&amp;gt;log_2\,\sqrt{P}\leq n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Легко увидеть, что минимум функции &#039;&#039;T(n,P)&#039;&#039; будет при максимально возможном &#039;&#039;P&#039;&#039; : &amp;lt;math&amp;gt;log_2\,\sqrt{P}\leq n&amp;lt;/math&amp;gt;. Такое &#039;&#039;P&#039;&#039; будет оптимальным числом процессов для алгоритма. В частности, для &amp;lt;math&amp;gt;P=2^p,\,p\in\mathbb{N}&amp;lt;/math&amp;gt; оптимальное &amp;lt;math&amp;gt;P = 2^{2n}&amp;lt;/math&amp;gt;.&lt;br /&gt;
:&amp;lt;math&amp;gt;\frac{T(n)}{T(n,P)}=P&amp;lt;/math&amp;gt;.&lt;br /&gt;
То есть, отношение последовательной и параллельной сложности будет &#039;&#039;линейно&#039;&#039; зависеть от &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Вычислительная мощность&#039;&#039; алгоритма построения матрицы Адамара, как отношение числа операций к суммарному объему входных и выходных данных: &lt;br /&gt;
:&amp;lt;math&amp;gt;\,\frac{2^{2n}(2+[\frac{n}{4}])}{1+2^{2n}}\left( \sim [\frac{n}{4}],\,n\to+\infty \right)&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* Алгоритм построения матрицы Адамара является &#039;&#039;не детерминированным&#039;&#039;, так как число операций меняется в зависимости от входных данных (числа n, которое формирует матрицу размера 2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;&amp;amp;nbsp;&amp;amp;times;&amp;amp;nbsp;2&amp;lt;sup&amp;gt;&#039;&#039;n&#039;&#039;&amp;lt;/sup&amp;gt;);&lt;br /&gt;
&lt;br /&gt;
* Степень исхода вершины информационного графа равна 1;&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;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar(int** H, int n) // N = 2^n - размерность матрицы&lt;br /&gt;
{     &lt;br /&gt;
    int i,j,N;&lt;br /&gt;
    float h;&lt;br /&gt;
    h = pow(1/2,n/2); // h - нормализующий множитель&lt;br /&gt;
    N = pow(2,n);&lt;br /&gt;
&lt;br /&gt;
    for(i=0;i&amp;lt;N;++i) &lt;br /&gt;
    {&lt;br /&gt;
	for(j=0;j&amp;lt;N;++j)&lt;br /&gt;
	{&lt;br /&gt;
		ij = i &amp;amp; j;&lt;br /&gt;
    		for (l=0;ij;++l) ij&amp;amp;=ij-1; // l - количество единиц бинарного представления ij&lt;br /&gt;
		if(l%2==0) H[i][j] = h;&lt;br /&gt;
		else H[i][j] = -h;&lt;br /&gt;
	}&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;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar_recursion(int** H, int N, int i, int j, int h) // h - нормализующий множитель&lt;br /&gt;
{&lt;br /&gt;
    if(n==1) H[i][j] = h;&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        adamar(H, N/2, i, j, h);&lt;br /&gt;
        adamar(H, N/2, i, N/2+j, h);&lt;br /&gt;
        adamar(H, N/2, N/2+i, j, h);&lt;br /&gt;
        adamar(H, N/2, N/2+i, N/2+j, -h);&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;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void adamar_not_recursion(int** H, int n) // N = 2^n - размерность матрицы&lt;br /&gt;
{     &lt;br /&gt;
    int i,j,N;&lt;br /&gt;
    float h;&lt;br /&gt;
    h = pow(1/2,n/2);&lt;br /&gt;
    N = pow(2,n);&lt;br /&gt;
    k=2;&lt;br /&gt;
    H[0][0] = h;&lt;br /&gt;
	&lt;br /&gt;
    while(k&amp;lt;=N)&lt;br /&gt;
    {&lt;br /&gt;
	for (i=0; i&amp;lt;k; ++i)&lt;br /&gt;
	{&lt;br /&gt;
		for (j=0; j&amp;lt;k; ++j)&lt;br /&gt;
		{&lt;br /&gt;
			if (i&amp;lt;k/2 &amp;amp;&amp;amp; j&amp;lt;k/2)&lt;br /&gt;
			{&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				if(i&amp;gt;=k/2 &amp;amp;&amp;amp; j&amp;gt;=k/2)&lt;br /&gt;
				{&lt;br /&gt;
					H[i][j] = -(H[i-k/2][j-k/2]);&lt;br /&gt;
				}&lt;br /&gt;
				else&lt;br /&gt;
				{&lt;br /&gt;
					if (i&amp;gt;j)&lt;br /&gt;
					{&lt;br /&gt;
						H[i][j] = H[i-k/2][j];&lt;br /&gt;
					}&lt;br /&gt;
					else&lt;br /&gt;
					{&lt;br /&gt;
						H[i][j] = H[i][j-k/2];&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
		&lt;br /&gt;
        k=k*2;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для данного случая, рекурсия является менее эффективной для генерации матрицы Адамара ([https://habrahabr.ru/post/256351/ Хабрахабр. О бедной рекурсии замолвите слово, или всё, что вы не знали и не хотите о ней знать.]). С точки зрения последовательной реализации, генерация матрицы Адамара с помощью adamar_not_recursion будет выигрывать у adamar, так как adamar_not_recursion будет выполнять меньшее количество операций. С точки зрения параллельной реализации adamar имеет 100% парализацию и при определенных условиях будет выигрывать по времени у распараллелинной adamar_not_recursion (пусть в adamar и будет выполняться большее количество операций, но они являются [https://ru.wikipedia.org/wiki/%D0%91%D0%B8%D1%82%D0%BE%D0%B2%D1%8B%D0%B5_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B8 битовыми операциями]).&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
Исследование проводилось на суперкомпьютере &amp;quot;Blue Gene&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых  параметров запуска реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1, 2, 4, 8,..., 1024] ;&lt;br /&gt;
*	размер матрицы [2, 4, 8,..., 2048].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон эффективности реализации алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.0121%;&lt;br /&gt;
*	максимальная эффективность реализации 3.3003%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики производительности и эффективности выбранной реализации построение матрицы Адамара в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:Prois1.jpg|thumb|center|700px|Рис.5 Изменение производительности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
[[file:Effec1.jpg|thumb|center|700px|Рис.5 Изменение эффективности в зависимости от числа процессоров и размера матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Построим оценки масштабируемости выбранной реализации:&lt;br /&gt;
* При увеличении числа процессов производительность на рассмотренной области изменений параметров запуска увеличивается практически линейно. В следствии этого эффективность реализации, как видно по графику, перестает изменяться при увеличении числа процессоров и равна примерно 1,7%.&lt;br /&gt;
* При увеличении размера матрицы производительность на рассмотренной области изменений параметров запуска увеличивается логарифмически. Это связанно с тем, что количество операций зависит от количества единиц после бинарного произведения. Поэтому наиболее влияет порядок степени &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; размера матрицы &amp;lt;math&amp;gt;N=2^{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;
# [http://www.exponenta.ru/soft/matlab/potemkin/book2/chapter5/hadamard.asp MATLAB];&lt;br /&gt;
# [https://reference.wolfram.com/language/ref/HadamardMatrix.html WOLFRAM];&lt;br /&gt;
# [http://pydoc.net/Python/rogues/0.3.0/rogues.matrices.hadamard/ Python];&lt;br /&gt;
# [http://www.obihiro.ac.jp/~suzukim/masuda/octave/html3/octave_97.html Octave].&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что во многих вычислительных пакетах встроена операция тензорного произведения матриц, которая позволяет строить матрицу Адамара по определению. Этот факт позволяет использовать матрицу Адамара в этих вычислительных пакетах: &lt;br /&gt;
# [https://ru.wikipedia.org/wiki/Maple MAPLE];&lt;br /&gt;
# [https://ru.wikipedia.org/wiki/Mathcad MATCATH].&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Мак-Вильямс Ф.Дж., Слоэн Н.Дж.А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — 744 с.&lt;br /&gt;
&lt;br /&gt;
[2] Кронберг, Ю.И. Ожигов, А.Ю. Чернявский — Алгебраический аппарат квантовой информатики 2&lt;br /&gt;
&lt;br /&gt;
[3] Kunz H.O.. On the Equivalence Between One-Dimensional Discrete Walsh-Hadamard and Multidimensional Discrete Fourier Transforms. IEEE Transactions on Computers. 28 (3): 267–8. [https://en.wikipedia.org/wiki/Digital_object_identifier doi]:[http://ieeexplore.ieee.org/document/1675334/ 10.1109/TC.1979.1675334]&lt;br /&gt;
&lt;br /&gt;
[4] Википедия – свободная энциклопедия [Электронный ресурс]. -  https://en.wikipedia.org/wiki/Hadamard_transform. - (дата обращения: 15.10.2016).&lt;br /&gt;
&lt;br /&gt;
[5] Воеводин В.В.. Воеводин Вл.В. Параллельные вычисления. - СПб.: БХВ-Петербург, 2002. - 608 с.&lt;br /&gt;
&lt;br /&gt;
[6] Воронцов К.В.. Математические методы обучения по прецедентам (теория обучения машин)&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9F%D0%B5%D0%B9%D0%BB%D0%B8_%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=22599</id>
		<title>Алгоритм Пейли построения матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9F%D0%B5%D0%B9%D0%BB%D0%B8_%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=22599"/>
		<updated>2017-05-03T18:59:28Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Свойства и структура алгоритма */&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(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:Nikita|Иванов Н.В.]] (Разделы 1.1,1.7,1.9,1.10,2.4,2.7), [[Участник:Tsyganov Nikita|Цыганов Н.И.]] (Разделы 1.2,1.3,1.4,1.5,1.6,1.7,1.8,2.4), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (проверка, редактирование),  [[Участник:Sleo|С.Н.Леоненков]] (предварительня проверка), &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;rt&amp;quot;&amp;gt;http://cyberleninka.ru/article/n/matritsy-adamara-nechetnogo-poryadka.pdf&amp;lt;/ref&amp;gt; Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). &amp;lt;ref name=&amp;quot;rt2&amp;quot;&amp;gt;Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&amp;lt;/ref&amp;gt; М&lt;br /&gt;
&lt;br /&gt;
В данном описании рассматривается метод Пейли, основанный на теоретико-числовых принципах и позволяющий строить матрицы Адамара порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для решения поставленной задачи будем использовать метод Пейли.&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p. &lt;br /&gt;
&lt;br /&gt;
Чтобы найти все вычеты по модулю p, достаточно рассмотреть квадраты чисел от &amp;lt;math&amp;gt;1^2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;(p-1)^2&amp;lt;/math&amp;gt;. Но если учесть, что &amp;lt;math&amp;gt;(p-a)^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p = (-a)^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p = a^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p&amp;lt;/math&amp;gt;, то достаточно рассмотреть лишь числа &amp;lt;math&amp;gt;1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod &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;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Все элементы главной диагонали этой матрицы, кроме элемента &amp;lt;math&amp;gt;h_{00}&amp;lt;/math&amp;gt;, равны &amp;lt;math&amp;gt;X(0)-1=-1&amp;lt;/math&amp;gt;. Нетрудно заметить, что данная матрица состоит только лишь из элементов 1 и -1.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&amp;lt;ref name=&amp;quot;rt3&amp;quot;&amp;gt;http://tc.nsu.ru/uploads/codingtheory.pdf&amp;lt;/ref&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;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-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;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&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;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt; vector&amp;lt;int&amp;gt; &amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
    // 1) matrix size changing&lt;br /&gt;
    result.resize(n);&lt;br /&gt;
    for (int i=0; i&amp;lt;n; i++) {&lt;br /&gt;
        result[i].resize(n);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // 2) residue array building&lt;br /&gt;
    int p=n-1;&lt;br /&gt;
    vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
    residues.resize(2*p);&lt;br /&gt;
    for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
        residues[i] = -1;&lt;br /&gt;
    }&lt;br /&gt;
    for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
        residues[i*i % p] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
        residues[i] = residues[i-p];&lt;br /&gt;
    }&lt;br /&gt;
    // 3) Paley matrix building&lt;br /&gt;
    // first line filling&lt;br /&gt;
    for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
        result[0][j] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    // first column filling&lt;br /&gt;
    for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
        result[i][0] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    // others&lt;br /&gt;
    for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
        for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
            result[i][j] = residues[j-i+p];&lt;br /&gt;
        }&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;
Под сложностью будем понимать зависимость числа операций от задаваемого порядка матрицы &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;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&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;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph2.png|600px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания, каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt; соответствует трём последовательным операциям: умножения, взятия остатка по модулю и присваивания, а вершины, окрашенные серым, представляют собой промежуточные точки синхронизации.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph3.jpg|600px|thumb|center|Информационный граф для n=4.]]&lt;br /&gt;
На рисунке приведен информационный граф алгоритма для случая n=4. Вершины графа соответствуют следующим строчкам кода:&lt;br /&gt;
&lt;br /&gt;
a. residues[i] = -1;&lt;br /&gt;
&lt;br /&gt;
b. residues[i*i%p] = 1;&lt;br /&gt;
&lt;br /&gt;
c. residues[i] = residues[i-p];&lt;br /&gt;
&lt;br /&gt;
d. result[0][j] = 1;&lt;br /&gt;
&lt;br /&gt;
e. result[i][0] = 1;&lt;br /&gt;
&lt;br /&gt;
f. result[i][j] = residues[i-j+p];&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа алгоритма, в параллельном варианте необходимо последовательно выполнить следующие блоки:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; участков, состоящих из трёх операций: умножения, взятия остатка и присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из этого можно сделать вывод, что высота ярусно-параллельной формы информационного графа равняется 6 (присваивание, умножение, взятие остатка, присваивание, присваивание, присваивание). Ширина ярусно-параллельной формы равняется &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;, что означает, что при использовании &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; процессоров матрица Адамара будет строиться за 6 операций.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - порядок матрицы Адамара &amp;lt;math&amp;gt;H_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;n&amp;lt;/math&amp;gt; - натуральное;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое.&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &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;H_n&amp;lt;/math&amp;gt; (её элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара размера &amp;lt;math&amp;gt;n*n&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;O(1)&amp;lt;/math&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
Алгоритм является полностью детерминированным. &lt;br /&gt;
&lt;br /&gt;
Для вершин &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt; информационного графа степени исхода являются линейными, что означает, что при возможности на этапе реализации необходимо позаботиться об эффективном доступе к элементам массива &amp;quot;&amp;lt;math&amp;gt;residues&amp;lt;/math&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма построения матрицы Адамара проводилось на суперкомпьютере «Ломоносов». Для этого была исследована собственная реализация алгоритма с использованием средств MPI. В ходе исследования  было произведено множество запусков программы с различными значениями параметра &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (размер матрицы Адамара) и числом процессоров.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма:&lt;br /&gt;
*число процессоров (p): [2,64] с шагом 2;&lt;br /&gt;
*размер матрицы: простые числа в диапазоне [4,10000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон эффективности реализации алгоритма:&lt;br /&gt;
*минимальная эффективность реализации 0.0000036% при n=4, p=2;&lt;br /&gt;
*максимальная эффективность реализации 0.333426% при n=948, p=2.&lt;br /&gt;
&lt;br /&gt;
Ниже представлены графики времени работы, производительности и эффективности данной реализации алгоритма построения матрицы Адамара в зависимости от изменяемых параметров запуска.&lt;br /&gt;
[[Файл:time_graph1.png|500px|thumb|center|Время работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:perform_graph1.png|500px|thumb|center|Изменение производительности параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:efficiency_graph1.png|500px|thumb|center|Эффективность работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/snikersman/Hadamard Исследованная параллельная реализация на языке 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;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм построения матрицы Адамара реализован в различных математических пакетах и библиотеках: &lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9F%D0%B5%D0%B9%D0%BB%D0%B8_%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=22598</id>
		<title>Алгоритм Пейли построения матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9F%D0%B5%D0%B9%D0%BB%D0%B8_%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=22598"/>
		<updated>2017-05-03T18:58:19Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Общее описание алгоритма */&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(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:Nikita|Иванов Н.В.]] (Разделы 1.1,1.7,1.9,1.10,2.4,2.7), [[Участник:Tsyganov Nikita|Цыганов Н.И.]] (Разделы 1.2,1.3,1.4,1.5,1.6,1.7,1.8,2.4), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (проверка, редактирование),  [[Участник:Sleo|С.Н.Леоненков]] (предварительня проверка), &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;rt&amp;quot;&amp;gt;http://cyberleninka.ru/article/n/matritsy-adamara-nechetnogo-poryadka.pdf&amp;lt;/ref&amp;gt; Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). &amp;lt;ref name=&amp;quot;rt2&amp;quot;&amp;gt;Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&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;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p. &lt;br /&gt;
&lt;br /&gt;
Чтобы найти все вычеты по модулю p, достаточно рассмотреть квадраты чисел от &amp;lt;math&amp;gt;1^2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;(p-1)^2&amp;lt;/math&amp;gt;. Но если учесть, что &amp;lt;math&amp;gt;(p-a)^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p = (-a)^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p = a^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p&amp;lt;/math&amp;gt;, то достаточно рассмотреть лишь числа &amp;lt;math&amp;gt;1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod &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;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Все элементы главной диагонали этой матрицы, кроме элемента &amp;lt;math&amp;gt;h_{00}&amp;lt;/math&amp;gt;, равны &amp;lt;math&amp;gt;X(0)-1=-1&amp;lt;/math&amp;gt;. Нетрудно заметить, что данная матрица состоит только лишь из элементов 1 и -1.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&amp;lt;ref name=&amp;quot;rt3&amp;quot;&amp;gt;http://tc.nsu.ru/uploads/codingtheory.pdf&amp;lt;/ref&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;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-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;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&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;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt; vector&amp;lt;int&amp;gt; &amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
    // 1) matrix size changing&lt;br /&gt;
    result.resize(n);&lt;br /&gt;
    for (int i=0; i&amp;lt;n; i++) {&lt;br /&gt;
        result[i].resize(n);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // 2) residue array building&lt;br /&gt;
    int p=n-1;&lt;br /&gt;
    vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
    residues.resize(2*p);&lt;br /&gt;
    for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
        residues[i] = -1;&lt;br /&gt;
    }&lt;br /&gt;
    for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
        residues[i*i % p] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
        residues[i] = residues[i-p];&lt;br /&gt;
    }&lt;br /&gt;
    // 3) Paley matrix building&lt;br /&gt;
    // first line filling&lt;br /&gt;
    for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
        result[0][j] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    // first column filling&lt;br /&gt;
    for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
        result[i][0] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    // others&lt;br /&gt;
    for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
        for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
            result[i][j] = residues[j-i+p];&lt;br /&gt;
        }&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;
Под сложностью будем понимать зависимость числа операций от задаваемого порядка матрицы &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;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&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;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph2.png|600px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания, каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt; соответствует трём последовательным операциям: умножения, взятия остатка по модулю и присваивания, а вершины, окрашенные серым, представляют собой промежуточные точки синхронизации.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph3.jpg|600px|thumb|center|Информационный граф для n=4.]]&lt;br /&gt;
На рисунке приведен информационный граф алгоритма для случая n=4. Вершины графа соответствуют следующим строчкам кода:&lt;br /&gt;
&lt;br /&gt;
a. residues[i] = -1;&lt;br /&gt;
&lt;br /&gt;
b. residues[i*i%p] = 1;&lt;br /&gt;
&lt;br /&gt;
c. residues[i] = residues[i-p];&lt;br /&gt;
&lt;br /&gt;
d. result[0][j] = 1;&lt;br /&gt;
&lt;br /&gt;
e. result[i][0] = 1;&lt;br /&gt;
&lt;br /&gt;
f. result[i][j] = residues[i-j+p];&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа алгоритма, в параллельном варианте необходимо последовательно выполнить следующие блоки:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; участков, состоящих из трёх операций: умножения, взятия остатка и присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из этого можно сделать вывод, что высота ярусно-параллельной формы информационного графа равняется 6 (присваивание, умножение, взятие остатка, присваивание, присваивание, присваивание). Ширина ярусно-параллельной формы равняется &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;, что означает, что при использовании &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; процессоров матрица Адамара будет строиться за 6 операций.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - порядок матрицы Адамара &amp;lt;math&amp;gt;H_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;n&amp;lt;/math&amp;gt; - натуральное;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое.&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &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;H_n&amp;lt;/math&amp;gt; (её элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара размера &amp;lt;math&amp;gt;n*n&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;O(1)&amp;lt;/math&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
Алгоритм является полностью детерминированным. &lt;br /&gt;
&lt;br /&gt;
Для вершин &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt; информационного графа степени исхода являются линейными, что означает, что при возможности на этапе реализации необходимо позаботиться об эффективном доступе к элементам массива &amp;quot;&amp;lt;math&amp;gt;residues&amp;lt;/math&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма построения матрицы Адамара проводилось на суперкомпьютере «Ломоносов». Для этого была исследована собственная реализация алгоритма с использованием средств MPI. В ходе исследования  было произведено множество запусков программы с различными значениями параметра &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (размер матрицы Адамара) и числом процессоров.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма:&lt;br /&gt;
*число процессоров (p): [2,64] с шагом 2;&lt;br /&gt;
*размер матрицы: простые числа в диапазоне [4,10000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон эффективности реализации алгоритма:&lt;br /&gt;
*минимальная эффективность реализации 0.0000036% при n=4, p=2;&lt;br /&gt;
*максимальная эффективность реализации 0.333426% при n=948, p=2.&lt;br /&gt;
&lt;br /&gt;
Ниже представлены графики времени работы, производительности и эффективности данной реализации алгоритма построения матрицы Адамара в зависимости от изменяемых параметров запуска.&lt;br /&gt;
[[Файл:time_graph1.png|500px|thumb|center|Время работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:perform_graph1.png|500px|thumb|center|Изменение производительности параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:efficiency_graph1.png|500px|thumb|center|Эффективность работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/snikersman/Hadamard Исследованная параллельная реализация на языке 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;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм построения матрицы Адамара реализован в различных математических пакетах и библиотеках: &lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9F%D0%B5%D0%B9%D0%BB%D0%B8_%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=22597</id>
		<title>Алгоритм Пейли построения матрицы Адамара</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9F%D0%B5%D0%B9%D0%BB%D0%B8_%D0%BF%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=22597"/>
		<updated>2017-05-03T18:42:42Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: Новая страница: « {{algorithm | name              = Алгоритм Пейли построение матрицы Адамара | serial_complexity = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; | pf_h…»&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(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:Nikita|Иванов Н.В.]] (Разделы 1.1,1.7,1.9,1.10,2.4,2.7), [[Участник:Tsyganov Nikita|Цыганов Н.И.]] (Разделы 1.2,1.3,1.4,1.5,1.6,1.7,1.8,2.4), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (проверка, редактирование),  [[Участник:Sleo|С.Н.Леоненков]] (предварительня проверка), &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;rt&amp;quot;&amp;gt;http://cyberleninka.ru/article/n/matritsy-adamara-nechetnogo-poryadka.pdf&amp;lt;/ref&amp;gt; Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). &amp;lt;ref name=&amp;quot;rt2&amp;quot;&amp;gt;Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&amp;lt;/ref&amp;gt; Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Для решения поставленной задачи будем использовать метод Пейли.&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p. &lt;br /&gt;
&lt;br /&gt;
Чтобы найти все вычеты по модулю p, достаточно рассмотреть квадраты чисел от &amp;lt;math&amp;gt;1^2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;(p-1)^2&amp;lt;/math&amp;gt;. Но если учесть, что &amp;lt;math&amp;gt;(p-a)^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p = (-a)^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p = a^2 &amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p&amp;lt;/math&amp;gt;, то достаточно рассмотреть лишь числа &amp;lt;math&amp;gt;1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod &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;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Все элементы главной диагонали этой матрицы, кроме элемента &amp;lt;math&amp;gt;h_{00}&amp;lt;/math&amp;gt;, равны &amp;lt;math&amp;gt;X(0)-1=-1&amp;lt;/math&amp;gt;. Нетрудно заметить, что данная матрица состоит только лишь из элементов 1 и -1.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&amp;lt;ref name=&amp;quot;rt3&amp;quot;&amp;gt;http://tc.nsu.ru/uploads/codingtheory.pdf&amp;lt;/ref&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;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-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;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&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;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt; vector&amp;lt;int&amp;gt; &amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
    // 1) matrix size changing&lt;br /&gt;
    result.resize(n);&lt;br /&gt;
    for (int i=0; i&amp;lt;n; i++) {&lt;br /&gt;
        result[i].resize(n);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // 2) residue array building&lt;br /&gt;
    int p=n-1;&lt;br /&gt;
    vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
    residues.resize(2*p);&lt;br /&gt;
    for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
        residues[i] = -1;&lt;br /&gt;
    }&lt;br /&gt;
    for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
        residues[i*i % p] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
        residues[i] = residues[i-p];&lt;br /&gt;
    }&lt;br /&gt;
    // 3) Paley matrix building&lt;br /&gt;
    // first line filling&lt;br /&gt;
    for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
        result[0][j] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    // first column filling&lt;br /&gt;
    for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
        result[i][0] = 1;&lt;br /&gt;
    }&lt;br /&gt;
    // others&lt;br /&gt;
    for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
        for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
            result[i][j] = residues[j-i+p];&lt;br /&gt;
        }&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;
Под сложностью будем понимать зависимость числа операций от задаваемого порядка матрицы &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;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&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;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph2.png|600px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания, каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt; соответствует трём последовательным операциям: умножения, взятия остатка по модулю и присваивания, а вершины, окрашенные серым, представляют собой промежуточные точки синхронизации.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph3.jpg|600px|thumb|center|Информационный граф для n=4.]]&lt;br /&gt;
На рисунке приведен информационный граф алгоритма для случая n=4. Вершины графа соответствуют следующим строчкам кода:&lt;br /&gt;
&lt;br /&gt;
a. residues[i] = -1;&lt;br /&gt;
&lt;br /&gt;
b. residues[i*i%p] = 1;&lt;br /&gt;
&lt;br /&gt;
c. residues[i] = residues[i-p];&lt;br /&gt;
&lt;br /&gt;
d. result[0][j] = 1;&lt;br /&gt;
&lt;br /&gt;
e. result[i][0] = 1;&lt;br /&gt;
&lt;br /&gt;
f. result[i][j] = residues[i-j+p];&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа алгоритма, в параллельном варианте необходимо последовательно выполнить следующие блоки:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; участков, состоящих из трёх операций: умножения, взятия остатка и присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из этого можно сделать вывод, что высота ярусно-параллельной формы информационного графа равняется 6 (присваивание, умножение, взятие остатка, присваивание, присваивание, присваивание). Ширина ярусно-параллельной формы равняется &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;, что означает, что при использовании &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; процессоров матрица Адамара будет строиться за 6 операций.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - порядок матрицы Адамара &amp;lt;math&amp;gt;H_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;n&amp;lt;/math&amp;gt; - натуральное;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое.&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &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;H_n&amp;lt;/math&amp;gt; (её элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара размера &amp;lt;math&amp;gt;n*n&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;O(1)&amp;lt;/math&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
Алгоритм является полностью детерминированным. &lt;br /&gt;
&lt;br /&gt;
Для вершин &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt; информационного графа степени исхода являются линейными, что означает, что при возможности на этапе реализации необходимо позаботиться об эффективном доступе к элементам массива &amp;quot;&amp;lt;math&amp;gt;residues&amp;lt;/math&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма построения матрицы Адамара проводилось на суперкомпьютере «Ломоносов». Для этого была исследована собственная реализация алгоритма с использованием средств MPI. В ходе исследования  было произведено множество запусков программы с различными значениями параметра &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (размер матрицы Адамара) и числом процессоров.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма:&lt;br /&gt;
*число процессоров (p): [2,64] с шагом 2;&lt;br /&gt;
*размер матрицы: простые числа в диапазоне [4,10000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон эффективности реализации алгоритма:&lt;br /&gt;
*минимальная эффективность реализации 0.0000036% при n=4, p=2;&lt;br /&gt;
*максимальная эффективность реализации 0.333426% при n=948, p=2.&lt;br /&gt;
&lt;br /&gt;
Ниже представлены графики времени работы, производительности и эффективности данной реализации алгоритма построения матрицы Адамара в зависимости от изменяемых параметров запуска.&lt;br /&gt;
[[Файл:time_graph1.png|500px|thumb|center|Время работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:perform_graph1.png|500px|thumb|center|Изменение производительности параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:efficiency_graph1.png|500px|thumb|center|Эффективность работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/snikersman/Hadamard Исследованная параллельная реализация на языке 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;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм построения матрицы Адамара реализован в различных математических пакетах и библиотеках: &lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22596</id>
		<title>Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22596"/>
		<updated>2017-05-03T13:40:33Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Литература */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Sagak|С.А.Айвазян]], [[Участник:Kozlov_Vladimir|В.Козлов]] (Часть 1), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (компоновка и редактирование), [[Участник:ASA|А.С.Антонов]] (предварительная проверка).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
Алгоритм  Ланцоша &amp;lt;ref&amp;gt;Деммель Дж. Вычислительная линейна алгебра. Теория и приложения. -М.: Мир, 2001. - 430 c.&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;Вербицкий В.В., Реут В.В. Введение в численные методы алгебры, 2015.&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;
Преимущество алгоритма заключается в том, что он дает приближение за конечное число шагов. Метод Ланцоша выигрывает в конкуренции таким прямым методам, как метод прямых или обратных итераций, &amp;lt;math&amp;gt;QR&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;QL&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; — это итерационный алгоритм поиска &amp;lt;math&amp;gt;k&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;. Алгоритм применяется, когда матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; слишком велика, чтобы к ней можно было применять точные прямые методы вычисления собственных значений. Алгоритм комбинирует &#039;&#039;&#039;метод Рэлея — Ритца&#039;&#039;&#039; поиска приближённых собственных значений и &#039;&#039;&#039;метод Ланцоша&#039;&#039;&#039; построения крыловского подпространства.&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца является методом поиска &amp;lt;math&amp;gt;k&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;. Если &amp;lt;math&amp;gt;Q = [Q_k, Q_u]&amp;lt;/math&amp;gt; — ортонормированная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_k&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_u&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times n - k&amp;lt;/math&amp;gt;, то можно записать равенство&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;T = Q^T A Q = [Q_k, Q_u]^T A [Q_k, Q_u] = &lt;br /&gt;
\left[ \begin{array}{cc}&lt;br /&gt;
Q_k^T A Q_k &amp;amp; Q_k^T A Q_u\\&lt;br /&gt;
Q_u^T A Q_k &amp;amp; Q_u^T A Q_u&lt;br /&gt;
\end{array} \right]&lt;br /&gt;
= \left[ \begin{array}{cc}&lt;br /&gt;
T_{k} &amp;amp; T_{ku}^T\\&lt;br /&gt;
T_{ku} &amp;amp; T_{u}&lt;br /&gt;
\end{array} \right].&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца заключается в том, что собственные значения матрицы &amp;lt;math&amp;gt;T_k = Q_k^T A Q_k&amp;lt;/math&amp;gt; объявляются приближёнными собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Такое приближение является в некотором смысле «наилучшим»: можно показать, что если &amp;lt;math&amp;gt;T_k = V \Lambda V^{-1}&amp;lt;/math&amp;gt; — спектральное разложение &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;, то пара &amp;lt;math&amp;gt;(Q_k V, \Lambda)&amp;lt;/math&amp;gt; минимизирует функционал &amp;lt;math&amp;gt;L(P_k, D) = \Vert A P_k - P_k D \Vert_2&amp;lt;/math&amp;gt;, причём &amp;lt;math&amp;gt;L(Q_k V, \Lambda) = \Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;, то есть &amp;lt;math&amp;gt;A \approx (Q_k V) \Lambda (Q_k V)^{-1}&amp;lt;/math&amp;gt;. Из этого также видно, что метод Рэлея — Ритца позволяет получать приближения для собственных векторов матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Более того, можно показать, что собственные значения &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; отличаются от некоторых собственных значений &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не более чем на &amp;lt;math&amp;gt;\Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Метод Ланцоша — это метод построения матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, при использовании которого, во-первых, матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; оказывается симметричной трёхдиагональной, во-вторых, столбцы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются последовательно. Трёхдиагональность &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; приводит к следующим явлениям:&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; является трёхдиагональной матрицей меньшей размерности, а для трёхдиагональных матриц существуют высокоэффективные методы поиска собственных значений;&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_{ku}&amp;lt;/math&amp;gt; имеет только один ненулевой (возможно) элемент — правый верхний, а значит, для оценки погрешности полученных собственных значений достаточно знать только этот элемент.&lt;br /&gt;
&lt;br /&gt;
В теории в методе Ланцоша для вычисления каждого следующего столбца &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; достаточно знать только &amp;lt;math&amp;gt;q_{j - 1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_{j}&amp;lt;/math&amp;gt; в силу трёхдиагональности матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;. На практике из-за ошибок округления, если не предпринимать специальных мер, набор векторов &amp;lt;math&amp;gt;q_{1}, \dots, q_{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;b&amp;lt;/math&amp;gt; — начальное приближение для метода Ланцоша.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: трёхдиагональная симметричная вещественная матрица &amp;lt;math&amp;gt;T_k = \left[ \begin{array}{cccc}&lt;br /&gt;
\alpha_1 &amp;amp; \beta_1 &amp;amp; &amp;amp; \\&lt;br /&gt;
\beta_1 &amp;amp; \ddots &amp;amp; \ddots &amp;amp; \\&lt;br /&gt;
&amp;amp; \ddots &amp;amp; \ddots &amp;amp; \beta_{k - 1}\\&lt;br /&gt;
&amp;amp; &amp;amp; \beta_{k - 1} &amp;amp; \alpha_k&lt;br /&gt;
\end{array} \right]&amp;lt;/math&amp;gt;, ортонормированный набор векторов &amp;lt;math&amp;gt;q_1, \dots, q_k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;T_k = [q_1, \dots, q_k]^T A [q_1, \dots, q_k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Формулы метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{l}&lt;br /&gt;
q_1 = b / \Vert b \Vert_2\\&lt;br /&gt;
j = \overline{1, k}:\\&lt;br /&gt;
\quad z_j = A q_j \\&lt;br /&gt;
\quad \alpha_j = q_j^T A q_j = q_j^T z_j \\&lt;br /&gt;
\quad z_j&#039; = z_j - \sum_{i=1}^j (z_j^T q_i) q_i \\&lt;br /&gt;
\quad z_j&#039;&#039; = z_j&#039; - \sum_{i=1}^j (z_j&#039;^T q_i) q_i\\&lt;br /&gt;
\quad \beta_j = \Vert z_j&#039;&#039; \Vert_2\\&lt;br /&gt;
\quad q_{j+1} = z_j&#039;&#039; / \Vert z_j&#039;&#039; \Vert_2 = z_j&#039;&#039;/\beta_j&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Собственные значения и собственные векторы матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; ищутся любым прямым алгоритмом.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;z_j&#039;, z_j&#039;&#039;&amp;lt;/math&amp;gt; — это полная переортогонализация &amp;lt;math&amp;gt;z_j&amp;lt;/math&amp;gt; методом Грама — Шмидта. Двойной запуск практически гарантирует, что &amp;lt;math&amp;gt;z_j&#039;&#039;&amp;lt;/math&amp;gt; будет ортогонален &amp;lt;math&amp;gt;q_1, \dots, q_j&amp;lt;/math&amp;gt;. Заметим, что &amp;lt;math&amp;gt;\sum_{i=1}^j (z^T q_i) q_i = Q_j Q_j^T z&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_j = [q_1, \dots, q_j]&amp;lt;/math&amp;gt;, поэтому переортогонализацию можно переписать в виде &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j, z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_j = 0&amp;lt;/math&amp;gt; для какого-либо &amp;lt;math&amp;gt;j &amp;lt; k&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\Vert T_{ju}\Vert_2 = 0&amp;lt;/math&amp;gt;, а значит, собственные значения &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; в точности совпадают с каким-то собственными значениями &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. В этом случае дальнейшие вычисления прекращаются и либо используется полученная &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; размерности меньшей, чем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, либо процедура запускается заново с другим начальным вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
У алгоритма построения матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; в том виде, как он описан выше, можно выделить два ядра:&lt;br /&gt;
# умножение матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на вектор &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;z_j = A q_j&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; умножений вещественных чисел);&lt;br /&gt;
# переортогонализация: &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j,\; z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(nk^2)&amp;lt;/math&amp;gt; умножений вещественных чисел).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
На макроуровне выделяем 3 основные операции:&lt;br /&gt;
&lt;br /&gt;
1. Умножение исходной матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на очередной вектор базиса &amp;lt;math&amp;gt;q_p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z=Aq_p. &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Повторное проведения процесса  Грамма-Шмидта  для ортогонализации посчитанного вектора &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt; со всеми построенными ранее векторами базиса.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i.      &amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
3.Непосредственное вычисление нового базисного вектора &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; и элементов &amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j&lt;br /&gt;
&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; \beta_{j+1}&lt;br /&gt;
&amp;lt;/math&amp;gt;  трехдиагональной матрицы.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j=q_j^Tz,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{j+1}=z/\beta_{j+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;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; q_1=b/||b||,\\&lt;br /&gt;
&amp;amp; \beta_1=0,\\&lt;br /&gt;
&amp;amp;q_0=0, \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&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;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&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;&lt;br /&gt;
1.z=Aq_j, &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j}&amp;lt;/math&amp;gt; конечной матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
2.\alpha_j=q_j^Tz,&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;&lt;br /&gt;
3.z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;4.z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,      &amp;lt;/math&amp;gt; &lt;br /&gt;
  &lt;br /&gt;
После ортогонализации процедура продолжается следующим образом.                      &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;5.z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j+1}&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;t_{j+1,j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;6.\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_{j+1}=0&amp;lt;/math&amp;gt;, то алгоритм завершается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;7.q_{j+1}=z/\beta_{j+1}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В конце каждой итерации получаем очередной вектор &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; базиса с единичной нормой, который ортогонален всем предыдущим векторам базиса,&lt;br /&gt;
&lt;br /&gt;
и элементы &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\beta_{j+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;
На &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ой итерации алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2 + n + 4nj + n + n = n^2 + 3n + 4nj&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;n(n - 1) + (n - 1) + (4n - 2)j + (n - 1) = n^2 + (n - 2) + (4n - 2)j&amp;lt;/math&amp;gt; сложений и вычитаний;&lt;br /&gt;
* одно извлечение квадратного корня.&lt;br /&gt;
&lt;br /&gt;
Всего за &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; итераций алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;(n + 3)nk + 2nk(k + 1)&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;(n^2 + n - 2)k + (2n - 1)k(k + 1)&amp;lt;/math&amp;gt; сложений и вычитаний.&lt;br /&gt;
&lt;br /&gt;
Таким образом, алгоритм имеет последовательную сложность &amp;lt;math&amp;gt;O(n^2k + nk^2)&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;
[[Файл:Lanczoc-full-orth-macro.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 1. Информационный граф алгоритма Ланцоша на уровне итераций с входными и выходными данными. In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и вектор &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), nrm — вычисление еклидовой нормы вектора, / — деление вектора на число, Iter — итерации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Информационный граф на уровне одной итерации с входными и выходными данными====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Lanczoc-full-orth-iter.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 2. Информационный граф итерации алгоритма Ланцоша на уровне макроопераций (первые три итерации). In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), dprod — скалярное произведение векторов, mprod — произведение матрицы на вектор, - — разность векторов, nrm — вычисление еклидовой нормы вектора, / — деление вектора на число.]]&lt;br /&gt;
&lt;br /&gt;
====Общий информационный граф алгроитма====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:photo.jpg|thumb|center|alt=Общий информационный граф алгроитма Ланцоша|Рисунок 3. Общий информационный граф алгроитма алгоритма Ланцоша.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Вершина черного цвета соответствует операции  &amp;lt;math&amp;gt;Aq_j,&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина красного цвета соответствует операции скалярного произведения &amp;lt;math&amp;gt;q_j^Tz&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина сиреневого цвета соответствует операции &amp;lt;math&amp;gt;z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина желтого цвета соответствует операции &amp;lt;math&amp;gt;z-\alpha_jq_j-\beta_{j-1}q_{j-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина синего цвета соответствует операции &amp;lt;math&amp;gt;||z||&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина зеленого цвета соответствует операции &amp;lt;math&amp;gt;z/\beta_j&amp;lt;/math&amp;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;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операциями умножения в каждом (вычисление &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операцией умножения в каждом (вычисление &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;j&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; ярусов сложений с &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;n&amp;lt;/math&amp;gt; (первая переортогонализация);&lt;br /&gt;
# &amp;lt;math&amp;gt;j&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; ярусов сложений с &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;n&amp;lt;/math&amp;gt; (вторая переортогонализация);&lt;br /&gt;
# &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операцией умножения в каждом (вычисление &amp;lt;math&amp;gt;\beta_j&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; ярус делений размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (вычисление &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Итого ширина ЯПФ одной итерации составляет &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, высота — &amp;lt;math&amp;gt;4n + 2j + 3&amp;lt;/math&amp;gt;. Ширина ЯПФ всего алгоритма составляет &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, высота — &amp;lt;math&amp;gt;O(nk + k^2)&amp;lt;/math&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;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;),произвольный вектор ненулевой &amp;lt;math&amp;gt;b&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;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; – симметрическая матрица, т. е. &amp;lt;math&amp;gt;a_{ij}= a_{ji}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;..&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 3)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: трехдиагональная симметрическая матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;_{ij}&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; размерности &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2k&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;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных равняется  &amp;lt;math&amp;gt;O(k)&amp;lt;/math&amp;gt;. Алгоритм недетерминированный, так как если в какой-то итерации &amp;lt;math&amp;gt;b_j=0&amp;lt;/math&amp;gt;, то алгоритм останавливается. Также на недетерминированность может повлиять изменение порядка выполнения ассоциативных операций, в частности при вычислении скалярного произведения. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Длинных&amp;quot; дуг в информационном графе нет,  запись данных происходит предсказуемо(на каждом шаге заполняются следующие элементы выходных векторов), следовательно нет никаких потенциальных сложностей с размещением данных в иерархии памяти компьютера на этапе выполнения программы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Первое исследование масштабируемости проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
Набор изменяемых параметров запуска реализации алгоритма и границы значений параметров алгоритма:&lt;br /&gt;
*Число процессоров &amp;lt;math&amp;gt;1,2,4,8,16,32,48&amp;lt;/math&amp;gt;&lt;br /&gt;
*Размерность матрицы &amp;lt;math&amp;gt;[1000:16000]&amp;lt;/math&amp;gt;&lt;br /&gt;
*Количество итераций &amp;lt;math&amp;gt;10&amp;lt;/math&amp;gt;&lt;br /&gt;
Использовался компилятор g++ версии 5.4.0 с параметрами запуска: &lt;br /&gt;
*-fopenmp &lt;br /&gt;
*-std=c++11&lt;br /&gt;
Реализация алгоритма написана с использованием  стандарта OpenMP.&lt;br /&gt;
[[Файл:just2.png|thumb|center|1024px|Рисунок 4. Зависимость производительности от числа процессов и размера входной матрицы]]&lt;br /&gt;
[http://pastebin.com/iurnjf8f Используемая параллельная реализация алгоритма на языке C++]&lt;br /&gt;
&lt;br /&gt;
Как видно из графика, размер задачи не оказывает существенного влияния на производительность. С увеличением количества процессоров производительность сначала возрастает, затем  медленно убывает. Высокая производительность достигается  при работе 20-30 процессоров,  при дальнейшем увеличении числа процессоров накладные расходы на организацию параллельного вычисления ведут к уменьшению производительности.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Следующее исследование масштабируемости реализации алгоритма проводилось с использованием стандарта MPI на суперкомпьютере &amp;quot;Ломоносов&amp;quot; суперкомпьютерного комплекса Московского университета.&lt;br /&gt;
&lt;br /&gt;
Набор изменяемых параметров запуска реализации алгоритма и границы значений параметров алгоритма:&lt;br /&gt;
*Число процессоров &amp;lt;math&amp;gt;1,2,4,8,16,32,64,96,128&amp;lt;/math&amp;gt;&lt;br /&gt;
*Размерность матрицы &amp;lt;math&amp;gt; 1000:15000,1700,21000,25000,30000&amp;lt;/math&amp;gt;&lt;br /&gt;
*Количество итераций &amp;lt;math&amp;gt;500&amp;lt;/math&amp;gt;&lt;br /&gt;
Сборка осуществлялась с параметрами: &lt;br /&gt;
*openmpi/1.5.5-icc&lt;br /&gt;
*intel/13.1.0&lt;br /&gt;
[[Файл:just5.png|thumb|center|1024px|Рисунок 4. Зависимость производительности от числа процессов и размера входной матрицы]]&lt;br /&gt;
[[Файл:just6.png|thumb|center|1024px|Рисунок 4. Зависимость времени выполнения от числа процессов и размера входной матрицы]]&lt;br /&gt;
[http://pastebin.com/5id6w9is  Используемая параллельная реализация алгоритма на языке C++]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов производительность возрастает  на всей рассмотренной области изменений параметров запуска. Увеличение размера задачи так же повышает производительность   в рассматриваемой области, как и при увеличении количества  процессоров, но при размерах задачи больше 25000 наблюдается медленный спад. Это снижение производительности объясняется тем, что при увеличении размера задачи существенно возрастают объемы передаваемых данных между процессами.&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
NAG Library имеет множество процедур для решения система алгебраических уравнений и нахождения собственных значений, которые используют алгоритм Ланцоша.&lt;br /&gt;
&lt;br /&gt;
http://www.nag.com/content/nag-library C, C++, Fortran, C#, MATLAB, R.&lt;br /&gt;
&lt;br /&gt;
MATLAB содержит реализацию алгоритма в пакете  Gaussian Belief Propagation Matlab Package.&lt;br /&gt;
&lt;br /&gt;
http://www.cs.cmu.edu/~bickson/gabp/.&lt;br /&gt;
 &lt;br /&gt;
GraphLab имеет библиотеку, в которой есть огромное количество параллельных реализаций алгоритма Ланцоша &lt;br /&gt;
        &lt;br /&gt;
https://turi.com/products/create/open_source.html C++.&lt;br /&gt;
&lt;br /&gt;
В LANSO/PLANSO есть параллельная версия алгоритма&lt;br /&gt;
&lt;br /&gt;
http://web.cs.ucdavis.edu/~bai/ET/lanczos_methods/overview_PLANSO.html Fortran.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория:Статьи в работе]]&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22595</id>
		<title>Метод «разделяй и властвуй» вычисления собственных значений и векторов симметричной трехдиагональной матрицы</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22595"/>
		<updated>2017-05-03T13:40:11Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Роман_Землянский|Р.Землянский]] (Разделы &lt;br /&gt;
[[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]]), В.Завольсков (Разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Существующие реализации алгоритма|2.7]]), [[Участник:IgorS]] (предварительная проверка), [[Участник:Chernyavskiy|А.Ю. Чернявский]] (проверка, редактирование).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод &amp;quot;Разделяй и властвуй&amp;quot; вычисления собственных значений и векторов трёхдиагональной матрицы&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt; c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt; O(n^{2.3}) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
крайне редко: &amp;lt;math&amp;gt;  O(n^{2}) &amp;lt;/math&amp;gt; &lt;br /&gt;
| pf_width          = &lt;br /&gt;
| input_data        =  &amp;lt;math&amp;gt; 2n + 1 &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       =  &amp;lt;math&amp;gt; n(n + 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; - это наиболее быстрый из существующих методов, если нужны все собственные значения и собственные векторы трехдиагональной матрицы, начиная с порядка n, примерно равного 26. (Точное значение этого порогового порядка зависит от компьютера.) Его численно устойчивая реализация весьма не тривиальна. В самом деле, хотя впервые метод был предложен еще в 1981 г., &amp;quot;правильный&amp;quot; способ его реализации был найден лишь в 1992 г. Этот способ воплощен LAPACK-программами ssyevd (для плотных матриц) и sstevd (для трехдиагональных матриц). В них стратегия &amp;quot;разделяй-и-влавствуй&amp;quot; используется для матриц порядка, большего чем 25. Для матриц меньшего порядка (или если нужны только собственные значения) происходит автоматический переход к QR-итерации.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Пусть &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
T = \begin{bmatrix}&lt;br /&gt;
 a_{1} &amp;amp; b_{1}&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp; b_{m} &amp;amp; a_{m+1} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
= \begin{bmatrix}&lt;br /&gt;
  a_{1} &amp;amp; b_{1} &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} - b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; a_{m+1} - b_{m} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix} +&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
+ \begin{bmatrix}&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 &amp;amp;&amp;amp;b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&lt;br /&gt;
= \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m} * \begin{bmatrix} 0 \\ \vdots \\ 0 \\ 1 \\ 1 \\ 0 \\ \vdots \\ 0 \end{bmatrix} \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix} &lt;br /&gt;
&lt;br /&gt;
\equiv \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Предположим, что нам известны спектральные разложения матриц &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; T_{2} &amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; T_{i} = Q_{i} \Lambda_{i} Q_{i}^{T} &amp;lt;/math&amp;gt;. В действительности, они будут рекурсивно вычисляться тем же самым алгоритмом. Установим связь между собственными значениями матрицы Т и собственными значениями матриц&lt;br /&gt;
&amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;. Имеем:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt; &lt;br /&gt;
T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} \Lambda_{1} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2} \Lambda_{2} Q_{2}^{T}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}(\begin{bmatrix} \Lambda_{1} &amp;amp; \\  &amp;amp; \Lambda_{2}\end{bmatrix} + b_{m}uu^{T})\begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}&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;&lt;br /&gt;
u = \begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}v&lt;br /&gt;
  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
так как &amp;lt;math&amp;gt;v = \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix}^T&amp;lt;/math&amp;gt;, получим матрицу, состоящую из последнего столбца матрицы &amp;lt;math&amp;gt; Q_{1}^{T}&amp;lt;/math&amp;gt; и первого столбца матрицы &amp;lt;math&amp;gt; Q_{2}^{T}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Следовательно, &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; имеет те же собственные значения, что и подобная ей матрица &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;D = \begin{bmatrix} \Lambda_{1} &amp;amp; 0 \\ 0 &amp;amp; \Lambda_{2}\end{bmatrix}&amp;lt;/math&amp;gt; - диагональная матрица, &lt;br /&gt;
&amp;lt;math&amp;gt;\rho = b_{m}&amp;lt;/math&amp;gt; - число, а &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - вектор. &lt;br /&gt;
&lt;br /&gt;
Будем предполагать, не ограничивая общности, что диагональные элементы &amp;lt;math&amp;gt;d_{1}, \ldots, d_{n}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; упорядочены по убыванию: &amp;lt;math&amp;gt;d_{n} &amp;lt;= \ldots &amp;lt;=d_{1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Чтобы найти собственные значения матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, вычислим её характеристический многочлен, считая пока матрицу &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденной.&lt;br /&gt;
Тогда&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;det(D + \rho uu^{T} - \lambda I) = det((D - \lambda I)(I + \rho (D- \lambda I)^{-1} uu^{T}))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Поскольку &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденна, &amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 0&amp;lt;/math&amp;gt; тогда и только тогда, когда &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; - собственное значение. Заметим, что матрица &amp;lt;math&amp;gt;I + \rho (D - \lambda I)^{-1}uu^{T}&amp;lt;/math&amp;gt; получается из единичной добавлением матрицы ранга 1. Определитель такой матрицы легко вычислить.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;&#039;Лемма 1.&#039;&#039;&#039; Справедливо равенство &amp;lt;math&amp;gt;det(I + xy^{T}) = 1 + y^{T}x&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; - векторы.&lt;br /&gt;
&lt;br /&gt;
Таким образом,&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 1 + \rho u^{T}(D - \lambda I)^{-1}u&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; = 1 + \rho \sum_{i=1, n} \frac{u_{i}^{2}} {d_{i}-\lambda} \equiv f(\lambda)&amp;lt;/math&amp;gt; , &lt;br /&gt;
&lt;br /&gt;
т.е. собственные значения матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; есть корни так называемого векового уравнения &amp;lt;math&amp;gt;f(\lambda) = 0&amp;lt;/math&amp;gt;. Если все числа &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; различны и все &amp;lt;math&amp;gt;u_{i} &amp;lt;&amp;gt; 0&amp;lt;/math&amp;gt; (случай общего положения), то &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; имеет график типа показанного на рис.1(где &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\rho &amp;gt; 0&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
[[File:Graphics.PNG|thumb|center|800px|Рис. 1. График функции &amp;lt;math&amp;gt; f(\lambda) = 1 + \frac{0.5}{1 - \lambda} + \frac{0.5}{2 - \lambda} + \frac{0.5}{3 - \lambda} + \frac{0.5}{4 - \lambda}&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Можно видеть, что прямая &amp;lt;math&amp;gt;y = 1&amp;lt;/math&amp;gt; является горизонтальной асимптотой для этого графика, а прямые &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt; есть вертикальные асимптоты. Поскольку &amp;lt;math&amp;gt;f^{&#039;}(\lambda) =  \rho \sum_{i=1, n} \frac{u_{i}^{2}} {(d_{i}-\lambda)^{2}}&amp;gt; 0 &amp;lt;/math&amp;gt;, функция возрастает всюду, кроме точек &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt;. Поэтому корни функции разделяются числами &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; и ещё один корень находится справа от точки &amp;lt;math&amp;gt;d_{1}&amp;lt;/math&amp;gt; (на рис. 1 &amp;lt;math&amp;gt;d_{1} = 4&amp;lt;/math&amp;gt;). (При &amp;lt;math&amp;gt;\rho&amp;lt;0&amp;lt;/math&amp;gt; функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; всюду убывает и соответствующий корень находится слева от точки &amp;lt;math&amp;gt;d_{n}&amp;lt;/math&amp;gt;). Для функции &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt;, монотонной и гладкой на каждом из интервалов &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;, можно найти вариант метода Ньютона, который быстро и монотонно сходится к каждому из корней, если начальная точка взята в &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;. Нам достаточно знать, что на практике метод сходится к каждому собственному значению за ограниченное число шагов. Поскольку вычисление &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;f^{&#039;}(\lambda)&amp;lt;/math&amp;gt; стоит &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов, для вычисления одного собственного значения достаточно &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, а для вычисления всех &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; собственных значений матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt;O(n^{2})&amp;lt;/math&amp;gt; флопов.&lt;br /&gt;
Для собственных векторов матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; мы легко можем получить явные выражения.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;&#039;Лемма 2.&#039;&#039;&#039; Если &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - собственное значение матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, то соответствующий вектор равен &amp;lt;math&amp;gt;(D - \alpha I)^{-1}u&amp;lt;/math&amp;gt;. Поскольку матрица &amp;lt;math&amp;gt;D - \alpha I&amp;lt;/math&amp;gt; диагональная, для вычисления такого вектора достаточно &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов.&lt;br /&gt;
&lt;br /&gt;
Доказательство.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;(D + \rho uu^{T})[(D - \alpha I)^{-1}u] = (D - \alpha I + \alpha I + \rho uu^{T})(D - \alpha I)^{-1}u&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=u + \alpha (D - \alpha I)^{-1}u + u[\rho u^{T}(D - \alpha I)^{-1}u] &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=u + \alpha(D - \alpha I)^{-1}u - u&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
                                                       поскольку &amp;lt;math&amp;gt; \rho u^{T}(D - \alpha I)^{-1}u + 1 = f(\alpha) = 0 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=\alpha [(D - \alpha I)^{-1}u]&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; собственных векторов требуется &amp;lt;math&amp;gt;O(n^{2})&amp;lt;/math&amp;gt; флопов. К сожалению, формула не обеспечивает численной устойчивости, так как для двух очень близких значений &amp;lt;math&amp;gt;\alpha_{i}&amp;lt;/math&amp;gt; может давать неортогональные приближенные собственные векторы &amp;lt;math&amp;gt;u_{i}&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;d_{i}&amp;lt;/math&amp;gt; различны и все &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt; отличны от нуля. Если это не так, вековое уравнение &amp;lt;math&amp;gt;f(\lambda)=0&amp;lt;/math&amp;gt; имеет &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вертикальных асимптот, где &amp;lt;math&amp;gt;k&amp;lt;n&amp;lt;/math&amp;gt;, а потому &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; корней. Однако оказывается, что остальные &amp;lt;math&amp;gt;n - k&amp;lt;/math&amp;gt; собственных значений могут быть определены без каких-либо усилий: если &amp;lt;math&amp;gt;d_{i}=d_{i+1}&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;u_{i}=0&amp;lt;/math&amp;gt;, то легко показать, что &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; является собственным значением и для матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;. В такой ситуации мы говорим о &#039;&#039;дефляции&#039;&#039;. На практике выбирается некоторое пороговое значение и дефляция для числа &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; регистрируется, если в смысле этого порога &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; достаточно близко к &amp;lt;math&amp;gt;d_{i+1}&amp;lt;/math&amp;gt; либо &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&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;u_{i}=0&amp;lt;/math&amp;gt;, то соответствующий собственный вектор есть i-й столбец &amp;lt;math&amp;gt;e_{i}&amp;lt;/math&amp;gt; единичной матрицы. Это означает, что &amp;lt;math&amp;gt;e_{i}&amp;lt;/math&amp;gt; является i-м столбцом в матрице &amp;lt;math&amp;gt;Q_{&#039;}&amp;lt;/math&amp;gt;, поэтому при формировании матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; посредством левого умножения &amp;lt;math&amp;gt;Q_{1}&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;Q_{2}&amp;lt;/math&amp;gt; вычисление i-го столбца не требует никаких затрат. Аналогичное упрощение имеет место в случае &amp;lt;math&amp;gt;d_{i} = d_{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;
Предположим, что некоторое &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt;, хотя и мало, все же недостаточно мало для того, чтобы была зарегистрирована дефляция. В этом случае применение метода Ньютона к решению векового уравнения встречается с затруднениями. Вспомним, что пересчет приближённого решения &amp;lt;math&amp;gt;u_{j}&amp;lt;/math&amp;gt; уравнения &amp;lt;math&amp;gt;f(\lambda) = 0&amp;lt;/math&amp;gt; в методе Ньютона основан на следующих положениях:&lt;br /&gt;
&lt;br /&gt;
 1. Вблизи точки &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt; функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; аппроксимируется линейной функцией &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt;; график есть прямая линия, касающаяся графика функции &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 2. В качестве &amp;lt;math&amp;gt;\lambda_{j+1}&amp;lt;/math&amp;gt; берётся нуль этого линейного приближения, т.е. &amp;lt;math&amp;gt;l(\lambda_{j+1})=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Функция, показанная на рис.1, не доставляет видимых трудностей методу Ньютона, поскольку вблизи каждого своего нуля &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; достаточно хорошо аппроксимируется линейными функциями. Однако рассмотрим график функции на рис.2. Она получена из функции на рис. 1 заменой значения .5 для &amp;lt;math&amp;gt;u_{i}^{2}&amp;lt;/math&amp;gt; на .001. Это новое значение недостаточно мало для того, чтобы вызвать дефляцию. График функции в левой части рис.2 визуально не отличим от её вертикальных и горизонтальных асимптот, поэтому в правой части укрупненно воспроизведён фрагмент графика, прилегающий к вертикальной асимптоте &amp;lt;math&amp;gt;\lambda = 2&amp;lt;/math&amp;gt;. Видно, что график слишком быстро &amp;quot;выполняет поворот&amp;quot; и для большей части значений &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; почти горизонтален. Поэтому, применяя метод Ньютона почти к любому начальному приближению &amp;lt;math&amp;gt;\lambda_{0}&amp;lt;/math&amp;gt;, мы получаем линейное приближение &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt; с почти горизонтальным графиком и малым положительным угловым коэффициентом. В результате &amp;lt;math&amp;gt;\lambda_{1}&amp;lt;/math&amp;gt; является отрицательным числом, огромным по абсолютной величине, которое совершенно бесполезно в качестве приближения к истинному корню.&lt;br /&gt;
&lt;br /&gt;
[[File:GraphNewton.png|thumb|center|800px|Рис. 2. График функции &amp;lt;math&amp;gt; f(\lambda) = 1 + \frac{10^{-3}}{1 - \lambda} + \frac{10^{-3}}{2 - \lambda} + \frac{10^{-3}}{3 - \lambda} + \frac{10^{-3}}{4 - \lambda}&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Чтобы найти выход из этого положения, можно модифицировать метод Ньютона следующим образом: раз &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; нельзя хорошо приблизить линейной функцией &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt;, попробуем взять в качестве приближения какую-нибудь другую простую функцию &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;. Нет ничего особого именно в прямых линиях: для метода Ньютона вместо &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt; можно взять любое приближение &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;, значения и нули которого легко вычисляются. Функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; имеет полюсы в точках &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;d_{i+1}&amp;lt;/math&amp;gt;, которые определяют её поведение в соответствующих окрестностях. Поэтому при поиске корня в интервале &amp;lt;math&amp;gt;(d_{i+1}, d_{i})&amp;lt;/math&amp;gt; естественно выбрать функцию &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;, также имеющую эти полюсы, т.е. функцию вида&lt;br /&gt;
 &amp;lt;math&amp;gt;h(\lambda)= \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} + c_{3}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Константы &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; обеспечивающие, что &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt; есть приближение к &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt;, можно выбрать несколькими способами. Отметим, что если &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; уже известны, то уравнение &amp;lt;math&amp;gt;h(\lambda)=0&amp;lt;/math&amp;gt; легко решается относительно &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt;, поскольку сводится к эквивалентному квадратному уравнению&lt;br /&gt;
 &amp;lt;math&amp;gt;c_{1}(d_{i+1}-\lambda)+c_{2}(d_{i}-\lambda)+c_{3}(d_{i}-\lambda)(d_{i+1}-\lambda)=0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;\lambda_{j}&amp;lt;/math&amp;gt; - приближённое значение корня. определим &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; так, чтобы&lt;br /&gt;
 &amp;lt;math&amp;gt;\frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} + c_{3} = h(\lambda) \approx f(\lambda) = 1 + \rho \sum_{k=1, n} \frac{u_{k}^{2}} {d_{k}-\lambda} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
для &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; в окрестности &amp;lt;math&amp;gt;\lambda_{j}&amp;lt;/math&amp;gt;. Заметим, что&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;f(\lambda) = 1 + \rho \sum_{k=1, i} \frac{u_{k}^{2}} {d_{k}-\lambda} + \rho \sum_{k=i+1, n} \frac{u_{k}^{2}} {d_{k}-\lambda} \equiv 1 + \psi_{1}(\lambda) + \psi_{2}(\lambda)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\lambda \in (d_{i+1},d_{i})&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\psi_{1}(\lambda)&amp;lt;/math&amp;gt; есть сумма положительных слагаемых, а &amp;lt;math&amp;gt;\psi_{2}(\lambda)&amp;lt;/math&amp;gt; - сумма отрицательных. Поэтому и &amp;lt;math&amp;gt;\psi_{1}(\lambda)&amp;lt;/math&amp;gt;, и &amp;lt;math&amp;gt;\psi_{2}(\lambda)&amp;lt;/math&amp;gt; могут быть вычислены с высокой точностью; однако при их сложении вполне вероятно взаимное уничтожение верных разрядов и потеря относительной точности в сумме. Возьмем числа &amp;lt;math&amp;gt;c_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{1}}&amp;lt;/math&amp;gt;, такие, что функция &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h_{1}(\lambda) \equiv \hat{c_{1}} + \frac{c_{1}}{d_{i}-\lambda}&amp;lt;/math&amp;gt;   удовлетворяет условиям  &amp;lt;math&amp;gt;h_{1}(\lambda_{j}) = \psi_{1}(\lambda_{j})&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;h_{1}^{&#039;}(\lambda_{j})=\psi_{1}^{&#039;}(\lambda_{j})&amp;lt;/math&amp;gt; (1)&lt;br /&gt;
&lt;br /&gt;
Это означает, что гипербола, являющаяся графиком функции &amp;lt;math&amp;gt;h_{1}(\lambda)&amp;lt;/math&amp;gt;, касается графика функции &amp;lt;math&amp;gt;\psi_{i}(\lambda)&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt;. Два условия в (1) - это обычные условия метода Ньютона, за исключением того, что вместо прямой в качестве приближения используется гипербола. Легко проверить, что &amp;lt;math&amp;gt;c_{1}=\psi_{1}^{&#039;}(\lambda_{j})(d_{i} - \lambda_{j})^{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{1}}=\psi_{1}(\lambda_{j}) - \psi_{1}^{&#039;}(\lambda_{j})(d_{i} - \lambda_{j})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подобным же образом выбираем &amp;lt;math&amp;gt;c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{2}}&amp;lt;/math&amp;gt; так, чтобы функция &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h_{2}(\lambda) \equiv \hat{c_{2}} + \frac{c_{2}}{d_{i+1}-\lambda}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Удовлетворяла условиям&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;h_{2}(\lambda_{j}) = \psi_{2}(\lambda_{j})&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;h_{2}^{&#039;}(\lambda_{j})=\psi_{2}^{&#039;}(\lambda_{j})&amp;lt;/math&amp;gt; (2)&lt;br /&gt;
&lt;br /&gt;
Наконец, полагаем&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h(\lambda) = 1 + h_{1}(\lambda) + h_{2}(\lambda) = (1 + \hat{c_{1}} + \hat{c_{2}} + \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;\equiv c_{3} + \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром последовательной схемы решения является вычисление матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; собственных векторов путём умножения матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; Данная операция имеет сложность &amp;lt;math&amp;gt;cn^{3}&amp;lt;/math&amp;gt; о чём и говорится в разделе [[#Последовательная сложность алгоритма]] .&lt;br /&gt;
Ей предшествует вычисление собственных значений и векторов матрицы &amp;lt;math&amp;gt; D + \rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Ниже описана структура алгоритма, в которой есть блок умножения матриц для вычисления собственных векторов, являющийся вычислительным ядром алгоритма. В соответствующем разделе ([[#Вычислительное ядро алгоритма]]) мы упоминали о том, что данному блоку предшествует вычисление собственных значений, которое производится [https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%9D%D1%8C%D1%8E%D1%82%D0%BE%D0%BD%D0%B0 методом Ньютона].&lt;br /&gt;
&lt;br /&gt;
[[File:DivideAndConquerTree.png|thumb|center|left|800px|Рис. 3. Дерево алгоритма &amp;quot;Разделяй и властвуй&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
[[File:InfoGraph.jpg|thumb|center|1200px|Рис. 4. Детальное описание одного блока алгоритма]]&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&#039;&#039;Вычисление собственных значений и собственных векторов симметричной трехдиагональной матрицы посредством стратегии &amp;quot;разделяй и властвуй&amp;quot;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;proc dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T,Q,\Lambda)...&amp;lt;/math&amp;gt; по входной матрице &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются выходные матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;T = Q\Lambda Q^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Если &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - матрица размера &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; x &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  1. Присвоить выходным параметрам значения &amp;lt;math&amp;gt; Q = 1, \Lambda = T&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Иначе&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  1. Представить &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; в виде &amp;lt;math&amp;gt; T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  2. &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{1},Q_{1},\Lambda_{1})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  3. &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{2},Q_{2},\Lambda_{2})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  4. Построить &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt; по &amp;lt;math&amp;gt; \Lambda_{1},\Lambda_{2}, Q_{1}, Q_{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  5. Найти матрицу собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  6. Найти матрицу собственных векторов &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  7. Построить матрицу собственных векторов &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; : &amp;lt;math&amp;gt; Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}* Q^{&#039;} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  8. Присвоить выходным параметрам значения &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;endif&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Проанализируем сложность алгоритма. Пусть &amp;lt;math&amp;gt;t(n)&amp;lt;/math&amp;gt; - число флопов при обработке матрицы размера &amp;lt;math&amp;gt; n x n&amp;lt;/math&amp;gt; процедурой &#039;&#039;dc_eig&#039;&#039;. Тогда &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; t(n) = 2t(n/2) &amp;lt;/math&amp;gt; два рекурсивных обращения к &#039;&#039;dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{i},Q_{i},\Lambda_{i})&amp;lt;/math&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;D+\rho uu^{T}&amp;lt;/math&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;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; +c*n^{3}&amp;lt;/math&amp;gt; вычисление матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}*Q^{&#039;}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; Q_{1}, Q_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; рассматриваются как плотные матрицы и используется стандартный алгоритм матричного умножения, то константа &amp;lt;math&amp;gt; c &amp;lt;/math&amp;gt; в последней строке равна 1. Таким образом, именно это умножение составляет наиболее трудоёмкую часть алгоритма в целом. Игнорируя члены порядка &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;, получаем &amp;lt;math&amp;gt;t(n) = 2t(n/2) + cn^{3}&amp;lt;/math&amp;gt;. Решая это разностное уравнение, находим &amp;lt;math&amp;gt; t \approx c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На практике константа &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; обычно гораздо меньше 1, потому что матрица &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; весьма разрежена вследствие явления, называемого дефляцией.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
В данном разделе на рисунке 5 представлен информационный граф алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[File:InfoGraphSC.jpg|thumb|center|left|1200px|Рис. 5. Информационный граф алгоритма &amp;quot;Разделяй и властвуй&amp;quot; - шаг &amp;lt;b&amp;gt;Divide&amp;lt;/b&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Операции: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; - операция Divide разделения матрицы &amp;lt;math&amp;gt; T &amp;lt;/math&amp;gt; на матрицы &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Индексы - размерность &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{k}&amp;lt;/math&amp;gt; - операция Conquer сбора матрицы &amp;lt;math&amp;gt; D &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_{k} &amp;lt;/math&amp;gt; - операция поиска собственных значений &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; S^{&#039;} &amp;lt;/math&amp;gt; - операция поиска собственных векторов матрицы &amp;lt;math&amp;gt; Q^{&#039;} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; S &amp;lt;/math&amp;gt; - операция поиска собственных векторов матрицы &amp;lt;math&amp;gt; Q &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Рассмотрев информационный граф алгоритма, можно заметить, что в структуре имеется два параллельных блока - вызов рекурсивных функций &#039;&#039;dc_eig&#039;&#039; для вычисления собственных значений и векторов матриц &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&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;dc_eig&#039;&#039; отрабатывают последовательно - сначала со входными параметрами &amp;lt;math&amp;gt;T_{1}, Q_{1}, \Lambda_{1}&amp;lt;/math&amp;gt;, затем - &amp;lt;math&amp;gt;T_{2}, Q_{2}, \Lambda_{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, благодаря параллелизму высота алгоритма параллельного составляет &amp;lt;math&amp;gt;log_{2}(n)&amp;lt;/math&amp;gt;, когда как при последовательной реализации высота алгоритма равна сумме геометрической прогрессии &amp;lt;math&amp;gt;1+2+4+8+...+2^{n-1} = 2^{n} - 1&amp;lt;/math&amp;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;
&amp;lt;math&amp;gt;&lt;br /&gt;
L = \begin{bmatrix}&lt;br /&gt;
 a_{1} &amp;amp; b_{1}&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp; b_{m} &amp;amp; a_{m+1} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&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;2n + 1&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; n &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;
&lt;br /&gt;
&amp;lt;math&amp;gt; n + n^{2} = n(n + 1) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Описанный в данной статье алгоритм является самым быстрым алгоритмом, среди существующих: QR / Бисекция и обратная итерация / Разделяй и властвуй.&lt;br /&gt;
&lt;br /&gt;
Последовательная сложность алгоритма (не принимая во внимание дефляцию) удовлетворяет рекурсивному соотношению: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;t(n) = n^3 +2t(\frac{n}{2})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решение которого имеет вид:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt; t = c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На практике же, параллельная сложность алгоритма в силу использования дефляции, позволяющей получить выигрыш в количестве операций, который заключается в ускорении матричного умножения на последнем шаге алгоритма (см. [[#Дефляция]]), имеет следующий вид: &amp;lt;math&amp;gt; O(n^{2.3})&amp;lt;/math&amp;gt;  или в самых редких случаях &amp;lt;math&amp;gt; O(n^{2}) &amp;lt;/math&amp;gt; (см. [3] стр. 8).&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;
= Программная реализация алгоритма =&lt;br /&gt;
Вторая часть описания алгоритмов в рамках AlgoWiki рассматривает все составные части процесса их реализации. Рассматривается как последовательная реализация алгоритма, так и параллельная. Описывается взаимосвязь свойств программ, реализующих алгоритм, и особенностей архитектуры компьютера, на которой они выполняются. Исследуется работа с памятью, локальность данных и вычислений, описывается масштабируемость и эффективность параллельных программ, производительность компьютеров, достигаемая на данной программе. Обсуждаются особенности реализации для разных классов архитектур компьютеров, приводятся ссылки на реализации в существующих библиотеках.&lt;br /&gt;
&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;
*	число процессоров [1 : 8] (1,2,3,4,8);&lt;br /&gt;
*	размер матрицы [4 : 8192].&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости алгоритм был реализован на библиотеке OpenMP 1.5.5 для языка C++(компилятор g++) на cуперкомпьютере Ломоносов на узле compiler. Для данного узла максимально возможное число потоков - 8. В ходе оценки масштабируемости, программа была запущена в 1, 2, 4, 8 потока. &lt;br /&gt;
Параметры компиляции и запуска: &lt;br /&gt;
&lt;br /&gt;
 ssh compiler &lt;br /&gt;
 module add slurm&lt;br /&gt;
 module add openmpi/1.5.5-icc&lt;br /&gt;
 g++ _scratch/test.c++ -fopenmp -std=c++0x -o test &lt;br /&gt;
 sbatch -p test -n1 run ./test&lt;br /&gt;
&lt;br /&gt;
Для управления количеством потоков использовалась операция OpenMP omp_set_num_threads();&lt;br /&gt;
&lt;br /&gt;
[[File:ResultsDiagram.jpg|thumb|center|left|800px|Рис. 6. График времени работы программы в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Масштабируемость рассматриваемой реализации алгоритма &#039;&#039;&#039;&amp;quot;Разделяй и властвуй&amp;quot;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* При увеличении числа процессов общая эффективность программы увеличивается, т.к. время чтения и подготовки исходной матрицы остаётся неизменным, а время работы алгоритма уменьшается, однако рост незначительный.&lt;br /&gt;
* При увеличении размерности матрицы общая эффективность программы постепенно уменьшается, т.к. время чтения и подготовки исходных данных растёт быстрее, чем время работы исследуемого алгоритма.&lt;br /&gt;
* При одновременном увеличении как числа процессов, так и размерности матрицы общая эффективность программы уменьшается.&lt;br /&gt;
&lt;br /&gt;
Код исследуемой реализации представлен здесь [http://pastebin.com/QpfYZGkK pastebin.com]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Описываемый метод реализован в пакете LAPACK, описание которого можно найти в [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf этой статье] на страницах 7, 19 и 20, которая указана в списке литературы.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Дж. Деммель, «Вычислительная линейная алгебра» //С. 230-235&lt;br /&gt;
&lt;br /&gt;
[2] [http://www.netlib.org/utk/people/JackDongarra/PAPERS/104_1999_a-parallel-divide-and-conquer-algorithm.pdf Francoise Tisseury, Jack Dongarra, A Parallel Divide and Conquer Algorithm for the Symmetric Eigenvalue Problem on Distributed Memory Architectures]&lt;br /&gt;
&lt;br /&gt;
[3] [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf Francoise Tisseury, Jack Dongarra, Parallelizing the Divide and Conquer Algorithm for the Symmetric Tridiagonal Eigenvalue Problem on Distributed Memory Architectures]&lt;br /&gt;
&lt;br /&gt;
[4] [https://en.wikipedia.org/wiki/Divide-and-conquer_eigenvalue_algorithm Алгоритм &amp;quot;Разделяй и властвуй&amp;quot; - Wikipedia]&lt;br /&gt;
&lt;br /&gt;
[5] [http://www.cscamm.umd.edu/tadmor/pub/linear-stability/Gill_Tadmor_SISC90.pdf Doron Grill and Eitan Tadmor AN &amp;lt;math&amp;gt;O(N2)&amp;lt;/math&amp;gt; METHOD FOR COMPUTING THE EIGENSYSTEM OF &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;x&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; SYMMETRIC TRIDIAGONAL MATRICES BY THE DIVIDE AND CONQUER APPROACH]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория:Статьи в работе]]&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22594</id>
		<title>Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22594"/>
		<updated>2017-05-03T13:39:09Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Sagak|С.А.Айвазян]], [[Участник:Kozlov_Vladimir|В.Козлов]] (Часть 1), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (компоновка и редактирование), [[Участник:ASA|А.С.Антонов]] (предварительная проверка).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
Алгоритм  Ланцоша &amp;lt;ref&amp;gt;Деммель Дж. Вычислительная линейна алгебра. Теория и приложения. -М.: Мир, 2001. - 430 c.&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;Вербицкий В.В., Реут В.В. Введение в численные методы алгебры, 2015.&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;
Преимущество алгоритма заключается в том, что он дает приближение за конечное число шагов. Метод Ланцоша выигрывает в конкуренции таким прямым методам, как метод прямых или обратных итераций, &amp;lt;math&amp;gt;QR&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;QL&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; — это итерационный алгоритм поиска &amp;lt;math&amp;gt;k&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;. Алгоритм применяется, когда матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; слишком велика, чтобы к ней можно было применять точные прямые методы вычисления собственных значений. Алгоритм комбинирует &#039;&#039;&#039;метод Рэлея — Ритца&#039;&#039;&#039; поиска приближённых собственных значений и &#039;&#039;&#039;метод Ланцоша&#039;&#039;&#039; построения крыловского подпространства.&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца является методом поиска &amp;lt;math&amp;gt;k&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;. Если &amp;lt;math&amp;gt;Q = [Q_k, Q_u]&amp;lt;/math&amp;gt; — ортонормированная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_k&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_u&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times n - k&amp;lt;/math&amp;gt;, то можно записать равенство&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;T = Q^T A Q = [Q_k, Q_u]^T A [Q_k, Q_u] = &lt;br /&gt;
\left[ \begin{array}{cc}&lt;br /&gt;
Q_k^T A Q_k &amp;amp; Q_k^T A Q_u\\&lt;br /&gt;
Q_u^T A Q_k &amp;amp; Q_u^T A Q_u&lt;br /&gt;
\end{array} \right]&lt;br /&gt;
= \left[ \begin{array}{cc}&lt;br /&gt;
T_{k} &amp;amp; T_{ku}^T\\&lt;br /&gt;
T_{ku} &amp;amp; T_{u}&lt;br /&gt;
\end{array} \right].&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца заключается в том, что собственные значения матрицы &amp;lt;math&amp;gt;T_k = Q_k^T A Q_k&amp;lt;/math&amp;gt; объявляются приближёнными собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Такое приближение является в некотором смысле «наилучшим»: можно показать, что если &amp;lt;math&amp;gt;T_k = V \Lambda V^{-1}&amp;lt;/math&amp;gt; — спектральное разложение &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;, то пара &amp;lt;math&amp;gt;(Q_k V, \Lambda)&amp;lt;/math&amp;gt; минимизирует функционал &amp;lt;math&amp;gt;L(P_k, D) = \Vert A P_k - P_k D \Vert_2&amp;lt;/math&amp;gt;, причём &amp;lt;math&amp;gt;L(Q_k V, \Lambda) = \Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;, то есть &amp;lt;math&amp;gt;A \approx (Q_k V) \Lambda (Q_k V)^{-1}&amp;lt;/math&amp;gt;. Из этого также видно, что метод Рэлея — Ритца позволяет получать приближения для собственных векторов матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Более того, можно показать, что собственные значения &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; отличаются от некоторых собственных значений &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не более чем на &amp;lt;math&amp;gt;\Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Метод Ланцоша — это метод построения матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, при использовании которого, во-первых, матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; оказывается симметричной трёхдиагональной, во-вторых, столбцы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются последовательно. Трёхдиагональность &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; приводит к следующим явлениям:&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; является трёхдиагональной матрицей меньшей размерности, а для трёхдиагональных матриц существуют высокоэффективные методы поиска собственных значений;&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_{ku}&amp;lt;/math&amp;gt; имеет только один ненулевой (возможно) элемент — правый верхний, а значит, для оценки погрешности полученных собственных значений достаточно знать только этот элемент.&lt;br /&gt;
&lt;br /&gt;
В теории в методе Ланцоша для вычисления каждого следующего столбца &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; достаточно знать только &amp;lt;math&amp;gt;q_{j - 1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_{j}&amp;lt;/math&amp;gt; в силу трёхдиагональности матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;. На практике из-за ошибок округления, если не предпринимать специальных мер, набор векторов &amp;lt;math&amp;gt;q_{1}, \dots, q_{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;b&amp;lt;/math&amp;gt; — начальное приближение для метода Ланцоша.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: трёхдиагональная симметричная вещественная матрица &amp;lt;math&amp;gt;T_k = \left[ \begin{array}{cccc}&lt;br /&gt;
\alpha_1 &amp;amp; \beta_1 &amp;amp; &amp;amp; \\&lt;br /&gt;
\beta_1 &amp;amp; \ddots &amp;amp; \ddots &amp;amp; \\&lt;br /&gt;
&amp;amp; \ddots &amp;amp; \ddots &amp;amp; \beta_{k - 1}\\&lt;br /&gt;
&amp;amp; &amp;amp; \beta_{k - 1} &amp;amp; \alpha_k&lt;br /&gt;
\end{array} \right]&amp;lt;/math&amp;gt;, ортонормированный набор векторов &amp;lt;math&amp;gt;q_1, \dots, q_k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;T_k = [q_1, \dots, q_k]^T A [q_1, \dots, q_k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Формулы метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{l}&lt;br /&gt;
q_1 = b / \Vert b \Vert_2\\&lt;br /&gt;
j = \overline{1, k}:\\&lt;br /&gt;
\quad z_j = A q_j \\&lt;br /&gt;
\quad \alpha_j = q_j^T A q_j = q_j^T z_j \\&lt;br /&gt;
\quad z_j&#039; = z_j - \sum_{i=1}^j (z_j^T q_i) q_i \\&lt;br /&gt;
\quad z_j&#039;&#039; = z_j&#039; - \sum_{i=1}^j (z_j&#039;^T q_i) q_i\\&lt;br /&gt;
\quad \beta_j = \Vert z_j&#039;&#039; \Vert_2\\&lt;br /&gt;
\quad q_{j+1} = z_j&#039;&#039; / \Vert z_j&#039;&#039; \Vert_2 = z_j&#039;&#039;/\beta_j&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Собственные значения и собственные векторы матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; ищутся любым прямым алгоритмом.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;z_j&#039;, z_j&#039;&#039;&amp;lt;/math&amp;gt; — это полная переортогонализация &amp;lt;math&amp;gt;z_j&amp;lt;/math&amp;gt; методом Грама — Шмидта. Двойной запуск практически гарантирует, что &amp;lt;math&amp;gt;z_j&#039;&#039;&amp;lt;/math&amp;gt; будет ортогонален &amp;lt;math&amp;gt;q_1, \dots, q_j&amp;lt;/math&amp;gt;. Заметим, что &amp;lt;math&amp;gt;\sum_{i=1}^j (z^T q_i) q_i = Q_j Q_j^T z&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_j = [q_1, \dots, q_j]&amp;lt;/math&amp;gt;, поэтому переортогонализацию можно переписать в виде &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j, z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_j = 0&amp;lt;/math&amp;gt; для какого-либо &amp;lt;math&amp;gt;j &amp;lt; k&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\Vert T_{ju}\Vert_2 = 0&amp;lt;/math&amp;gt;, а значит, собственные значения &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; в точности совпадают с каким-то собственными значениями &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. В этом случае дальнейшие вычисления прекращаются и либо используется полученная &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; размерности меньшей, чем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, либо процедура запускается заново с другим начальным вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
У алгоритма построения матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; в том виде, как он описан выше, можно выделить два ядра:&lt;br /&gt;
# умножение матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на вектор &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;z_j = A q_j&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; умножений вещественных чисел);&lt;br /&gt;
# переортогонализация: &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j,\; z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(nk^2)&amp;lt;/math&amp;gt; умножений вещественных чисел).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
На макроуровне выделяем 3 основные операции:&lt;br /&gt;
&lt;br /&gt;
1. Умножение исходной матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на очередной вектор базиса &amp;lt;math&amp;gt;q_p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z=Aq_p. &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Повторное проведения процесса  Грамма-Шмидта  для ортогонализации посчитанного вектора &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt; со всеми построенными ранее векторами базиса.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i.      &amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
3.Непосредственное вычисление нового базисного вектора &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; и элементов &amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j&lt;br /&gt;
&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; \beta_{j+1}&lt;br /&gt;
&amp;lt;/math&amp;gt;  трехдиагональной матрицы.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j=q_j^Tz,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{j+1}=z/\beta_{j+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;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; q_1=b/||b||,\\&lt;br /&gt;
&amp;amp; \beta_1=0,\\&lt;br /&gt;
&amp;amp;q_0=0, \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&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;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&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;&lt;br /&gt;
1.z=Aq_j, &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j}&amp;lt;/math&amp;gt; конечной матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
2.\alpha_j=q_j^Tz,&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;&lt;br /&gt;
3.z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;4.z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,      &amp;lt;/math&amp;gt; &lt;br /&gt;
  &lt;br /&gt;
После ортогонализации процедура продолжается следующим образом.                      &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;5.z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j+1}&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;t_{j+1,j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;6.\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_{j+1}=0&amp;lt;/math&amp;gt;, то алгоритм завершается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;7.q_{j+1}=z/\beta_{j+1}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В конце каждой итерации получаем очередной вектор &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; базиса с единичной нормой, который ортогонален всем предыдущим векторам базиса,&lt;br /&gt;
&lt;br /&gt;
и элементы &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\beta_{j+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;
На &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ой итерации алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2 + n + 4nj + n + n = n^2 + 3n + 4nj&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;n(n - 1) + (n - 1) + (4n - 2)j + (n - 1) = n^2 + (n - 2) + (4n - 2)j&amp;lt;/math&amp;gt; сложений и вычитаний;&lt;br /&gt;
* одно извлечение квадратного корня.&lt;br /&gt;
&lt;br /&gt;
Всего за &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; итераций алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;(n + 3)nk + 2nk(k + 1)&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;(n^2 + n - 2)k + (2n - 1)k(k + 1)&amp;lt;/math&amp;gt; сложений и вычитаний.&lt;br /&gt;
&lt;br /&gt;
Таким образом, алгоритм имеет последовательную сложность &amp;lt;math&amp;gt;O(n^2k + nk^2)&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;
[[Файл:Lanczoc-full-orth-macro.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 1. Информационный граф алгоритма Ланцоша на уровне итераций с входными и выходными данными. In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и вектор &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), nrm — вычисление еклидовой нормы вектора, / — деление вектора на число, Iter — итерации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Информационный граф на уровне одной итерации с входными и выходными данными====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Lanczoc-full-orth-iter.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 2. Информационный граф итерации алгоритма Ланцоша на уровне макроопераций (первые три итерации). In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), dprod — скалярное произведение векторов, mprod — произведение матрицы на вектор, - — разность векторов, nrm — вычисление еклидовой нормы вектора, / — деление вектора на число.]]&lt;br /&gt;
&lt;br /&gt;
====Общий информационный граф алгроитма====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:photo.jpg|thumb|center|alt=Общий информационный граф алгроитма Ланцоша|Рисунок 3. Общий информационный граф алгроитма алгоритма Ланцоша.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Вершина черного цвета соответствует операции  &amp;lt;math&amp;gt;Aq_j,&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина красного цвета соответствует операции скалярного произведения &amp;lt;math&amp;gt;q_j^Tz&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина сиреневого цвета соответствует операции &amp;lt;math&amp;gt;z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина желтого цвета соответствует операции &amp;lt;math&amp;gt;z-\alpha_jq_j-\beta_{j-1}q_{j-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина синего цвета соответствует операции &amp;lt;math&amp;gt;||z||&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина зеленого цвета соответствует операции &amp;lt;math&amp;gt;z/\beta_j&amp;lt;/math&amp;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;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операциями умножения в каждом (вычисление &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операцией умножения в каждом (вычисление &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;j&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; ярусов сложений с &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;n&amp;lt;/math&amp;gt; (первая переортогонализация);&lt;br /&gt;
# &amp;lt;math&amp;gt;j&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; ярусов сложений с &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;n&amp;lt;/math&amp;gt; (вторая переортогонализация);&lt;br /&gt;
# &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операцией умножения в каждом (вычисление &amp;lt;math&amp;gt;\beta_j&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; ярус делений размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (вычисление &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Итого ширина ЯПФ одной итерации составляет &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, высота — &amp;lt;math&amp;gt;4n + 2j + 3&amp;lt;/math&amp;gt;. Ширина ЯПФ всего алгоритма составляет &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, высота — &amp;lt;math&amp;gt;O(nk + k^2)&amp;lt;/math&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;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;),произвольный вектор ненулевой &amp;lt;math&amp;gt;b&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;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; – симметрическая матрица, т. е. &amp;lt;math&amp;gt;a_{ij}= a_{ji}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;..&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 3)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: трехдиагональная симметрическая матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;_{ij}&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; размерности &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2k&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;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных равняется  &amp;lt;math&amp;gt;O(k)&amp;lt;/math&amp;gt;. Алгоритм недетерминированный, так как если в какой-то итерации &amp;lt;math&amp;gt;b_j=0&amp;lt;/math&amp;gt;, то алгоритм останавливается. Также на недетерминированность может повлиять изменение порядка выполнения ассоциативных операций, в частности при вычислении скалярного произведения. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Длинных&amp;quot; дуг в информационном графе нет,  запись данных происходит предсказуемо(на каждом шаге заполняются следующие элементы выходных векторов), следовательно нет никаких потенциальных сложностей с размещением данных в иерархии памяти компьютера на этапе выполнения программы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Первое исследование масштабируемости проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
Набор изменяемых параметров запуска реализации алгоритма и границы значений параметров алгоритма:&lt;br /&gt;
*Число процессоров &amp;lt;math&amp;gt;1,2,4,8,16,32,48&amp;lt;/math&amp;gt;&lt;br /&gt;
*Размерность матрицы &amp;lt;math&amp;gt;[1000:16000]&amp;lt;/math&amp;gt;&lt;br /&gt;
*Количество итераций &amp;lt;math&amp;gt;10&amp;lt;/math&amp;gt;&lt;br /&gt;
Использовался компилятор g++ версии 5.4.0 с параметрами запуска: &lt;br /&gt;
*-fopenmp &lt;br /&gt;
*-std=c++11&lt;br /&gt;
Реализация алгоритма написана с использованием  стандарта OpenMP.&lt;br /&gt;
[[Файл:just2.png|thumb|center|1024px|Рисунок 4. Зависимость производительности от числа процессов и размера входной матрицы]]&lt;br /&gt;
[http://pastebin.com/iurnjf8f Используемая параллельная реализация алгоритма на языке C++]&lt;br /&gt;
&lt;br /&gt;
Как видно из графика, размер задачи не оказывает существенного влияния на производительность. С увеличением количества процессоров производительность сначала возрастает, затем  медленно убывает. Высокая производительность достигается  при работе 20-30 процессоров,  при дальнейшем увеличении числа процессоров накладные расходы на организацию параллельного вычисления ведут к уменьшению производительности.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Следующее исследование масштабируемости реализации алгоритма проводилось с использованием стандарта MPI на суперкомпьютере &amp;quot;Ломоносов&amp;quot; суперкомпьютерного комплекса Московского университета.&lt;br /&gt;
&lt;br /&gt;
Набор изменяемых параметров запуска реализации алгоритма и границы значений параметров алгоритма:&lt;br /&gt;
*Число процессоров &amp;lt;math&amp;gt;1,2,4,8,16,32,64,96,128&amp;lt;/math&amp;gt;&lt;br /&gt;
*Размерность матрицы &amp;lt;math&amp;gt; 1000:15000,1700,21000,25000,30000&amp;lt;/math&amp;gt;&lt;br /&gt;
*Количество итераций &amp;lt;math&amp;gt;500&amp;lt;/math&amp;gt;&lt;br /&gt;
Сборка осуществлялась с параметрами: &lt;br /&gt;
*openmpi/1.5.5-icc&lt;br /&gt;
*intel/13.1.0&lt;br /&gt;
[[Файл:just5.png|thumb|center|1024px|Рисунок 4. Зависимость производительности от числа процессов и размера входной матрицы]]&lt;br /&gt;
[[Файл:just6.png|thumb|center|1024px|Рисунок 4. Зависимость времени выполнения от числа процессов и размера входной матрицы]]&lt;br /&gt;
[http://pastebin.com/5id6w9is  Используемая параллельная реализация алгоритма на языке C++]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов производительность возрастает  на всей рассмотренной области изменений параметров запуска. Увеличение размера задачи так же повышает производительность   в рассматриваемой области, как и при увеличении количества  процессоров, но при размерах задачи больше 25000 наблюдается медленный спад. Это снижение производительности объясняется тем, что при увеличении размера задачи существенно возрастают объемы передаваемых данных между процессами.&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
NAG Library имеет множество процедур для решения система алгебраических уравнений и нахождения собственных значений, которые используют алгоритм Ланцоша.&lt;br /&gt;
&lt;br /&gt;
http://www.nag.com/content/nag-library C, C++, Fortran, C#, MATLAB, R.&lt;br /&gt;
&lt;br /&gt;
MATLAB содержит реализацию алгоритма в пакете  Gaussian Belief Propagation Matlab Package.&lt;br /&gt;
&lt;br /&gt;
http://www.cs.cmu.edu/~bickson/gabp/.&lt;br /&gt;
 &lt;br /&gt;
GraphLab имеет библиотеку, в которой есть огромное количество параллельных реализаций алгоритма Ланцоша &lt;br /&gt;
        &lt;br /&gt;
https://turi.com/products/create/open_source.html C++.&lt;br /&gt;
&lt;br /&gt;
В LANSO/PLANSO есть параллельная версия алгоритма&lt;br /&gt;
&lt;br /&gt;
http://web.cs.ucdavis.edu/~bai/ET/lanczos_methods/overview_PLANSO.html Fortran.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22593</id>
		<title>Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22593"/>
		<updated>2017-05-03T13:38:24Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Sagak|С.А.Айвазян]], [[Участник:Kozlov_Vladimir|В.Козлов]] (Часть 1), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (компоновка и редактирование), [[Участник:ASA|А.С.Антонов]] (предварительная проверка).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
Алгоритм  Ланцоша &amp;lt;ref&amp;gt;Деммель Дж. Вычислительная линейна алгебра. Теория и приложения. -М.: Мир, 2001. - 430 c.&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;Вербицкий В.В., Реут В.В. Введение в численные методы алгебры, 2015.&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;
Преимущество алгоритма заключается в том, что он дает приближение за конечное число шагов. Метод Ланцоша выигрывает в конкуренции таким прямым методам, как метод прямых или обратных итераций, &amp;lt;math&amp;gt;QR&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;QL&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; — это итерационный алгоритм поиска &amp;lt;math&amp;gt;k&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;. Алгоритм применяется, когда матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; слишком велика, чтобы к ней можно было применять точные прямые методы вычисления собственных значений. Алгоритм комбинирует &#039;&#039;&#039;метод Рэлея — Ритца&#039;&#039;&#039; поиска приближённых собственных значений и &#039;&#039;&#039;метод Ланцоша&#039;&#039;&#039; построения крыловского подпространства.&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца является методом поиска &amp;lt;math&amp;gt;k&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;. Если &amp;lt;math&amp;gt;Q = [Q_k, Q_u]&amp;lt;/math&amp;gt; — ортонормированная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_k&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_u&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times n - k&amp;lt;/math&amp;gt;, то можно записать равенство&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;T = Q^T A Q = [Q_k, Q_u]^T A [Q_k, Q_u] = &lt;br /&gt;
\left[ \begin{array}{cc}&lt;br /&gt;
Q_k^T A Q_k &amp;amp; Q_k^T A Q_u\\&lt;br /&gt;
Q_u^T A Q_k &amp;amp; Q_u^T A Q_u&lt;br /&gt;
\end{array} \right]&lt;br /&gt;
= \left[ \begin{array}{cc}&lt;br /&gt;
T_{k} &amp;amp; T_{ku}^T\\&lt;br /&gt;
T_{ku} &amp;amp; T_{u}&lt;br /&gt;
\end{array} \right].&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца заключается в том, что собственные значения матрицы &amp;lt;math&amp;gt;T_k = Q_k^T A Q_k&amp;lt;/math&amp;gt; объявляются приближёнными собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Такое приближение является в некотором смысле «наилучшим»: можно показать, что если &amp;lt;math&amp;gt;T_k = V \Lambda V^{-1}&amp;lt;/math&amp;gt; — спектральное разложение &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;, то пара &amp;lt;math&amp;gt;(Q_k V, \Lambda)&amp;lt;/math&amp;gt; минимизирует функционал &amp;lt;math&amp;gt;L(P_k, D) = \Vert A P_k - P_k D \Vert_2&amp;lt;/math&amp;gt;, причём &amp;lt;math&amp;gt;L(Q_k V, \Lambda) = \Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;, то есть &amp;lt;math&amp;gt;A \approx (Q_k V) \Lambda (Q_k V)^{-1}&amp;lt;/math&amp;gt;. Из этого также видно, что метод Рэлея — Ритца позволяет получать приближения для собственных векторов матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Более того, можно показать, что собственные значения &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; отличаются от некоторых собственных значений &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не более чем на &amp;lt;math&amp;gt;\Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Метод Ланцоша — это метод построения матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, при использовании которого, во-первых, матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; оказывается симметричной трёхдиагональной, во-вторых, столбцы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются последовательно. Трёхдиагональность &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; приводит к следующим явлениям:&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; является трёхдиагональной матрицей меньшей размерности, а для трёхдиагональных матриц существуют высокоэффективные методы поиска собственных значений;&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_{ku}&amp;lt;/math&amp;gt; имеет только один ненулевой (возможно) элемент — правый верхний, а значит, для оценки погрешности полученных собственных значений достаточно знать только этот элемент.&lt;br /&gt;
&lt;br /&gt;
В теории в методе Ланцоша для вычисления каждого следующего столбца &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; достаточно знать только &amp;lt;math&amp;gt;q_{j - 1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_{j}&amp;lt;/math&amp;gt; в силу трёхдиагональности матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;. На практике из-за ошибок округления, если не предпринимать специальных мер, набор векторов &amp;lt;math&amp;gt;q_{1}, \dots, q_{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;b&amp;lt;/math&amp;gt; — начальное приближение для метода Ланцоша.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: трёхдиагональная симметричная вещественная матрица &amp;lt;math&amp;gt;T_k = \left[ \begin{array}{cccc}&lt;br /&gt;
\alpha_1 &amp;amp; \beta_1 &amp;amp; &amp;amp; \\&lt;br /&gt;
\beta_1 &amp;amp; \ddots &amp;amp; \ddots &amp;amp; \\&lt;br /&gt;
&amp;amp; \ddots &amp;amp; \ddots &amp;amp; \beta_{k - 1}\\&lt;br /&gt;
&amp;amp; &amp;amp; \beta_{k - 1} &amp;amp; \alpha_k&lt;br /&gt;
\end{array} \right]&amp;lt;/math&amp;gt;, ортонормированный набор векторов &amp;lt;math&amp;gt;q_1, \dots, q_k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;T_k = [q_1, \dots, q_k]^T A [q_1, \dots, q_k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Формулы метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{l}&lt;br /&gt;
q_1 = b / \Vert b \Vert_2\\&lt;br /&gt;
j = \overline{1, k}:\\&lt;br /&gt;
\quad z_j = A q_j \\&lt;br /&gt;
\quad \alpha_j = q_j^T A q_j = q_j^T z_j \\&lt;br /&gt;
\quad z_j&#039; = z_j - \sum_{i=1}^j (z_j^T q_i) q_i \\&lt;br /&gt;
\quad z_j&#039;&#039; = z_j&#039; - \sum_{i=1}^j (z_j&#039;^T q_i) q_i\\&lt;br /&gt;
\quad \beta_j = \Vert z_j&#039;&#039; \Vert_2\\&lt;br /&gt;
\quad q_{j+1} = z_j&#039;&#039; / \Vert z_j&#039;&#039; \Vert_2 = z_j&#039;&#039;/\beta_j&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Собственные значения и собственные векторы матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; ищутся любым прямым алгоритмом.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;z_j&#039;, z_j&#039;&#039;&amp;lt;/math&amp;gt; — это полная переортогонализация &amp;lt;math&amp;gt;z_j&amp;lt;/math&amp;gt; методом Грама — Шмидта. Двойной запуск практически гарантирует, что &amp;lt;math&amp;gt;z_j&#039;&#039;&amp;lt;/math&amp;gt; будет ортогонален &amp;lt;math&amp;gt;q_1, \dots, q_j&amp;lt;/math&amp;gt;. Заметим, что &amp;lt;math&amp;gt;\sum_{i=1}^j (z^T q_i) q_i = Q_j Q_j^T z&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_j = [q_1, \dots, q_j]&amp;lt;/math&amp;gt;, поэтому переортогонализацию можно переписать в виде &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j, z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_j = 0&amp;lt;/math&amp;gt; для какого-либо &amp;lt;math&amp;gt;j &amp;lt; k&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\Vert T_{ju}\Vert_2 = 0&amp;lt;/math&amp;gt;, а значит, собственные значения &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; в точности совпадают с каким-то собственными значениями &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. В этом случае дальнейшие вычисления прекращаются и либо используется полученная &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; размерности меньшей, чем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, либо процедура запускается заново с другим начальным вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
У алгоритма построения матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; в том виде, как он описан выше, можно выделить два ядра:&lt;br /&gt;
# умножение матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на вектор &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;z_j = A q_j&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; умножений вещественных чисел);&lt;br /&gt;
# переортогонализация: &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j,\; z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(nk^2)&amp;lt;/math&amp;gt; умножений вещественных чисел).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
На макроуровне выделяем 3 основные операции:&lt;br /&gt;
&lt;br /&gt;
1. Умножение исходной матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на очередной вектор базиса &amp;lt;math&amp;gt;q_p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z=Aq_p. &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Повторное проведения процесса  Грамма-Шмидта  для ортогонализации посчитанного вектора &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt; со всеми построенными ранее векторами базиса.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i.      &amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
3.Непосредственное вычисление нового базисного вектора &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; и элементов &amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j&lt;br /&gt;
&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; \beta_{j+1}&lt;br /&gt;
&amp;lt;/math&amp;gt;  трехдиагональной матрицы.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j=q_j^Tz,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{j+1}=z/\beta_{j+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;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; q_1=b/||b||,\\&lt;br /&gt;
&amp;amp; \beta_1=0,\\&lt;br /&gt;
&amp;amp;q_0=0, \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&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;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&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;&lt;br /&gt;
1.z=Aq_j, &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j}&amp;lt;/math&amp;gt; конечной матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
2.\alpha_j=q_j^Tz,&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;&lt;br /&gt;
3.z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;4.z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,      &amp;lt;/math&amp;gt; &lt;br /&gt;
  &lt;br /&gt;
После ортогонализации процедура продолжается следующим образом.                      &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;5.z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j+1}&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;t_{j+1,j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;6.\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_{j+1}=0&amp;lt;/math&amp;gt;, то алгоритм завершается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;7.q_{j+1}=z/\beta_{j+1}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В конце каждой итерации получаем очередной вектор &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; базиса с единичной нормой, который ортогонален всем предыдущим векторам базиса,&lt;br /&gt;
&lt;br /&gt;
и элементы &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\beta_{j+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;
На &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ой итерации алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2 + n + 4nj + n + n = n^2 + 3n + 4nj&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;n(n - 1) + (n - 1) + (4n - 2)j + (n - 1) = n^2 + (n - 2) + (4n - 2)j&amp;lt;/math&amp;gt; сложений и вычитаний;&lt;br /&gt;
* одно извлечение квадратного корня.&lt;br /&gt;
&lt;br /&gt;
Всего за &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; итераций алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;(n + 3)nk + 2nk(k + 1)&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;(n^2 + n - 2)k + (2n - 1)k(k + 1)&amp;lt;/math&amp;gt; сложений и вычитаний.&lt;br /&gt;
&lt;br /&gt;
Таким образом, алгоритм имеет последовательную сложность &amp;lt;math&amp;gt;O(n^2k + nk^2)&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;
[[Файл:Lanczoc-full-orth-macro.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 1. Информационный граф алгоритма Ланцоша на уровне итераций с входными и выходными данными. In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и вектор &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), nrm — вычисление еклидовой нормы вектора, / — деление вектора на число, Iter — итерации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Информационный граф на уровне одной итерации с входными и выходными данными====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Lanczoc-full-orth-iter.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 2. Информационный граф итерации алгоритма Ланцоша на уровне макроопераций (первые три итерации). In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), dprod — скалярное произведение векторов, mprod — произведение матрицы на вектор, - — разность векторов, nrm — вычисление еклидовой нормы вектора, / — деление вектора на число.]]&lt;br /&gt;
&lt;br /&gt;
====Общий информационный граф алгроитма====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:photo.jpg|thumb|center|alt=Общий информационный граф алгроитма Ланцоша|Рисунок 3. Общий информационный граф алгроитма алгоритма Ланцоша.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Вершина черного цвета соответствует операции  &amp;lt;math&amp;gt;Aq_j,&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина красного цвета соответствует операции скалярного произведения &amp;lt;math&amp;gt;q_j^Tz&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина сиреневого цвета соответствует операции &amp;lt;math&amp;gt;z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина желтого цвета соответствует операции &amp;lt;math&amp;gt;z-\alpha_jq_j-\beta_{j-1}q_{j-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина синего цвета соответствует операции &amp;lt;math&amp;gt;||z||&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина зеленого цвета соответствует операции &amp;lt;math&amp;gt;z/\beta_j&amp;lt;/math&amp;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;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операциями умножения в каждом (вычисление &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операцией умножения в каждом (вычисление &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;j&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; ярусов сложений с &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;n&amp;lt;/math&amp;gt; (первая переортогонализация);&lt;br /&gt;
# &amp;lt;math&amp;gt;j&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; ярусов сложений с &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;n&amp;lt;/math&amp;gt; (вторая переортогонализация);&lt;br /&gt;
# &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операцией умножения в каждом (вычисление &amp;lt;math&amp;gt;\beta_j&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; ярус делений размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (вычисление &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Итого ширина ЯПФ одной итерации составляет &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, высота — &amp;lt;math&amp;gt;4n + 2j + 3&amp;lt;/math&amp;gt;. Ширина ЯПФ всего алгоритма составляет &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, высота — &amp;lt;math&amp;gt;O(nk + k^2)&amp;lt;/math&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;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;),произвольный вектор ненулевой &amp;lt;math&amp;gt;b&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;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; – симметрическая матрица, т. е. &amp;lt;math&amp;gt;a_{ij}= a_{ji}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;..&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 3)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: трехдиагональная симметрическая матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;_{ij}&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; размерности &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2k&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;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных равняется  &amp;lt;math&amp;gt;O(k)&amp;lt;/math&amp;gt;. Алгоритм недетерминированный, так как если в какой-то итерации &amp;lt;math&amp;gt;b_j=0&amp;lt;/math&amp;gt;, то алгоритм останавливается. Также на недетерминированность может повлиять изменение порядка выполнения ассоциативных операций, в частности при вычислении скалярного произведения. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Длинных&amp;quot; дуг в информационном графе нет,  запись данных происходит предсказуемо(на каждом шаге заполняются следующие элементы выходных векторов), следовательно нет никаких потенциальных сложностей с размещением данных в иерархии памяти компьютера на этапе выполнения программы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Первое исследование масштабируемости проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
Набор изменяемых параметров запуска реализации алгоритма и границы значений параметров алгоритма:&lt;br /&gt;
*Число процессоров &amp;lt;math&amp;gt;1,2,4,8,16,32,48&amp;lt;/math&amp;gt;&lt;br /&gt;
*Размерность матрицы &amp;lt;math&amp;gt;[1000:16000]&amp;lt;/math&amp;gt;&lt;br /&gt;
*Количество итераций &amp;lt;math&amp;gt;10&amp;lt;/math&amp;gt;&lt;br /&gt;
Использовался компилятор g++ версии 5.4.0 с параметрами запуска: &lt;br /&gt;
*-fopenmp &lt;br /&gt;
*-std=c++11&lt;br /&gt;
Реализация алгоритма написана с использованием  стандарта OpenMP.&lt;br /&gt;
[[Файл:just2.png|thumb|center|1024px|Рисунок 4. Зависимость производительности от числа процессов и размера входной матрицы]]&lt;br /&gt;
[http://pastebin.com/iurnjf8f Используемая параллельная реализация алгоритма на языке C++]&lt;br /&gt;
&lt;br /&gt;
Как видно из графика, размер задачи не оказывает существенного влияния на производительность. С увеличением количества процессоров производительность сначала возрастает, затем  медленно убывает. Высокая производительность достигается  при работе 20-30 процессоров,  при дальнейшем увеличении числа процессоров накладные расходы на организацию параллельного вычисления ведут к уменьшению производительности.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Следующее исследование масштабируемости реализации алгоритма проводилось с использованием стандарта MPI на суперкомпьютере &amp;quot;Ломоносов&amp;quot; суперкомпьютерного комплекса Московского университета.&lt;br /&gt;
&lt;br /&gt;
Набор изменяемых параметров запуска реализации алгоритма и границы значений параметров алгоритма:&lt;br /&gt;
*Число процессоров &amp;lt;math&amp;gt;1,2,4,8,16,32,64,96,128&amp;lt;/math&amp;gt;&lt;br /&gt;
*Размерность матрицы &amp;lt;math&amp;gt; 1000:15000,1700,21000,25000,30000&amp;lt;/math&amp;gt;&lt;br /&gt;
*Количество итераций &amp;lt;math&amp;gt;500&amp;lt;/math&amp;gt;&lt;br /&gt;
Сборка осуществлялась с параметрами: &lt;br /&gt;
*openmpi/1.5.5-icc&lt;br /&gt;
*intel/13.1.0&lt;br /&gt;
[[Файл:just5.png|thumb|center|1024px|Рисунок 4. Зависимость производительности от числа процессов и размера входной матрицы]]&lt;br /&gt;
[[Файл:just6.png|thumb|center|1024px|Рисунок 4. Зависимость времени выполнения от числа процессов и размера входной матрицы]]&lt;br /&gt;
[http://pastebin.com/5id6w9is  Используемая параллельная реализация алгоритма на языке C++]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов производительность возрастает  на всей рассмотренной области изменений параметров запуска. Увеличение размера задачи так же повышает производительность   в рассматриваемой области, как и при увеличении количества  процессоров, но при размерах задачи больше 25000 наблюдается медленный спад. Это снижение производительности объясняется тем, что при увеличении размера задачи существенно возрастают объемы передаваемых данных между процессами.&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
NAG Library имеет множество процедур для решения система алгебраических уравнений и нахождения собственных значений, которые используют алгоритм Ланцоша.&lt;br /&gt;
&lt;br /&gt;
http://www.nag.com/content/nag-library C, C++, Fortran, C#, MATLAB, R.&lt;br /&gt;
&lt;br /&gt;
MATLAB содержит реализацию алгоритма в пакете  Gaussian Belief Propagation Matlab Package.&lt;br /&gt;
&lt;br /&gt;
http://www.cs.cmu.edu/~bickson/gabp/.&lt;br /&gt;
 &lt;br /&gt;
GraphLab имеет библиотеку, в которой есть огромное количество параллельных реализаций алгоритма Ланцоша &lt;br /&gt;
        &lt;br /&gt;
https://turi.com/products/create/open_source.html C++.&lt;br /&gt;
&lt;br /&gt;
В LANSO/PLANSO есть параллельная версия алгоритма&lt;br /&gt;
&lt;br /&gt;
http://web.cs.ucdavis.edu/~bai/ET/lanczos_methods/overview_PLANSO.html Fortran.&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22592</id>
		<title>Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22592"/>
		<updated>2017-05-03T13:35:08Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Sagak|С.А.Айвазян]], [[Участник:Kozlov_Vladimir|В.Козлов]] (Часть 1), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (компоновка и редактирование), [[Участник:ASA|А.С.Антонов]] (предварительная проверка).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
Алгоритм  Ланцоша – итерационный метод , созданный Корнелиусом Ланцошем, для нахождения собственных значений и собственных векторов симметричной матрицы. Суть алгоритма в том, что он сводит частичную проблему собственных значений симметричной вещественной матрицы  к полной проблеме собственных значений для симметричной трехдиагональной матрицы  меньшей размерности. Алгоритм применяется  к матрицам большой размерности, к которым не применимы никакие прямые методы. &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;QR&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;QL&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; — это итерационный алгоритм поиска &amp;lt;math&amp;gt;k&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;. Алгоритм применяется, когда матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; слишком велика, чтобы к ней можно было применять точные прямые методы вычисления собственных значений. Алгоритм комбинирует &#039;&#039;&#039;метод Рэлея — Ритца&#039;&#039;&#039; поиска приближённых собственных значений и &#039;&#039;&#039;метод Ланцоша&#039;&#039;&#039; построения крыловского подпространства.&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца является методом поиска &amp;lt;math&amp;gt;k&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;. Если &amp;lt;math&amp;gt;Q = [Q_k, Q_u]&amp;lt;/math&amp;gt; — ортонормированная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_k&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_u&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times n - k&amp;lt;/math&amp;gt;, то можно записать равенство&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;T = Q^T A Q = [Q_k, Q_u]^T A [Q_k, Q_u] = &lt;br /&gt;
\left[ \begin{array}{cc}&lt;br /&gt;
Q_k^T A Q_k &amp;amp; Q_k^T A Q_u\\&lt;br /&gt;
Q_u^T A Q_k &amp;amp; Q_u^T A Q_u&lt;br /&gt;
\end{array} \right]&lt;br /&gt;
= \left[ \begin{array}{cc}&lt;br /&gt;
T_{k} &amp;amp; T_{ku}^T\\&lt;br /&gt;
T_{ku} &amp;amp; T_{u}&lt;br /&gt;
\end{array} \right].&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца заключается в том, что собственные значения матрицы &amp;lt;math&amp;gt;T_k = Q_k^T A Q_k&amp;lt;/math&amp;gt; объявляются приближёнными собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Такое приближение является в некотором смысле «наилучшим»: можно показать, что если &amp;lt;math&amp;gt;T_k = V \Lambda V^{-1}&amp;lt;/math&amp;gt; — спектральное разложение &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;, то пара &amp;lt;math&amp;gt;(Q_k V, \Lambda)&amp;lt;/math&amp;gt; минимизирует функционал &amp;lt;math&amp;gt;L(P_k, D) = \Vert A P_k - P_k D \Vert_2&amp;lt;/math&amp;gt;, причём &amp;lt;math&amp;gt;L(Q_k V, \Lambda) = \Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;, то есть &amp;lt;math&amp;gt;A \approx (Q_k V) \Lambda (Q_k V)^{-1}&amp;lt;/math&amp;gt;. Из этого также видно, что метод Рэлея — Ритца позволяет получать приближения для собственных векторов матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Более того, можно показать, что собственные значения &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; отличаются от некоторых собственных значений &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не более чем на &amp;lt;math&amp;gt;\Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Метод Ланцоша — это метод построения матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, при использовании которого, во-первых, матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; оказывается симметричной трёхдиагональной, во-вторых, столбцы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются последовательно. Трёхдиагональность &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; приводит к следующим явлениям:&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; является трёхдиагональной матрицей меньшей размерности, а для трёхдиагональных матриц существуют высокоэффективные методы поиска собственных значений;&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_{ku}&amp;lt;/math&amp;gt; имеет только один ненулевой (возможно) элемент — правый верхний, а значит, для оценки погрешности полученных собственных значений достаточно знать только этот элемент.&lt;br /&gt;
&lt;br /&gt;
В теории в методе Ланцоша для вычисления каждого следующего столбца &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; достаточно знать только &amp;lt;math&amp;gt;q_{j - 1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_{j}&amp;lt;/math&amp;gt; в силу трёхдиагональности матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;. На практике из-за ошибок округления, если не предпринимать специальных мер, набор векторов &amp;lt;math&amp;gt;q_{1}, \dots, q_{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;b&amp;lt;/math&amp;gt; — начальное приближение для метода Ланцоша.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: трёхдиагональная симметричная вещественная матрица &amp;lt;math&amp;gt;T_k = \left[ \begin{array}{cccc}&lt;br /&gt;
\alpha_1 &amp;amp; \beta_1 &amp;amp; &amp;amp; \\&lt;br /&gt;
\beta_1 &amp;amp; \ddots &amp;amp; \ddots &amp;amp; \\&lt;br /&gt;
&amp;amp; \ddots &amp;amp; \ddots &amp;amp; \beta_{k - 1}\\&lt;br /&gt;
&amp;amp; &amp;amp; \beta_{k - 1} &amp;amp; \alpha_k&lt;br /&gt;
\end{array} \right]&amp;lt;/math&amp;gt;, ортонормированный набор векторов &amp;lt;math&amp;gt;q_1, \dots, q_k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;T_k = [q_1, \dots, q_k]^T A [q_1, \dots, q_k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Формулы метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{l}&lt;br /&gt;
q_1 = b / \Vert b \Vert_2\\&lt;br /&gt;
j = \overline{1, k}:\\&lt;br /&gt;
\quad z_j = A q_j \\&lt;br /&gt;
\quad \alpha_j = q_j^T A q_j = q_j^T z_j \\&lt;br /&gt;
\quad z_j&#039; = z_j - \sum_{i=1}^j (z_j^T q_i) q_i \\&lt;br /&gt;
\quad z_j&#039;&#039; = z_j&#039; - \sum_{i=1}^j (z_j&#039;^T q_i) q_i\\&lt;br /&gt;
\quad \beta_j = \Vert z_j&#039;&#039; \Vert_2\\&lt;br /&gt;
\quad q_{j+1} = z_j&#039;&#039; / \Vert z_j&#039;&#039; \Vert_2 = z_j&#039;&#039;/\beta_j&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Собственные значения и собственные векторы матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; ищутся любым прямым алгоритмом.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;z_j&#039;, z_j&#039;&#039;&amp;lt;/math&amp;gt; — это полная переортогонализация &amp;lt;math&amp;gt;z_j&amp;lt;/math&amp;gt; методом Грама — Шмидта. Двойной запуск практически гарантирует, что &amp;lt;math&amp;gt;z_j&#039;&#039;&amp;lt;/math&amp;gt; будет ортогонален &amp;lt;math&amp;gt;q_1, \dots, q_j&amp;lt;/math&amp;gt;. Заметим, что &amp;lt;math&amp;gt;\sum_{i=1}^j (z^T q_i) q_i = Q_j Q_j^T z&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_j = [q_1, \dots, q_j]&amp;lt;/math&amp;gt;, поэтому переортогонализацию можно переписать в виде &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j, z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_j = 0&amp;lt;/math&amp;gt; для какого-либо &amp;lt;math&amp;gt;j &amp;lt; k&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\Vert T_{ju}\Vert_2 = 0&amp;lt;/math&amp;gt;, а значит, собственные значения &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; в точности совпадают с каким-то собственными значениями &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. В этом случае дальнейшие вычисления прекращаются и либо используется полученная &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; размерности меньшей, чем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, либо процедура запускается заново с другим начальным вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
У алгоритма построения матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; в том виде, как он описан выше, можно выделить два ядра:&lt;br /&gt;
# умножение матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на вектор &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;z_j = A q_j&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; умножений вещественных чисел);&lt;br /&gt;
# переортогонализация: &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j,\; z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(nk^2)&amp;lt;/math&amp;gt; умножений вещественных чисел).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
На макроуровне выделяем 3 основные операции:&lt;br /&gt;
&lt;br /&gt;
1. Умножение исходной матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на очередной вектор базиса &amp;lt;math&amp;gt;q_p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z=Aq_p. &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Повторное проведения процесса  Грамма-Шмидта  для ортогонализации посчитанного вектора &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt; со всеми построенными ранее векторами базиса.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i.      &amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
3.Непосредственное вычисление нового базисного вектора &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; и элементов &amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j&lt;br /&gt;
&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; \beta_{j+1}&lt;br /&gt;
&amp;lt;/math&amp;gt;  трехдиагональной матрицы.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j=q_j^Tz,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{j+1}=z/\beta_{j+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;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; q_1=b/||b||,\\&lt;br /&gt;
&amp;amp; \beta_1=0,\\&lt;br /&gt;
&amp;amp;q_0=0, \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&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;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&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;&lt;br /&gt;
1.z=Aq_j, &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j}&amp;lt;/math&amp;gt; конечной матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
2.\alpha_j=q_j^Tz,&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;&lt;br /&gt;
3.z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;4.z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,      &amp;lt;/math&amp;gt; &lt;br /&gt;
  &lt;br /&gt;
После ортогонализации процедура продолжается следующим образом.                      &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;5.z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j+1}&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;t_{j+1,j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;6.\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_{j+1}=0&amp;lt;/math&amp;gt;, то алгоритм завершается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;7.q_{j+1}=z/\beta_{j+1}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В конце каждой итерации получаем очередной вектор &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; базиса с единичной нормой, который ортогонален всем предыдущим векторам базиса,&lt;br /&gt;
&lt;br /&gt;
и элементы &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\beta_{j+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;
На &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ой итерации алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2 + n + 4nj + n + n = n^2 + 3n + 4nj&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;n(n - 1) + (n - 1) + (4n - 2)j + (n - 1) = n^2 + (n - 2) + (4n - 2)j&amp;lt;/math&amp;gt; сложений и вычитаний;&lt;br /&gt;
* одно извлечение квадратного корня.&lt;br /&gt;
&lt;br /&gt;
Всего за &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; итераций алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;(n + 3)nk + 2nk(k + 1)&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;(n^2 + n - 2)k + (2n - 1)k(k + 1)&amp;lt;/math&amp;gt; сложений и вычитаний.&lt;br /&gt;
&lt;br /&gt;
Таким образом, алгоритм имеет последовательную сложность &amp;lt;math&amp;gt;O(n^2k + nk^2)&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;
[[Файл:Lanczoc-full-orth-macro.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 1. Информационный граф алгоритма Ланцоша на уровне итераций с входными и выходными данными. In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и вектор &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), nrm — вычисление еклидовой нормы вектора, / — деление вектора на число, Iter — итерации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Информационный граф на уровне одной итерации с входными и выходными данными====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Lanczoc-full-orth-iter.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 2. Информационный граф итерации алгоритма Ланцоша на уровне макроопераций (первые три итерации). In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), dprod — скалярное произведение векторов, mprod — произведение матрицы на вектор, - — разность векторов, nrm — вычисление еклидовой нормы вектора, / — деление вектора на число.]]&lt;br /&gt;
&lt;br /&gt;
====Общий информационный граф алгроитма====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:photo.jpg|thumb|center|alt=Общий информационный граф алгроитма Ланцоша|Рисунок 3. Общий информационный граф алгроитма алгоритма Ланцоша.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Вершина черного цвета соответствует операции  &amp;lt;math&amp;gt;Aq_j,&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина красного цвета соответствует операции скалярного произведения &amp;lt;math&amp;gt;q_j^Tz&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина сиреневого цвета соответствует операции &amp;lt;math&amp;gt;z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина желтого цвета соответствует операции &amp;lt;math&amp;gt;z-\alpha_jq_j-\beta_{j-1}q_{j-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина синего цвета соответствует операции &amp;lt;math&amp;gt;||z||&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина зеленого цвета соответствует операции &amp;lt;math&amp;gt;z/\beta_j&amp;lt;/math&amp;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;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операциями умножения в каждом (вычисление &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операцией умножения в каждом (вычисление &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;j&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; ярусов сложений с &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;n&amp;lt;/math&amp;gt; (первая переортогонализация);&lt;br /&gt;
# &amp;lt;math&amp;gt;j&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; ярусов сложений с &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;n&amp;lt;/math&amp;gt; (вторая переортогонализация);&lt;br /&gt;
# &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операцией умножения в каждом (вычисление &amp;lt;math&amp;gt;\beta_j&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; ярус делений размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (вычисление &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Итого ширина ЯПФ одной итерации составляет &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, высота — &amp;lt;math&amp;gt;4n + 2j + 3&amp;lt;/math&amp;gt;. Ширина ЯПФ всего алгоритма составляет &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, высота — &amp;lt;math&amp;gt;O(nk + k^2)&amp;lt;/math&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;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;),произвольный вектор ненулевой &amp;lt;math&amp;gt;b&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;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; – симметрическая матрица, т. е. &amp;lt;math&amp;gt;a_{ij}= a_{ji}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;..&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 3)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: трехдиагональная симметрическая матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;_{ij}&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; размерности &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2k&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;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных равняется  &amp;lt;math&amp;gt;O(k)&amp;lt;/math&amp;gt;. Алгоритм недетерминированный, так как если в какой-то итерации &amp;lt;math&amp;gt;b_j=0&amp;lt;/math&amp;gt;, то алгоритм останавливается. Также на недетерминированность может повлиять изменение порядка выполнения ассоциативных операций, в частности при вычислении скалярного произведения. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Длинных&amp;quot; дуг в информационном графе нет,  запись данных происходит предсказуемо(на каждом шаге заполняются следующие элементы выходных векторов), следовательно нет никаких потенциальных сложностей с размещением данных в иерархии памяти компьютера на этапе выполнения программы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Первое исследование масштабируемости проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
Набор изменяемых параметров запуска реализации алгоритма и границы значений параметров алгоритма:&lt;br /&gt;
*Число процессоров &amp;lt;math&amp;gt;1,2,4,8,16,32,48&amp;lt;/math&amp;gt;&lt;br /&gt;
*Размерность матрицы &amp;lt;math&amp;gt;[1000:16000]&amp;lt;/math&amp;gt;&lt;br /&gt;
*Количество итераций &amp;lt;math&amp;gt;10&amp;lt;/math&amp;gt;&lt;br /&gt;
Использовался компилятор g++ версии 5.4.0 с параметрами запуска: &lt;br /&gt;
*-fopenmp &lt;br /&gt;
*-std=c++11&lt;br /&gt;
Реализация алгоритма написана с использованием  стандарта OpenMP.&lt;br /&gt;
[[Файл:just2.png|thumb|center|1024px|Рисунок 4. Зависимость производительности от числа процессов и размера входной матрицы]]&lt;br /&gt;
[http://pastebin.com/iurnjf8f Используемая параллельная реализация алгоритма на языке C++]&lt;br /&gt;
&lt;br /&gt;
Как видно из графика, размер задачи не оказывает существенного влияния на производительность. С увеличением количества процессоров производительность сначала возрастает, затем  медленно убывает. Высокая производительность достигается  при работе 20-30 процессоров,  при дальнейшем увеличении числа процессоров накладные расходы на организацию параллельного вычисления ведут к уменьшению производительности.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Следующее исследование масштабируемости реализации алгоритма проводилось с использованием стандарта MPI на суперкомпьютере &amp;quot;Ломоносов&amp;quot; суперкомпьютерного комплекса Московского университета.&lt;br /&gt;
&lt;br /&gt;
Набор изменяемых параметров запуска реализации алгоритма и границы значений параметров алгоритма:&lt;br /&gt;
*Число процессоров &amp;lt;math&amp;gt;1,2,4,8,16,32,64,96,128&amp;lt;/math&amp;gt;&lt;br /&gt;
*Размерность матрицы &amp;lt;math&amp;gt; 1000:15000,1700,21000,25000,30000&amp;lt;/math&amp;gt;&lt;br /&gt;
*Количество итераций &amp;lt;math&amp;gt;500&amp;lt;/math&amp;gt;&lt;br /&gt;
Сборка осуществлялась с параметрами: &lt;br /&gt;
*openmpi/1.5.5-icc&lt;br /&gt;
*intel/13.1.0&lt;br /&gt;
[[Файл:just5.png|thumb|center|1024px|Рисунок 4. Зависимость производительности от числа процессов и размера входной матрицы]]&lt;br /&gt;
[[Файл:just6.png|thumb|center|1024px|Рисунок 4. Зависимость времени выполнения от числа процессов и размера входной матрицы]]&lt;br /&gt;
[http://pastebin.com/5id6w9is  Используемая параллельная реализация алгоритма на языке C++]&lt;br /&gt;
&lt;br /&gt;
При увеличении числа процессов производительность возрастает  на всей рассмотренной области изменений параметров запуска. Увеличение размера задачи так же повышает производительность   в рассматриваемой области, как и при увеличении количества  процессоров, но при размерах задачи больше 25000 наблюдается медленный спад. Это снижение производительности объясняется тем, что при увеличении размера задачи существенно возрастают объемы передаваемых данных между процессами.&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
NAG Library имеет множество процедур для решения система алгебраических уравнений и нахождения собственных значений, которые используют алгоритм Ланцоша.&lt;br /&gt;
&lt;br /&gt;
http://www.nag.com/content/nag-library C, C++, Fortran, C#, MATLAB, R.&lt;br /&gt;
&lt;br /&gt;
MATLAB содержит реализацию алгоритма в пакете  Gaussian Belief Propagation Matlab Package.&lt;br /&gt;
&lt;br /&gt;
http://www.cs.cmu.edu/~bickson/gabp/.&lt;br /&gt;
 &lt;br /&gt;
GraphLab имеет библиотеку, в которой есть огромное количество параллельных реализаций алгоритма Ланцоша &lt;br /&gt;
        &lt;br /&gt;
https://turi.com/products/create/open_source.html C++.&lt;br /&gt;
&lt;br /&gt;
В LANSO/PLANSO есть параллельная версия алгоритма&lt;br /&gt;
&lt;br /&gt;
http://web.cs.ucdavis.edu/~bai/ET/lanczos_methods/overview_PLANSO.html Fortran.&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22591</id>
		<title>Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22591"/>
		<updated>2017-05-03T13:33:55Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Sagak|С.А.Айвазян]], [[Участник:Kozlov_Vladimir|В.Козлов]] (Часть 1), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (компоновка и редактирование), [[Участник:ASA|А.С.Антонов]] (предварительная проверка).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
Алгоритм  Ланцоша – итерационный метод , созданный Корнелиусом Ланцошем, для нахождения собственных значений и собственных векторов симметричной матрицы. Суть алгоритма в том, что он сводит частичную проблему собственных значений симметричной вещественной матрицы  к полной проблеме собственных значений для симметричной трехдиагональной матрицы  меньшей размерности. Алгоритм применяется  к матрицам большой размерности, к которым не применимы никакие прямые методы. &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;QR&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;QL&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; — это итерационный алгоритм поиска &amp;lt;math&amp;gt;k&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;. Алгоритм применяется, когда матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; слишком велика, чтобы к ней можно было применять точные прямые методы вычисления собственных значений. Алгоритм комбинирует &#039;&#039;&#039;метод Рэлея — Ритца&#039;&#039;&#039; поиска приближённых собственных значений и &#039;&#039;&#039;метод Ланцоша&#039;&#039;&#039; построения крыловского подпространства.&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца является методом поиска &amp;lt;math&amp;gt;k&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;. Если &amp;lt;math&amp;gt;Q = [Q_k, Q_u]&amp;lt;/math&amp;gt; — ортонормированная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_k&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_u&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times n - k&amp;lt;/math&amp;gt;, то можно записать равенство&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;T = Q^T A Q = [Q_k, Q_u]^T A [Q_k, Q_u] = &lt;br /&gt;
\left[ \begin{array}{cc}&lt;br /&gt;
Q_k^T A Q_k &amp;amp; Q_k^T A Q_u\\&lt;br /&gt;
Q_u^T A Q_k &amp;amp; Q_u^T A Q_u&lt;br /&gt;
\end{array} \right]&lt;br /&gt;
= \left[ \begin{array}{cc}&lt;br /&gt;
T_{k} &amp;amp; T_{ku}^T\\&lt;br /&gt;
T_{ku} &amp;amp; T_{u}&lt;br /&gt;
\end{array} \right].&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца заключается в том, что собственные значения матрицы &amp;lt;math&amp;gt;T_k = Q_k^T A Q_k&amp;lt;/math&amp;gt; объявляются приближёнными собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Такое приближение является в некотором смысле «наилучшим»: можно показать, что если &amp;lt;math&amp;gt;T_k = V \Lambda V^{-1}&amp;lt;/math&amp;gt; — спектральное разложение &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;, то пара &amp;lt;math&amp;gt;(Q_k V, \Lambda)&amp;lt;/math&amp;gt; минимизирует функционал &amp;lt;math&amp;gt;L(P_k, D) = \Vert A P_k - P_k D \Vert_2&amp;lt;/math&amp;gt;, причём &amp;lt;math&amp;gt;L(Q_k V, \Lambda) = \Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;, то есть &amp;lt;math&amp;gt;A \approx (Q_k V) \Lambda (Q_k V)^{-1}&amp;lt;/math&amp;gt;. Из этого также видно, что метод Рэлея — Ритца позволяет получать приближения для собственных векторов матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Более того, можно показать, что собственные значения &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; отличаются от некоторых собственных значений &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не более чем на &amp;lt;math&amp;gt;\Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Метод Ланцоша — это метод построения матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, при использовании которого, во-первых, матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; оказывается симметричной трёхдиагональной, во-вторых, столбцы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются последовательно. Трёхдиагональность &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; приводит к следующим явлениям:&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; является трёхдиагональной матрицей меньшей размерности, а для трёхдиагональных матриц существуют высокоэффективные методы поиска собственных значений;&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_{ku}&amp;lt;/math&amp;gt; имеет только один ненулевой (возможно) элемент — правый верхний, а значит, для оценки погрешности полученных собственных значений достаточно знать только этот элемент.&lt;br /&gt;
&lt;br /&gt;
В теории в методе Ланцоша для вычисления каждого следующего столбца &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; достаточно знать только &amp;lt;math&amp;gt;q_{j - 1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_{j}&amp;lt;/math&amp;gt; в силу трёхдиагональности матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;. На практике из-за ошибок округления, если не предпринимать специальных мер, набор векторов &amp;lt;math&amp;gt;q_{1}, \dots, q_{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;b&amp;lt;/math&amp;gt; — начальное приближение для метода Ланцоша.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: трёхдиагональная симметричная вещественная матрица &amp;lt;math&amp;gt;T_k = \left[ \begin{array}{cccc}&lt;br /&gt;
\alpha_1 &amp;amp; \beta_1 &amp;amp; &amp;amp; \\&lt;br /&gt;
\beta_1 &amp;amp; \ddots &amp;amp; \ddots &amp;amp; \\&lt;br /&gt;
&amp;amp; \ddots &amp;amp; \ddots &amp;amp; \beta_{k - 1}\\&lt;br /&gt;
&amp;amp; &amp;amp; \beta_{k - 1} &amp;amp; \alpha_k&lt;br /&gt;
\end{array} \right]&amp;lt;/math&amp;gt;, ортонормированный набор векторов &amp;lt;math&amp;gt;q_1, \dots, q_k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;T_k = [q_1, \dots, q_k]^T A [q_1, \dots, q_k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Формулы метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{l}&lt;br /&gt;
q_1 = b / \Vert b \Vert_2\\&lt;br /&gt;
j = \overline{1, k}:\\&lt;br /&gt;
\quad z_j = A q_j \\&lt;br /&gt;
\quad \alpha_j = q_j^T A q_j = q_j^T z_j \\&lt;br /&gt;
\quad z_j&#039; = z_j - \sum_{i=1}^j (z_j^T q_i) q_i \\&lt;br /&gt;
\quad z_j&#039;&#039; = z_j&#039; - \sum_{i=1}^j (z_j&#039;^T q_i) q_i\\&lt;br /&gt;
\quad \beta_j = \Vert z_j&#039;&#039; \Vert_2\\&lt;br /&gt;
\quad q_{j+1} = z_j&#039;&#039; / \Vert z_j&#039;&#039; \Vert_2 = z_j&#039;&#039;/\beta_j&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Собственные значения и собственные векторы матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; ищутся любым прямым алгоритмом.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;z_j&#039;, z_j&#039;&#039;&amp;lt;/math&amp;gt; — это полная переортогонализация &amp;lt;math&amp;gt;z_j&amp;lt;/math&amp;gt; методом Грама — Шмидта. Двойной запуск практически гарантирует, что &amp;lt;math&amp;gt;z_j&#039;&#039;&amp;lt;/math&amp;gt; будет ортогонален &amp;lt;math&amp;gt;q_1, \dots, q_j&amp;lt;/math&amp;gt;. Заметим, что &amp;lt;math&amp;gt;\sum_{i=1}^j (z^T q_i) q_i = Q_j Q_j^T z&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_j = [q_1, \dots, q_j]&amp;lt;/math&amp;gt;, поэтому переортогонализацию можно переписать в виде &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j, z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_j = 0&amp;lt;/math&amp;gt; для какого-либо &amp;lt;math&amp;gt;j &amp;lt; k&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\Vert T_{ju}\Vert_2 = 0&amp;lt;/math&amp;gt;, а значит, собственные значения &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; в точности совпадают с каким-то собственными значениями &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. В этом случае дальнейшие вычисления прекращаются и либо используется полученная &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; размерности меньшей, чем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, либо процедура запускается заново с другим начальным вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
У алгоритма построения матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; в том виде, как он описан выше, можно выделить два ядра:&lt;br /&gt;
# умножение матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на вектор &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;z_j = A q_j&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; умножений вещественных чисел);&lt;br /&gt;
# переортогонализация: &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j,\; z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(nk^2)&amp;lt;/math&amp;gt; умножений вещественных чисел).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
На макроуровне выделяем 3 основные операции:&lt;br /&gt;
&lt;br /&gt;
1. Умножение исходной матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на очередной вектор базиса &amp;lt;math&amp;gt;q_p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z=Aq_p. &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Повторное проведения процесса  Грамма-Шмидта  для ортогонализации посчитанного вектора &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt; со всеми построенными ранее векторами базиса.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i.      &amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
3.Непосредственное вычисление нового базисного вектора &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; и элементов &amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j&lt;br /&gt;
&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; \beta_{j+1}&lt;br /&gt;
&amp;lt;/math&amp;gt;  трехдиагональной матрицы.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j=q_j^Tz,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{j+1}=z/\beta_{j+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;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; q_1=b/||b||,\\&lt;br /&gt;
&amp;amp; \beta_1=0,\\&lt;br /&gt;
&amp;amp;q_0=0, \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&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;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&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;&lt;br /&gt;
1.z=Aq_j, &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j}&amp;lt;/math&amp;gt; конечной матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
2.\alpha_j=q_j^Tz,&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;&lt;br /&gt;
3.z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;4.z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,      &amp;lt;/math&amp;gt; &lt;br /&gt;
  &lt;br /&gt;
После ортогонализации процедура продолжается следующим образом.                      &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;5.z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j+1}&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;t_{j+1,j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;6.\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_{j+1}=0&amp;lt;/math&amp;gt;, то алгоритм завершается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;7.q_{j+1}=z/\beta_{j+1}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В конце каждой итерации получаем очередной вектор &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; базиса с единичной нормой, который ортогонален всем предыдущим векторам базиса,&lt;br /&gt;
&lt;br /&gt;
и элементы &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\beta_{j+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;
На &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ой итерации алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2 + n + 4nj + n + n = n^2 + 3n + 4nj&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;n(n - 1) + (n - 1) + (4n - 2)j + (n - 1) = n^2 + (n - 2) + (4n - 2)j&amp;lt;/math&amp;gt; сложений и вычитаний;&lt;br /&gt;
* одно извлечение квадратного корня.&lt;br /&gt;
&lt;br /&gt;
Всего за &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; итераций алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;(n + 3)nk + 2nk(k + 1)&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;(n^2 + n - 2)k + (2n - 1)k(k + 1)&amp;lt;/math&amp;gt; сложений и вычитаний.&lt;br /&gt;
&lt;br /&gt;
Таким образом, алгоритм имеет последовательную сложность &amp;lt;math&amp;gt;O(n^2k + nk^2)&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;
[[Файл:Lanczoc-full-orth-macro.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 1. Информационный граф алгоритма Ланцоша на уровне итераций с входными и выходными данными. In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и вектор &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), nrm — вычисление еклидовой нормы вектора, / — деление вектора на число, Iter — итерации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Информационный граф на уровне одной итерации с входными и выходными данными====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Lanczoc-full-orth-iter.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 2. Информационный граф итерации алгоритма Ланцоша на уровне макроопераций (первые три итерации). In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), dprod — скалярное произведение векторов, mprod — произведение матрицы на вектор, - — разность векторов, nrm — вычисление еклидовой нормы вектора, / — деление вектора на число.]]&lt;br /&gt;
&lt;br /&gt;
====Общий информационный граф алгроитма====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:photo.jpg|thumb|center|alt=Общий информационный граф алгроитма Ланцоша|Рисунок 3. Общий информационный граф алгроитма алгоритма Ланцоша.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Вершина черного цвета соответствует операции  &amp;lt;math&amp;gt;Aq_j,&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина красного цвета соответствует операции скалярного произведения &amp;lt;math&amp;gt;q_j^Tz&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина сиреневого цвета соответствует операции &amp;lt;math&amp;gt;z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина желтого цвета соответствует операции &amp;lt;math&amp;gt;z-\alpha_jq_j-\beta_{j-1}q_{j-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина синего цвета соответствует операции &amp;lt;math&amp;gt;||z||&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина зеленого цвета соответствует операции &amp;lt;math&amp;gt;z/\beta_j&amp;lt;/math&amp;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;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операциями умножения в каждом (вычисление &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операцией умножения в каждом (вычисление &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;j&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; ярусов сложений с &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;n&amp;lt;/math&amp;gt; (первая переортогонализация);&lt;br /&gt;
# &amp;lt;math&amp;gt;j&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; ярусов сложений с &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;n&amp;lt;/math&amp;gt; (вторая переортогонализация);&lt;br /&gt;
# &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операцией умножения в каждом (вычисление &amp;lt;math&amp;gt;\beta_j&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; ярус делений размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (вычисление &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Итого ширина ЯПФ одной итерации составляет &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, высота — &amp;lt;math&amp;gt;4n + 2j + 3&amp;lt;/math&amp;gt;. Ширина ЯПФ всего алгоритма составляет &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, высота — &amp;lt;math&amp;gt;O(nk + k^2)&amp;lt;/math&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;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;),произвольный вектор ненулевой &amp;lt;math&amp;gt;b&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;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; – симметрическая матрица, т. е. &amp;lt;math&amp;gt;a_{ij}= a_{ji}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;..&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 3)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: трехдиагональная симметрическая матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;_{ij}&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; размерности &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2k&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;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
При этом вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных равняется  &amp;lt;math&amp;gt;O(k)&amp;lt;/math&amp;gt;. Алгоритм недетерминированный, так как если в какой-то итерации &amp;lt;math&amp;gt;b_j=0&amp;lt;/math&amp;gt;, то алгоритм останавливается. Также на недетерминированность может повлиять изменение порядка выполнения ассоциативных операций, в частности при вычислении скалярного произведения. &lt;br /&gt;
&lt;br /&gt;
&amp;quot;Длинных&amp;quot; дуг в информационном графе нет,  запись данных происходит предсказуемо(на каждом шаге заполняются следующие элементы выходных векторов), следовательно нет никаких потенциальных сложностей с размещением данных в иерархии памяти компьютера на этапе выполнения программы.&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22590</id>
		<title>Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22590"/>
		<updated>2017-05-03T13:30:45Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Общий информационный граф алгроитма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Sagak|С.А.Айвазян]], [[Участник:Kozlov_Vladimir|В.Козлов]] (Часть 1), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (компоновка и редактирование), [[Участник:ASA|А.С.Антонов]] (предварительная проверка).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
Алгоритм  Ланцоша – итерационный метод , созданный Корнелиусом Ланцошем, для нахождения собственных значений и собственных векторов симметричной матрицы. Суть алгоритма в том, что он сводит частичную проблему собственных значений симметричной вещественной матрицы  к полной проблеме собственных значений для симметричной трехдиагональной матрицы  меньшей размерности. Алгоритм применяется  к матрицам большой размерности, к которым не применимы никакие прямые методы. &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;QR&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;QL&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; — это итерационный алгоритм поиска &amp;lt;math&amp;gt;k&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;. Алгоритм применяется, когда матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; слишком велика, чтобы к ней можно было применять точные прямые методы вычисления собственных значений. Алгоритм комбинирует &#039;&#039;&#039;метод Рэлея — Ритца&#039;&#039;&#039; поиска приближённых собственных значений и &#039;&#039;&#039;метод Ланцоша&#039;&#039;&#039; построения крыловского подпространства.&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца является методом поиска &amp;lt;math&amp;gt;k&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;. Если &amp;lt;math&amp;gt;Q = [Q_k, Q_u]&amp;lt;/math&amp;gt; — ортонормированная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_k&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_u&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times n - k&amp;lt;/math&amp;gt;, то можно записать равенство&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;T = Q^T A Q = [Q_k, Q_u]^T A [Q_k, Q_u] = &lt;br /&gt;
\left[ \begin{array}{cc}&lt;br /&gt;
Q_k^T A Q_k &amp;amp; Q_k^T A Q_u\\&lt;br /&gt;
Q_u^T A Q_k &amp;amp; Q_u^T A Q_u&lt;br /&gt;
\end{array} \right]&lt;br /&gt;
= \left[ \begin{array}{cc}&lt;br /&gt;
T_{k} &amp;amp; T_{ku}^T\\&lt;br /&gt;
T_{ku} &amp;amp; T_{u}&lt;br /&gt;
\end{array} \right].&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца заключается в том, что собственные значения матрицы &amp;lt;math&amp;gt;T_k = Q_k^T A Q_k&amp;lt;/math&amp;gt; объявляются приближёнными собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Такое приближение является в некотором смысле «наилучшим»: можно показать, что если &amp;lt;math&amp;gt;T_k = V \Lambda V^{-1}&amp;lt;/math&amp;gt; — спектральное разложение &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;, то пара &amp;lt;math&amp;gt;(Q_k V, \Lambda)&amp;lt;/math&amp;gt; минимизирует функционал &amp;lt;math&amp;gt;L(P_k, D) = \Vert A P_k - P_k D \Vert_2&amp;lt;/math&amp;gt;, причём &amp;lt;math&amp;gt;L(Q_k V, \Lambda) = \Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;, то есть &amp;lt;math&amp;gt;A \approx (Q_k V) \Lambda (Q_k V)^{-1}&amp;lt;/math&amp;gt;. Из этого также видно, что метод Рэлея — Ритца позволяет получать приближения для собственных векторов матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Более того, можно показать, что собственные значения &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; отличаются от некоторых собственных значений &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не более чем на &amp;lt;math&amp;gt;\Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Метод Ланцоша — это метод построения матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, при использовании которого, во-первых, матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; оказывается симметричной трёхдиагональной, во-вторых, столбцы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются последовательно. Трёхдиагональность &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; приводит к следующим явлениям:&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; является трёхдиагональной матрицей меньшей размерности, а для трёхдиагональных матриц существуют высокоэффективные методы поиска собственных значений;&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_{ku}&amp;lt;/math&amp;gt; имеет только один ненулевой (возможно) элемент — правый верхний, а значит, для оценки погрешности полученных собственных значений достаточно знать только этот элемент.&lt;br /&gt;
&lt;br /&gt;
В теории в методе Ланцоша для вычисления каждого следующего столбца &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; достаточно знать только &amp;lt;math&amp;gt;q_{j - 1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_{j}&amp;lt;/math&amp;gt; в силу трёхдиагональности матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;. На практике из-за ошибок округления, если не предпринимать специальных мер, набор векторов &amp;lt;math&amp;gt;q_{1}, \dots, q_{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;b&amp;lt;/math&amp;gt; — начальное приближение для метода Ланцоша.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: трёхдиагональная симметричная вещественная матрица &amp;lt;math&amp;gt;T_k = \left[ \begin{array}{cccc}&lt;br /&gt;
\alpha_1 &amp;amp; \beta_1 &amp;amp; &amp;amp; \\&lt;br /&gt;
\beta_1 &amp;amp; \ddots &amp;amp; \ddots &amp;amp; \\&lt;br /&gt;
&amp;amp; \ddots &amp;amp; \ddots &amp;amp; \beta_{k - 1}\\&lt;br /&gt;
&amp;amp; &amp;amp; \beta_{k - 1} &amp;amp; \alpha_k&lt;br /&gt;
\end{array} \right]&amp;lt;/math&amp;gt;, ортонормированный набор векторов &amp;lt;math&amp;gt;q_1, \dots, q_k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;T_k = [q_1, \dots, q_k]^T A [q_1, \dots, q_k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Формулы метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{l}&lt;br /&gt;
q_1 = b / \Vert b \Vert_2\\&lt;br /&gt;
j = \overline{1, k}:\\&lt;br /&gt;
\quad z_j = A q_j \\&lt;br /&gt;
\quad \alpha_j = q_j^T A q_j = q_j^T z_j \\&lt;br /&gt;
\quad z_j&#039; = z_j - \sum_{i=1}^j (z_j^T q_i) q_i \\&lt;br /&gt;
\quad z_j&#039;&#039; = z_j&#039; - \sum_{i=1}^j (z_j&#039;^T q_i) q_i\\&lt;br /&gt;
\quad \beta_j = \Vert z_j&#039;&#039; \Vert_2\\&lt;br /&gt;
\quad q_{j+1} = z_j&#039;&#039; / \Vert z_j&#039;&#039; \Vert_2 = z_j&#039;&#039;/\beta_j&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Собственные значения и собственные векторы матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; ищутся любым прямым алгоритмом.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;z_j&#039;, z_j&#039;&#039;&amp;lt;/math&amp;gt; — это полная переортогонализация &amp;lt;math&amp;gt;z_j&amp;lt;/math&amp;gt; методом Грама — Шмидта. Двойной запуск практически гарантирует, что &amp;lt;math&amp;gt;z_j&#039;&#039;&amp;lt;/math&amp;gt; будет ортогонален &amp;lt;math&amp;gt;q_1, \dots, q_j&amp;lt;/math&amp;gt;. Заметим, что &amp;lt;math&amp;gt;\sum_{i=1}^j (z^T q_i) q_i = Q_j Q_j^T z&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_j = [q_1, \dots, q_j]&amp;lt;/math&amp;gt;, поэтому переортогонализацию можно переписать в виде &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j, z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_j = 0&amp;lt;/math&amp;gt; для какого-либо &amp;lt;math&amp;gt;j &amp;lt; k&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\Vert T_{ju}\Vert_2 = 0&amp;lt;/math&amp;gt;, а значит, собственные значения &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; в точности совпадают с каким-то собственными значениями &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. В этом случае дальнейшие вычисления прекращаются и либо используется полученная &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; размерности меньшей, чем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, либо процедура запускается заново с другим начальным вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
У алгоритма построения матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; в том виде, как он описан выше, можно выделить два ядра:&lt;br /&gt;
# умножение матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на вектор &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;z_j = A q_j&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; умножений вещественных чисел);&lt;br /&gt;
# переортогонализация: &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j,\; z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(nk^2)&amp;lt;/math&amp;gt; умножений вещественных чисел).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
На макроуровне выделяем 3 основные операции:&lt;br /&gt;
&lt;br /&gt;
1. Умножение исходной матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на очередной вектор базиса &amp;lt;math&amp;gt;q_p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z=Aq_p. &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Повторное проведения процесса  Грамма-Шмидта  для ортогонализации посчитанного вектора &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt; со всеми построенными ранее векторами базиса.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i.      &amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
3.Непосредственное вычисление нового базисного вектора &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; и элементов &amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j&lt;br /&gt;
&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; \beta_{j+1}&lt;br /&gt;
&amp;lt;/math&amp;gt;  трехдиагональной матрицы.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j=q_j^Tz,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{j+1}=z/\beta_{j+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;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; q_1=b/||b||,\\&lt;br /&gt;
&amp;amp; \beta_1=0,\\&lt;br /&gt;
&amp;amp;q_0=0, \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&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;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&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;&lt;br /&gt;
1.z=Aq_j, &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j}&amp;lt;/math&amp;gt; конечной матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
2.\alpha_j=q_j^Tz,&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;&lt;br /&gt;
3.z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;4.z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,      &amp;lt;/math&amp;gt; &lt;br /&gt;
  &lt;br /&gt;
После ортогонализации процедура продолжается следующим образом.                      &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;5.z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j+1}&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;t_{j+1,j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;6.\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_{j+1}=0&amp;lt;/math&amp;gt;, то алгоритм завершается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;7.q_{j+1}=z/\beta_{j+1}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В конце каждой итерации получаем очередной вектор &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; базиса с единичной нормой, который ортогонален всем предыдущим векторам базиса,&lt;br /&gt;
&lt;br /&gt;
и элементы &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\beta_{j+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;
На &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ой итерации алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2 + n + 4nj + n + n = n^2 + 3n + 4nj&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;n(n - 1) + (n - 1) + (4n - 2)j + (n - 1) = n^2 + (n - 2) + (4n - 2)j&amp;lt;/math&amp;gt; сложений и вычитаний;&lt;br /&gt;
* одно извлечение квадратного корня.&lt;br /&gt;
&lt;br /&gt;
Всего за &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; итераций алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;(n + 3)nk + 2nk(k + 1)&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;(n^2 + n - 2)k + (2n - 1)k(k + 1)&amp;lt;/math&amp;gt; сложений и вычитаний.&lt;br /&gt;
&lt;br /&gt;
Таким образом, алгоритм имеет последовательную сложность &amp;lt;math&amp;gt;O(n^2k + nk^2)&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;
[[Файл:Lanczoc-full-orth-macro.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 1. Информационный граф алгоритма Ланцоша на уровне итераций с входными и выходными данными. In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и вектор &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), nrm — вычисление еклидовой нормы вектора, / — деление вектора на число, Iter — итерации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Информационный граф на уровне одной итерации с входными и выходными данными====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Lanczoc-full-orth-iter.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 2. Информационный граф итерации алгоритма Ланцоша на уровне макроопераций (первые три итерации). In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), dprod — скалярное произведение векторов, mprod — произведение матрицы на вектор, - — разность векторов, nrm — вычисление еклидовой нормы вектора, / — деление вектора на число.]]&lt;br /&gt;
&lt;br /&gt;
====Общий информационный граф алгроитма====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:photo.jpg|thumb|center|alt=Общий информационный граф алгроитма Ланцоша|Рисунок 3. Общий информационный граф алгроитма алгоритма Ланцоша.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Вершина черного цвета соответствует операции  &amp;lt;math&amp;gt;Aq_j,&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина красного цвета соответствует операции скалярного произведения &amp;lt;math&amp;gt;q_j^Tz&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина сиреневого цвета соответствует операции &amp;lt;math&amp;gt;z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина желтого цвета соответствует операции &amp;lt;math&amp;gt;z-\alpha_jq_j-\beta_{j-1}q_{j-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина синего цвета соответствует операции &amp;lt;math&amp;gt;||z||&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина зеленого цвета соответствует операции &amp;lt;math&amp;gt;z/\beta_j&amp;lt;/math&amp;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;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операциями умножения в каждом (вычисление &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операцией умножения в каждом (вычисление &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;j&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; ярусов сложений с &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;n&amp;lt;/math&amp;gt; (первая переортогонализация);&lt;br /&gt;
# &amp;lt;math&amp;gt;j&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; ярусов сложений с &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;n&amp;lt;/math&amp;gt; (вторая переортогонализация);&lt;br /&gt;
# &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операцией умножения в каждом (вычисление &amp;lt;math&amp;gt;\beta_j&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; ярус делений размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (вычисление &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Итого ширина ЯПФ одной итерации составляет &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, высота — &amp;lt;math&amp;gt;4n + 2j + 3&amp;lt;/math&amp;gt;. Ширина ЯПФ всего алгоритма составляет &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, высота — &amp;lt;math&amp;gt;O(nk + k^2)&amp;lt;/math&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;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;),произвольный вектор ненулевой &amp;lt;math&amp;gt;b&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;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; – симметрическая матрица, т. е. &amp;lt;math&amp;gt;a_{ij}= a_{ji}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;..&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 3)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: трехдиагональная симметрическая матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;_{ij}&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; размерности &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2k&amp;lt;/math&amp;gt;  (в силу трехдиагональности симметричности достаточно хранить только ненулевые элементы). В разных реализациях эта экономия хранения может быть выполнена разным образом.&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22589</id>
		<title>Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22589"/>
		<updated>2017-05-03T13:27:40Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Общий информационный граф алгроитма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Sagak|С.А.Айвазян]], [[Участник:Kozlov_Vladimir|В.Козлов]] (Часть 1), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (компоновка и редактирование), [[Участник:ASA|А.С.Антонов]] (предварительная проверка).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
Алгоритм  Ланцоша – итерационный метод , созданный Корнелиусом Ланцошем, для нахождения собственных значений и собственных векторов симметричной матрицы. Суть алгоритма в том, что он сводит частичную проблему собственных значений симметричной вещественной матрицы  к полной проблеме собственных значений для симметричной трехдиагональной матрицы  меньшей размерности. Алгоритм применяется  к матрицам большой размерности, к которым не применимы никакие прямые методы. &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;QR&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;QL&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; — это итерационный алгоритм поиска &amp;lt;math&amp;gt;k&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;. Алгоритм применяется, когда матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; слишком велика, чтобы к ней можно было применять точные прямые методы вычисления собственных значений. Алгоритм комбинирует &#039;&#039;&#039;метод Рэлея — Ритца&#039;&#039;&#039; поиска приближённых собственных значений и &#039;&#039;&#039;метод Ланцоша&#039;&#039;&#039; построения крыловского подпространства.&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца является методом поиска &amp;lt;math&amp;gt;k&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;. Если &amp;lt;math&amp;gt;Q = [Q_k, Q_u]&amp;lt;/math&amp;gt; — ортонормированная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_k&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_u&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times n - k&amp;lt;/math&amp;gt;, то можно записать равенство&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;T = Q^T A Q = [Q_k, Q_u]^T A [Q_k, Q_u] = &lt;br /&gt;
\left[ \begin{array}{cc}&lt;br /&gt;
Q_k^T A Q_k &amp;amp; Q_k^T A Q_u\\&lt;br /&gt;
Q_u^T A Q_k &amp;amp; Q_u^T A Q_u&lt;br /&gt;
\end{array} \right]&lt;br /&gt;
= \left[ \begin{array}{cc}&lt;br /&gt;
T_{k} &amp;amp; T_{ku}^T\\&lt;br /&gt;
T_{ku} &amp;amp; T_{u}&lt;br /&gt;
\end{array} \right].&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца заключается в том, что собственные значения матрицы &amp;lt;math&amp;gt;T_k = Q_k^T A Q_k&amp;lt;/math&amp;gt; объявляются приближёнными собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Такое приближение является в некотором смысле «наилучшим»: можно показать, что если &amp;lt;math&amp;gt;T_k = V \Lambda V^{-1}&amp;lt;/math&amp;gt; — спектральное разложение &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;, то пара &amp;lt;math&amp;gt;(Q_k V, \Lambda)&amp;lt;/math&amp;gt; минимизирует функционал &amp;lt;math&amp;gt;L(P_k, D) = \Vert A P_k - P_k D \Vert_2&amp;lt;/math&amp;gt;, причём &amp;lt;math&amp;gt;L(Q_k V, \Lambda) = \Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;, то есть &amp;lt;math&amp;gt;A \approx (Q_k V) \Lambda (Q_k V)^{-1}&amp;lt;/math&amp;gt;. Из этого также видно, что метод Рэлея — Ритца позволяет получать приближения для собственных векторов матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Более того, можно показать, что собственные значения &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; отличаются от некоторых собственных значений &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не более чем на &amp;lt;math&amp;gt;\Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Метод Ланцоша — это метод построения матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, при использовании которого, во-первых, матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; оказывается симметричной трёхдиагональной, во-вторых, столбцы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются последовательно. Трёхдиагональность &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; приводит к следующим явлениям:&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; является трёхдиагональной матрицей меньшей размерности, а для трёхдиагональных матриц существуют высокоэффективные методы поиска собственных значений;&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_{ku}&amp;lt;/math&amp;gt; имеет только один ненулевой (возможно) элемент — правый верхний, а значит, для оценки погрешности полученных собственных значений достаточно знать только этот элемент.&lt;br /&gt;
&lt;br /&gt;
В теории в методе Ланцоша для вычисления каждого следующего столбца &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; достаточно знать только &amp;lt;math&amp;gt;q_{j - 1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_{j}&amp;lt;/math&amp;gt; в силу трёхдиагональности матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;. На практике из-за ошибок округления, если не предпринимать специальных мер, набор векторов &amp;lt;math&amp;gt;q_{1}, \dots, q_{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;b&amp;lt;/math&amp;gt; — начальное приближение для метода Ланцоша.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: трёхдиагональная симметричная вещественная матрица &amp;lt;math&amp;gt;T_k = \left[ \begin{array}{cccc}&lt;br /&gt;
\alpha_1 &amp;amp; \beta_1 &amp;amp; &amp;amp; \\&lt;br /&gt;
\beta_1 &amp;amp; \ddots &amp;amp; \ddots &amp;amp; \\&lt;br /&gt;
&amp;amp; \ddots &amp;amp; \ddots &amp;amp; \beta_{k - 1}\\&lt;br /&gt;
&amp;amp; &amp;amp; \beta_{k - 1} &amp;amp; \alpha_k&lt;br /&gt;
\end{array} \right]&amp;lt;/math&amp;gt;, ортонормированный набор векторов &amp;lt;math&amp;gt;q_1, \dots, q_k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;T_k = [q_1, \dots, q_k]^T A [q_1, \dots, q_k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Формулы метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{l}&lt;br /&gt;
q_1 = b / \Vert b \Vert_2\\&lt;br /&gt;
j = \overline{1, k}:\\&lt;br /&gt;
\quad z_j = A q_j \\&lt;br /&gt;
\quad \alpha_j = q_j^T A q_j = q_j^T z_j \\&lt;br /&gt;
\quad z_j&#039; = z_j - \sum_{i=1}^j (z_j^T q_i) q_i \\&lt;br /&gt;
\quad z_j&#039;&#039; = z_j&#039; - \sum_{i=1}^j (z_j&#039;^T q_i) q_i\\&lt;br /&gt;
\quad \beta_j = \Vert z_j&#039;&#039; \Vert_2\\&lt;br /&gt;
\quad q_{j+1} = z_j&#039;&#039; / \Vert z_j&#039;&#039; \Vert_2 = z_j&#039;&#039;/\beta_j&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Собственные значения и собственные векторы матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; ищутся любым прямым алгоритмом.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;z_j&#039;, z_j&#039;&#039;&amp;lt;/math&amp;gt; — это полная переортогонализация &amp;lt;math&amp;gt;z_j&amp;lt;/math&amp;gt; методом Грама — Шмидта. Двойной запуск практически гарантирует, что &amp;lt;math&amp;gt;z_j&#039;&#039;&amp;lt;/math&amp;gt; будет ортогонален &amp;lt;math&amp;gt;q_1, \dots, q_j&amp;lt;/math&amp;gt;. Заметим, что &amp;lt;math&amp;gt;\sum_{i=1}^j (z^T q_i) q_i = Q_j Q_j^T z&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_j = [q_1, \dots, q_j]&amp;lt;/math&amp;gt;, поэтому переортогонализацию можно переписать в виде &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j, z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_j = 0&amp;lt;/math&amp;gt; для какого-либо &amp;lt;math&amp;gt;j &amp;lt; k&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\Vert T_{ju}\Vert_2 = 0&amp;lt;/math&amp;gt;, а значит, собственные значения &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; в точности совпадают с каким-то собственными значениями &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. В этом случае дальнейшие вычисления прекращаются и либо используется полученная &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; размерности меньшей, чем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, либо процедура запускается заново с другим начальным вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
У алгоритма построения матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; в том виде, как он описан выше, можно выделить два ядра:&lt;br /&gt;
# умножение матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на вектор &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;z_j = A q_j&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; умножений вещественных чисел);&lt;br /&gt;
# переортогонализация: &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j,\; z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(nk^2)&amp;lt;/math&amp;gt; умножений вещественных чисел).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
На макроуровне выделяем 3 основные операции:&lt;br /&gt;
&lt;br /&gt;
1. Умножение исходной матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на очередной вектор базиса &amp;lt;math&amp;gt;q_p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z=Aq_p. &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Повторное проведения процесса  Грамма-Шмидта  для ортогонализации посчитанного вектора &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt; со всеми построенными ранее векторами базиса.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i.      &amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
3.Непосредственное вычисление нового базисного вектора &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; и элементов &amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j&lt;br /&gt;
&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; \beta_{j+1}&lt;br /&gt;
&amp;lt;/math&amp;gt;  трехдиагональной матрицы.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j=q_j^Tz,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{j+1}=z/\beta_{j+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;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; q_1=b/||b||,\\&lt;br /&gt;
&amp;amp; \beta_1=0,\\&lt;br /&gt;
&amp;amp;q_0=0, \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&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;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&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;&lt;br /&gt;
1.z=Aq_j, &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j}&amp;lt;/math&amp;gt; конечной матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
2.\alpha_j=q_j^Tz,&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;&lt;br /&gt;
3.z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;4.z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,      &amp;lt;/math&amp;gt; &lt;br /&gt;
  &lt;br /&gt;
После ортогонализации процедура продолжается следующим образом.                      &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;5.z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j+1}&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;t_{j+1,j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;6.\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_{j+1}=0&amp;lt;/math&amp;gt;, то алгоритм завершается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;7.q_{j+1}=z/\beta_{j+1}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В конце каждой итерации получаем очередной вектор &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; базиса с единичной нормой, который ортогонален всем предыдущим векторам базиса,&lt;br /&gt;
&lt;br /&gt;
и элементы &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\beta_{j+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;
На &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ой итерации алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2 + n + 4nj + n + n = n^2 + 3n + 4nj&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;n(n - 1) + (n - 1) + (4n - 2)j + (n - 1) = n^2 + (n - 2) + (4n - 2)j&amp;lt;/math&amp;gt; сложений и вычитаний;&lt;br /&gt;
* одно извлечение квадратного корня.&lt;br /&gt;
&lt;br /&gt;
Всего за &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; итераций алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;(n + 3)nk + 2nk(k + 1)&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;(n^2 + n - 2)k + (2n - 1)k(k + 1)&amp;lt;/math&amp;gt; сложений и вычитаний.&lt;br /&gt;
&lt;br /&gt;
Таким образом, алгоритм имеет последовательную сложность &amp;lt;math&amp;gt;O(n^2k + nk^2)&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;
[[Файл:Lanczoc-full-orth-macro.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 1. Информационный граф алгоритма Ланцоша на уровне итераций с входными и выходными данными. In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и вектор &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), nrm — вычисление еклидовой нормы вектора, / — деление вектора на число, Iter — итерации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Информационный граф на уровне одной итерации с входными и выходными данными====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Lanczoc-full-orth-iter.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 2. Информационный граф итерации алгоритма Ланцоша на уровне макроопераций (первые три итерации). In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), dprod — скалярное произведение векторов, mprod — произведение матрицы на вектор, - — разность векторов, nrm — вычисление еклидовой нормы вектора, / — деление вектора на число.]]&lt;br /&gt;
&lt;br /&gt;
====Общий информационный граф алгроитма====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:photo.jpg|thumb|left|alt=Общий информационный граф алгроитма Ланцоша|Рисунок 3. Общий информационный граф алгроитма алгоритма Ланцоша.]]&lt;br /&gt;
&lt;br /&gt;
* Вершина черного цвета соответствует операции  &amp;lt;math&amp;gt;Aq_j,&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина красного цвета соответствует операции скалярного произведения &amp;lt;math&amp;gt;q_j^Tz&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина сиреневого цвета соответствует операции &amp;lt;math&amp;gt;z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина желтого цвета соответствует операции &amp;lt;math&amp;gt;z-\alpha_jq_j-\beta_{j-1}q_{j-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина синего цвета соответствует операции &amp;lt;math&amp;gt;||z||&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина зеленого цвета соответствует операции &amp;lt;math&amp;gt;z/\beta_j&amp;lt;/math&amp;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;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; операциями умножения в каждом (вычисление &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операцией умножения в каждом (вычисление &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;j&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; ярусов сложений с &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;n&amp;lt;/math&amp;gt; (первая переортогонализация);&lt;br /&gt;
# &amp;lt;math&amp;gt;j&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; ярусов сложений с &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;n&amp;lt;/math&amp;gt; (вторая переортогонализация);&lt;br /&gt;
# &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; ярусов сложений с &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; операцией умножения в каждом (вычисление &amp;lt;math&amp;gt;\beta_j&amp;lt;/math&amp;gt;);&lt;br /&gt;
# &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; ярус делений размера &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (вычисление &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Итого ширина ЯПФ одной итерации составляет &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, высота — &amp;lt;math&amp;gt;4n + 2j + 3&amp;lt;/math&amp;gt;. Ширина ЯПФ всего алгоритма составляет &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, высота — &amp;lt;math&amp;gt;O(nk + k^2)&amp;lt;/math&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;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;),произвольный вектор ненулевой &amp;lt;math&amp;gt;b&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;
* &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; – симметрическая матрица, т. е. &amp;lt;math&amp;gt;a_{ij}= a_{ji}, i, j = 1, \ldots, n&amp;lt;/math&amp;gt;..&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 3)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: трехдиагональная симметрическая матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;_{ij}&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; размерности &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2k&amp;lt;/math&amp;gt;  (в силу трехдиагональности симметричности достаточно хранить только ненулевые элементы). В разных реализациях эта экономия хранения может быть выполнена разным образом.&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22588</id>
		<title>Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22588"/>
		<updated>2017-05-03T13:21:20Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Sagak|С.А.Айвазян]], [[Участник:Kozlov_Vladimir|В.Козлов]] (Часть 1), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (компоновка и редактирование), [[Участник:ASA|А.С.Антонов]] (предварительная проверка).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
Алгоритм  Ланцоша – итерационный метод , созданный Корнелиусом Ланцошем, для нахождения собственных значений и собственных векторов симметричной матрицы. Суть алгоритма в том, что он сводит частичную проблему собственных значений симметричной вещественной матрицы  к полной проблеме собственных значений для симметричной трехдиагональной матрицы  меньшей размерности. Алгоритм применяется  к матрицам большой размерности, к которым не применимы никакие прямые методы. &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;QR&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;QL&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; — это итерационный алгоритм поиска &amp;lt;math&amp;gt;k&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;. Алгоритм применяется, когда матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; слишком велика, чтобы к ней можно было применять точные прямые методы вычисления собственных значений. Алгоритм комбинирует &#039;&#039;&#039;метод Рэлея — Ритца&#039;&#039;&#039; поиска приближённых собственных значений и &#039;&#039;&#039;метод Ланцоша&#039;&#039;&#039; построения крыловского подпространства.&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца является методом поиска &amp;lt;math&amp;gt;k&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;. Если &amp;lt;math&amp;gt;Q = [Q_k, Q_u]&amp;lt;/math&amp;gt; — ортонормированная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_k&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_u&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times n - k&amp;lt;/math&amp;gt;, то можно записать равенство&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;T = Q^T A Q = [Q_k, Q_u]^T A [Q_k, Q_u] = &lt;br /&gt;
\left[ \begin{array}{cc}&lt;br /&gt;
Q_k^T A Q_k &amp;amp; Q_k^T A Q_u\\&lt;br /&gt;
Q_u^T A Q_k &amp;amp; Q_u^T A Q_u&lt;br /&gt;
\end{array} \right]&lt;br /&gt;
= \left[ \begin{array}{cc}&lt;br /&gt;
T_{k} &amp;amp; T_{ku}^T\\&lt;br /&gt;
T_{ku} &amp;amp; T_{u}&lt;br /&gt;
\end{array} \right].&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца заключается в том, что собственные значения матрицы &amp;lt;math&amp;gt;T_k = Q_k^T A Q_k&amp;lt;/math&amp;gt; объявляются приближёнными собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Такое приближение является в некотором смысле «наилучшим»: можно показать, что если &amp;lt;math&amp;gt;T_k = V \Lambda V^{-1}&amp;lt;/math&amp;gt; — спектральное разложение &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;, то пара &amp;lt;math&amp;gt;(Q_k V, \Lambda)&amp;lt;/math&amp;gt; минимизирует функционал &amp;lt;math&amp;gt;L(P_k, D) = \Vert A P_k - P_k D \Vert_2&amp;lt;/math&amp;gt;, причём &amp;lt;math&amp;gt;L(Q_k V, \Lambda) = \Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;, то есть &amp;lt;math&amp;gt;A \approx (Q_k V) \Lambda (Q_k V)^{-1}&amp;lt;/math&amp;gt;. Из этого также видно, что метод Рэлея — Ритца позволяет получать приближения для собственных векторов матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Более того, можно показать, что собственные значения &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; отличаются от некоторых собственных значений &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не более чем на &amp;lt;math&amp;gt;\Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Метод Ланцоша — это метод построения матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, при использовании которого, во-первых, матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; оказывается симметричной трёхдиагональной, во-вторых, столбцы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются последовательно. Трёхдиагональность &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; приводит к следующим явлениям:&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; является трёхдиагональной матрицей меньшей размерности, а для трёхдиагональных матриц существуют высокоэффективные методы поиска собственных значений;&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_{ku}&amp;lt;/math&amp;gt; имеет только один ненулевой (возможно) элемент — правый верхний, а значит, для оценки погрешности полученных собственных значений достаточно знать только этот элемент.&lt;br /&gt;
&lt;br /&gt;
В теории в методе Ланцоша для вычисления каждого следующего столбца &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; достаточно знать только &amp;lt;math&amp;gt;q_{j - 1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_{j}&amp;lt;/math&amp;gt; в силу трёхдиагональности матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;. На практике из-за ошибок округления, если не предпринимать специальных мер, набор векторов &amp;lt;math&amp;gt;q_{1}, \dots, q_{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;b&amp;lt;/math&amp;gt; — начальное приближение для метода Ланцоша.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: трёхдиагональная симметричная вещественная матрица &amp;lt;math&amp;gt;T_k = \left[ \begin{array}{cccc}&lt;br /&gt;
\alpha_1 &amp;amp; \beta_1 &amp;amp; &amp;amp; \\&lt;br /&gt;
\beta_1 &amp;amp; \ddots &amp;amp; \ddots &amp;amp; \\&lt;br /&gt;
&amp;amp; \ddots &amp;amp; \ddots &amp;amp; \beta_{k - 1}\\&lt;br /&gt;
&amp;amp; &amp;amp; \beta_{k - 1} &amp;amp; \alpha_k&lt;br /&gt;
\end{array} \right]&amp;lt;/math&amp;gt;, ортонормированный набор векторов &amp;lt;math&amp;gt;q_1, \dots, q_k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;T_k = [q_1, \dots, q_k]^T A [q_1, \dots, q_k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Формулы метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{l}&lt;br /&gt;
q_1 = b / \Vert b \Vert_2\\&lt;br /&gt;
j = \overline{1, k}:\\&lt;br /&gt;
\quad z_j = A q_j \\&lt;br /&gt;
\quad \alpha_j = q_j^T A q_j = q_j^T z_j \\&lt;br /&gt;
\quad z_j&#039; = z_j - \sum_{i=1}^j (z_j^T q_i) q_i \\&lt;br /&gt;
\quad z_j&#039;&#039; = z_j&#039; - \sum_{i=1}^j (z_j&#039;^T q_i) q_i\\&lt;br /&gt;
\quad \beta_j = \Vert z_j&#039;&#039; \Vert_2\\&lt;br /&gt;
\quad q_{j+1} = z_j&#039;&#039; / \Vert z_j&#039;&#039; \Vert_2 = z_j&#039;&#039;/\beta_j&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Собственные значения и собственные векторы матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; ищутся любым прямым алгоритмом.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;z_j&#039;, z_j&#039;&#039;&amp;lt;/math&amp;gt; — это полная переортогонализация &amp;lt;math&amp;gt;z_j&amp;lt;/math&amp;gt; методом Грама — Шмидта. Двойной запуск практически гарантирует, что &amp;lt;math&amp;gt;z_j&#039;&#039;&amp;lt;/math&amp;gt; будет ортогонален &amp;lt;math&amp;gt;q_1, \dots, q_j&amp;lt;/math&amp;gt;. Заметим, что &amp;lt;math&amp;gt;\sum_{i=1}^j (z^T q_i) q_i = Q_j Q_j^T z&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_j = [q_1, \dots, q_j]&amp;lt;/math&amp;gt;, поэтому переортогонализацию можно переписать в виде &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j, z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_j = 0&amp;lt;/math&amp;gt; для какого-либо &amp;lt;math&amp;gt;j &amp;lt; k&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\Vert T_{ju}\Vert_2 = 0&amp;lt;/math&amp;gt;, а значит, собственные значения &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; в точности совпадают с каким-то собственными значениями &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. В этом случае дальнейшие вычисления прекращаются и либо используется полученная &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; размерности меньшей, чем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, либо процедура запускается заново с другим начальным вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
У алгоритма построения матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; в том виде, как он описан выше, можно выделить два ядра:&lt;br /&gt;
# умножение матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на вектор &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;z_j = A q_j&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; умножений вещественных чисел);&lt;br /&gt;
# переортогонализация: &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j,\; z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(nk^2)&amp;lt;/math&amp;gt; умножений вещественных чисел).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
На макроуровне выделяем 3 основные операции:&lt;br /&gt;
&lt;br /&gt;
1. Умножение исходной матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на очередной вектор базиса &amp;lt;math&amp;gt;q_p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z=Aq_p. &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Повторное проведения процесса  Грамма-Шмидта  для ортогонализации посчитанного вектора &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt; со всеми построенными ранее векторами базиса.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i.      &amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
3.Непосредственное вычисление нового базисного вектора &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; и элементов &amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j&lt;br /&gt;
&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; \beta_{j+1}&lt;br /&gt;
&amp;lt;/math&amp;gt;  трехдиагональной матрицы.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j=q_j^Tz,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{j+1}=z/\beta_{j+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;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; q_1=b/||b||,\\&lt;br /&gt;
&amp;amp; \beta_1=0,\\&lt;br /&gt;
&amp;amp;q_0=0, \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&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;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&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;&lt;br /&gt;
1.z=Aq_j, &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j}&amp;lt;/math&amp;gt; конечной матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
2.\alpha_j=q_j^Tz,&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;&lt;br /&gt;
3.z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;4.z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,      &amp;lt;/math&amp;gt; &lt;br /&gt;
  &lt;br /&gt;
После ортогонализации процедура продолжается следующим образом.                      &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;5.z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j+1}&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;t_{j+1,j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;6.\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_{j+1}=0&amp;lt;/math&amp;gt;, то алгоритм завершается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;7.q_{j+1}=z/\beta_{j+1}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В конце каждой итерации получаем очередной вектор &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; базиса с единичной нормой, который ортогонален всем предыдущим векторам базиса,&lt;br /&gt;
&lt;br /&gt;
и элементы &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\beta_{j+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;
На &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ой итерации алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2 + n + 4nj + n + n = n^2 + 3n + 4nj&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;n(n - 1) + (n - 1) + (4n - 2)j + (n - 1) = n^2 + (n - 2) + (4n - 2)j&amp;lt;/math&amp;gt; сложений и вычитаний;&lt;br /&gt;
* одно извлечение квадратного корня.&lt;br /&gt;
&lt;br /&gt;
Всего за &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; итераций алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;(n + 3)nk + 2nk(k + 1)&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;(n^2 + n - 2)k + (2n - 1)k(k + 1)&amp;lt;/math&amp;gt; сложений и вычитаний.&lt;br /&gt;
&lt;br /&gt;
Таким образом, алгоритм имеет последовательную сложность &amp;lt;math&amp;gt;O(n^2k + nk^2)&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;
[[Файл:Lanczoc-full-orth-macro.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 1. Информационный граф алгоритма Ланцоша на уровне итераций с входными и выходными данными. In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и вектор &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), nrm — вычисление еклидовой нормы вектора, / — деление вектора на число, Iter — итерации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Информационный граф на уровне одной итерации с входными и выходными данными====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Lanczoc-full-orth-iter.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 2. Информационный граф итерации алгоритма Ланцоша на уровне макроопераций (первые три итерации). In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), dprod — скалярное произведение векторов, mprod — произведение матрицы на вектор, - — разность векторов, nrm — вычисление еклидовой нормы вектора, / — деление вектора на число.]]&lt;br /&gt;
&lt;br /&gt;
====Общий информационный граф алгроитма====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:photo.jpg|thumb|left|alt=Общий информационный граф алгроитма Ланцоша|Рисунок 3. Общий информационный граф алгроитма алгоритма Ланцоша.]]&lt;br /&gt;
&lt;br /&gt;
* Вершина черного цвета соответствует операции  &amp;lt;math&amp;gt;Aq_j,&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина красного цвета соответствует операции скалярного произведения &amp;lt;math&amp;gt;q_j^Tz&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина сиреневого цвета соответствует операции &amp;lt;math&amp;gt;z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина желтого цвета соответствует операции &amp;lt;math&amp;gt;z-\alpha_jq_j-\beta_{j-1}q_{j-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина синего цвета соответствует операции &amp;lt;math&amp;gt;||z||&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина зеленого цвета соответствует операции &amp;lt;math&amp;gt;z/\beta_j&amp;lt;/math&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22587</id>
		<title>Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22587"/>
		<updated>2017-05-03T13:15:39Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* =Общий информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Sagak|С.А.Айвазян]], [[Участник:Kozlov_Vladimir|В.Козлов]] (Часть 1), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (компоновка и редактирование), [[Участник:ASA|А.С.Антонов]] (предварительная проверка).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
Алгоритм  Ланцоша – итерационный метод , созданный Корнелиусом Ланцошем, для нахождения собственных значений и собственных векторов симметричной матрицы. Суть алгоритма в том, что он сводит частичную проблему собственных значений симметричной вещественной матрицы  к полной проблеме собственных значений для симметричной трехдиагональной матрицы  меньшей размерности. Алгоритм применяется  к матрицам большой размерности, к которым не применимы никакие прямые методы. &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;QR&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;QL&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; — это итерационный алгоритм поиска &amp;lt;math&amp;gt;k&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;. Алгоритм применяется, когда матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; слишком велика, чтобы к ней можно было применять точные прямые методы вычисления собственных значений. Алгоритм комбинирует &#039;&#039;&#039;метод Рэлея — Ритца&#039;&#039;&#039; поиска приближённых собственных значений и &#039;&#039;&#039;метод Ланцоша&#039;&#039;&#039; построения крыловского подпространства.&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца является методом поиска &amp;lt;math&amp;gt;k&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;. Если &amp;lt;math&amp;gt;Q = [Q_k, Q_u]&amp;lt;/math&amp;gt; — ортонормированная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_k&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_u&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times n - k&amp;lt;/math&amp;gt;, то можно записать равенство&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;T = Q^T A Q = [Q_k, Q_u]^T A [Q_k, Q_u] = &lt;br /&gt;
\left[ \begin{array}{cc}&lt;br /&gt;
Q_k^T A Q_k &amp;amp; Q_k^T A Q_u\\&lt;br /&gt;
Q_u^T A Q_k &amp;amp; Q_u^T A Q_u&lt;br /&gt;
\end{array} \right]&lt;br /&gt;
= \left[ \begin{array}{cc}&lt;br /&gt;
T_{k} &amp;amp; T_{ku}^T\\&lt;br /&gt;
T_{ku} &amp;amp; T_{u}&lt;br /&gt;
\end{array} \right].&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца заключается в том, что собственные значения матрицы &amp;lt;math&amp;gt;T_k = Q_k^T A Q_k&amp;lt;/math&amp;gt; объявляются приближёнными собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Такое приближение является в некотором смысле «наилучшим»: можно показать, что если &amp;lt;math&amp;gt;T_k = V \Lambda V^{-1}&amp;lt;/math&amp;gt; — спектральное разложение &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;, то пара &amp;lt;math&amp;gt;(Q_k V, \Lambda)&amp;lt;/math&amp;gt; минимизирует функционал &amp;lt;math&amp;gt;L(P_k, D) = \Vert A P_k - P_k D \Vert_2&amp;lt;/math&amp;gt;, причём &amp;lt;math&amp;gt;L(Q_k V, \Lambda) = \Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;, то есть &amp;lt;math&amp;gt;A \approx (Q_k V) \Lambda (Q_k V)^{-1}&amp;lt;/math&amp;gt;. Из этого также видно, что метод Рэлея — Ритца позволяет получать приближения для собственных векторов матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Более того, можно показать, что собственные значения &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; отличаются от некоторых собственных значений &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не более чем на &amp;lt;math&amp;gt;\Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Метод Ланцоша — это метод построения матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, при использовании которого, во-первых, матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; оказывается симметричной трёхдиагональной, во-вторых, столбцы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются последовательно. Трёхдиагональность &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; приводит к следующим явлениям:&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; является трёхдиагональной матрицей меньшей размерности, а для трёхдиагональных матриц существуют высокоэффективные методы поиска собственных значений;&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_{ku}&amp;lt;/math&amp;gt; имеет только один ненулевой (возможно) элемент — правый верхний, а значит, для оценки погрешности полученных собственных значений достаточно знать только этот элемент.&lt;br /&gt;
&lt;br /&gt;
В теории в методе Ланцоша для вычисления каждого следующего столбца &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; достаточно знать только &amp;lt;math&amp;gt;q_{j - 1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_{j}&amp;lt;/math&amp;gt; в силу трёхдиагональности матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;. На практике из-за ошибок округления, если не предпринимать специальных мер, набор векторов &amp;lt;math&amp;gt;q_{1}, \dots, q_{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;b&amp;lt;/math&amp;gt; — начальное приближение для метода Ланцоша.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: трёхдиагональная симметричная вещественная матрица &amp;lt;math&amp;gt;T_k = \left[ \begin{array}{cccc}&lt;br /&gt;
\alpha_1 &amp;amp; \beta_1 &amp;amp; &amp;amp; \\&lt;br /&gt;
\beta_1 &amp;amp; \ddots &amp;amp; \ddots &amp;amp; \\&lt;br /&gt;
&amp;amp; \ddots &amp;amp; \ddots &amp;amp; \beta_{k - 1}\\&lt;br /&gt;
&amp;amp; &amp;amp; \beta_{k - 1} &amp;amp; \alpha_k&lt;br /&gt;
\end{array} \right]&amp;lt;/math&amp;gt;, ортонормированный набор векторов &amp;lt;math&amp;gt;q_1, \dots, q_k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;T_k = [q_1, \dots, q_k]^T A [q_1, \dots, q_k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Формулы метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{l}&lt;br /&gt;
q_1 = b / \Vert b \Vert_2\\&lt;br /&gt;
j = \overline{1, k}:\\&lt;br /&gt;
\quad z_j = A q_j \\&lt;br /&gt;
\quad \alpha_j = q_j^T A q_j = q_j^T z_j \\&lt;br /&gt;
\quad z_j&#039; = z_j - \sum_{i=1}^j (z_j^T q_i) q_i \\&lt;br /&gt;
\quad z_j&#039;&#039; = z_j&#039; - \sum_{i=1}^j (z_j&#039;^T q_i) q_i\\&lt;br /&gt;
\quad \beta_j = \Vert z_j&#039;&#039; \Vert_2\\&lt;br /&gt;
\quad q_{j+1} = z_j&#039;&#039; / \Vert z_j&#039;&#039; \Vert_2 = z_j&#039;&#039;/\beta_j&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Собственные значения и собственные векторы матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; ищутся любым прямым алгоритмом.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;z_j&#039;, z_j&#039;&#039;&amp;lt;/math&amp;gt; — это полная переортогонализация &amp;lt;math&amp;gt;z_j&amp;lt;/math&amp;gt; методом Грама — Шмидта. Двойной запуск практически гарантирует, что &amp;lt;math&amp;gt;z_j&#039;&#039;&amp;lt;/math&amp;gt; будет ортогонален &amp;lt;math&amp;gt;q_1, \dots, q_j&amp;lt;/math&amp;gt;. Заметим, что &amp;lt;math&amp;gt;\sum_{i=1}^j (z^T q_i) q_i = Q_j Q_j^T z&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_j = [q_1, \dots, q_j]&amp;lt;/math&amp;gt;, поэтому переортогонализацию можно переписать в виде &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j, z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_j = 0&amp;lt;/math&amp;gt; для какого-либо &amp;lt;math&amp;gt;j &amp;lt; k&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\Vert T_{ju}\Vert_2 = 0&amp;lt;/math&amp;gt;, а значит, собственные значения &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; в точности совпадают с каким-то собственными значениями &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. В этом случае дальнейшие вычисления прекращаются и либо используется полученная &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; размерности меньшей, чем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, либо процедура запускается заново с другим начальным вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
У алгоритма построения матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; в том виде, как он описан выше, можно выделить два ядра:&lt;br /&gt;
# умножение матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на вектор &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;z_j = A q_j&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; умножений вещественных чисел);&lt;br /&gt;
# переортогонализация: &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j,\; z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(nk^2)&amp;lt;/math&amp;gt; умножений вещественных чисел).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
На макроуровне выделяем 3 основные операции:&lt;br /&gt;
&lt;br /&gt;
1. Умножение исходной матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на очередной вектор базиса &amp;lt;math&amp;gt;q_p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z=Aq_p. &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Повторное проведения процесса  Грамма-Шмидта  для ортогонализации посчитанного вектора &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt; со всеми построенными ранее векторами базиса.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i.      &amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
3.Непосредственное вычисление нового базисного вектора &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; и элементов &amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j&lt;br /&gt;
&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; \beta_{j+1}&lt;br /&gt;
&amp;lt;/math&amp;gt;  трехдиагональной матрицы.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j=q_j^Tz,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{j+1}=z/\beta_{j+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;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; q_1=b/||b||,\\&lt;br /&gt;
&amp;amp; \beta_1=0,\\&lt;br /&gt;
&amp;amp;q_0=0, \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&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;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&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;&lt;br /&gt;
1.z=Aq_j, &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j}&amp;lt;/math&amp;gt; конечной матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
2.\alpha_j=q_j^Tz,&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;&lt;br /&gt;
3.z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;4.z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,      &amp;lt;/math&amp;gt; &lt;br /&gt;
  &lt;br /&gt;
После ортогонализации процедура продолжается следующим образом.                      &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;5.z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j+1}&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;t_{j+1,j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;6.\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_{j+1}=0&amp;lt;/math&amp;gt;, то алгоритм завершается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;7.q_{j+1}=z/\beta_{j+1}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В конце каждой итерации получаем очередной вектор &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; базиса с единичной нормой, который ортогонален всем предыдущим векторам базиса,&lt;br /&gt;
&lt;br /&gt;
и элементы &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\beta_{j+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;
На &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ой итерации алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2 + n + 4nj + n + n = n^2 + 3n + 4nj&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;n(n - 1) + (n - 1) + (4n - 2)j + (n - 1) = n^2 + (n - 2) + (4n - 2)j&amp;lt;/math&amp;gt; сложений и вычитаний;&lt;br /&gt;
* одно извлечение квадратного корня.&lt;br /&gt;
&lt;br /&gt;
Всего за &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; итераций алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;(n + 3)nk + 2nk(k + 1)&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;(n^2 + n - 2)k + (2n - 1)k(k + 1)&amp;lt;/math&amp;gt; сложений и вычитаний.&lt;br /&gt;
&lt;br /&gt;
Таким образом, алгоритм имеет последовательную сложность &amp;lt;math&amp;gt;O(n^2k + nk^2)&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;
[[Файл:Lanczoc-full-orth-macro.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 1. Информационный граф алгоритма Ланцоша на уровне итераций с входными и выходными данными. In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и вектор &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), nrm — вычисление еклидовой нормы вектора, / — деление вектора на число, Iter — итерации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Информационный граф на уровне одной итерации с входными и выходными данными====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Lanczoc-full-orth-iter.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 2. Информационный граф итерации алгоритма Ланцоша на уровне макроопераций. In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), dprod — скалярное произведение векторов, mprod — произведение матрицы на вектор, - — разность векторов, nrm — вычисление еклидовой нормы вектора, / — деление вектора на число.]]&lt;br /&gt;
&lt;br /&gt;
====Общий информационный граф алгроитма====&lt;br /&gt;
[[Файл:photo.jpg]]Здесь показаны первые три итерации алгоритма, при больших итерациях граф строится аналогичным образом.&lt;br /&gt;
* Вершина черного цвета соответствует операции  &amp;lt;math&amp;gt;Aq_j,&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина красного цвета соответствует операции скалярного произведения &amp;lt;math&amp;gt;q_j^Tz&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина сиреневого цвета соответствует операции &amp;lt;math&amp;gt;z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина желтого цвета соответствует операции &amp;lt;math&amp;gt;z-\alpha_jq_j-\beta_{j-1}q_{j-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина синего цвета соответствует операции &amp;lt;math&amp;gt;||z||&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина зеленого цвета соответствует операции &amp;lt;math&amp;gt;z/\beta_j&amp;lt;/math&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22586</id>
		<title>Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22586"/>
		<updated>2017-05-03T13:15:21Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* =Информационный граф на уровне макроопераций с входными и выходными данными */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Sagak|С.А.Айвазян]], [[Участник:Kozlov_Vladimir|В.Козлов]] (Часть 1), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (компоновка и редактирование), [[Участник:ASA|А.С.Антонов]] (предварительная проверка).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
Алгоритм  Ланцоша – итерационный метод , созданный Корнелиусом Ланцошем, для нахождения собственных значений и собственных векторов симметричной матрицы. Суть алгоритма в том, что он сводит частичную проблему собственных значений симметричной вещественной матрицы  к полной проблеме собственных значений для симметричной трехдиагональной матрицы  меньшей размерности. Алгоритм применяется  к матрицам большой размерности, к которым не применимы никакие прямые методы. &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;QR&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;QL&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; — это итерационный алгоритм поиска &amp;lt;math&amp;gt;k&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;. Алгоритм применяется, когда матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; слишком велика, чтобы к ней можно было применять точные прямые методы вычисления собственных значений. Алгоритм комбинирует &#039;&#039;&#039;метод Рэлея — Ритца&#039;&#039;&#039; поиска приближённых собственных значений и &#039;&#039;&#039;метод Ланцоша&#039;&#039;&#039; построения крыловского подпространства.&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца является методом поиска &amp;lt;math&amp;gt;k&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;. Если &amp;lt;math&amp;gt;Q = [Q_k, Q_u]&amp;lt;/math&amp;gt; — ортонормированная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_k&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_u&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times n - k&amp;lt;/math&amp;gt;, то можно записать равенство&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;T = Q^T A Q = [Q_k, Q_u]^T A [Q_k, Q_u] = &lt;br /&gt;
\left[ \begin{array}{cc}&lt;br /&gt;
Q_k^T A Q_k &amp;amp; Q_k^T A Q_u\\&lt;br /&gt;
Q_u^T A Q_k &amp;amp; Q_u^T A Q_u&lt;br /&gt;
\end{array} \right]&lt;br /&gt;
= \left[ \begin{array}{cc}&lt;br /&gt;
T_{k} &amp;amp; T_{ku}^T\\&lt;br /&gt;
T_{ku} &amp;amp; T_{u}&lt;br /&gt;
\end{array} \right].&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца заключается в том, что собственные значения матрицы &amp;lt;math&amp;gt;T_k = Q_k^T A Q_k&amp;lt;/math&amp;gt; объявляются приближёнными собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Такое приближение является в некотором смысле «наилучшим»: можно показать, что если &amp;lt;math&amp;gt;T_k = V \Lambda V^{-1}&amp;lt;/math&amp;gt; — спектральное разложение &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;, то пара &amp;lt;math&amp;gt;(Q_k V, \Lambda)&amp;lt;/math&amp;gt; минимизирует функционал &amp;lt;math&amp;gt;L(P_k, D) = \Vert A P_k - P_k D \Vert_2&amp;lt;/math&amp;gt;, причём &amp;lt;math&amp;gt;L(Q_k V, \Lambda) = \Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;, то есть &amp;lt;math&amp;gt;A \approx (Q_k V) \Lambda (Q_k V)^{-1}&amp;lt;/math&amp;gt;. Из этого также видно, что метод Рэлея — Ритца позволяет получать приближения для собственных векторов матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Более того, можно показать, что собственные значения &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; отличаются от некоторых собственных значений &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не более чем на &amp;lt;math&amp;gt;\Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Метод Ланцоша — это метод построения матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, при использовании которого, во-первых, матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; оказывается симметричной трёхдиагональной, во-вторых, столбцы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются последовательно. Трёхдиагональность &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; приводит к следующим явлениям:&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; является трёхдиагональной матрицей меньшей размерности, а для трёхдиагональных матриц существуют высокоэффективные методы поиска собственных значений;&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_{ku}&amp;lt;/math&amp;gt; имеет только один ненулевой (возможно) элемент — правый верхний, а значит, для оценки погрешности полученных собственных значений достаточно знать только этот элемент.&lt;br /&gt;
&lt;br /&gt;
В теории в методе Ланцоша для вычисления каждого следующего столбца &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; достаточно знать только &amp;lt;math&amp;gt;q_{j - 1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_{j}&amp;lt;/math&amp;gt; в силу трёхдиагональности матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;. На практике из-за ошибок округления, если не предпринимать специальных мер, набор векторов &amp;lt;math&amp;gt;q_{1}, \dots, q_{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;b&amp;lt;/math&amp;gt; — начальное приближение для метода Ланцоша.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: трёхдиагональная симметричная вещественная матрица &amp;lt;math&amp;gt;T_k = \left[ \begin{array}{cccc}&lt;br /&gt;
\alpha_1 &amp;amp; \beta_1 &amp;amp; &amp;amp; \\&lt;br /&gt;
\beta_1 &amp;amp; \ddots &amp;amp; \ddots &amp;amp; \\&lt;br /&gt;
&amp;amp; \ddots &amp;amp; \ddots &amp;amp; \beta_{k - 1}\\&lt;br /&gt;
&amp;amp; &amp;amp; \beta_{k - 1} &amp;amp; \alpha_k&lt;br /&gt;
\end{array} \right]&amp;lt;/math&amp;gt;, ортонормированный набор векторов &amp;lt;math&amp;gt;q_1, \dots, q_k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;T_k = [q_1, \dots, q_k]^T A [q_1, \dots, q_k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Формулы метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{l}&lt;br /&gt;
q_1 = b / \Vert b \Vert_2\\&lt;br /&gt;
j = \overline{1, k}:\\&lt;br /&gt;
\quad z_j = A q_j \\&lt;br /&gt;
\quad \alpha_j = q_j^T A q_j = q_j^T z_j \\&lt;br /&gt;
\quad z_j&#039; = z_j - \sum_{i=1}^j (z_j^T q_i) q_i \\&lt;br /&gt;
\quad z_j&#039;&#039; = z_j&#039; - \sum_{i=1}^j (z_j&#039;^T q_i) q_i\\&lt;br /&gt;
\quad \beta_j = \Vert z_j&#039;&#039; \Vert_2\\&lt;br /&gt;
\quad q_{j+1} = z_j&#039;&#039; / \Vert z_j&#039;&#039; \Vert_2 = z_j&#039;&#039;/\beta_j&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Собственные значения и собственные векторы матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; ищутся любым прямым алгоритмом.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;z_j&#039;, z_j&#039;&#039;&amp;lt;/math&amp;gt; — это полная переортогонализация &amp;lt;math&amp;gt;z_j&amp;lt;/math&amp;gt; методом Грама — Шмидта. Двойной запуск практически гарантирует, что &amp;lt;math&amp;gt;z_j&#039;&#039;&amp;lt;/math&amp;gt; будет ортогонален &amp;lt;math&amp;gt;q_1, \dots, q_j&amp;lt;/math&amp;gt;. Заметим, что &amp;lt;math&amp;gt;\sum_{i=1}^j (z^T q_i) q_i = Q_j Q_j^T z&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_j = [q_1, \dots, q_j]&amp;lt;/math&amp;gt;, поэтому переортогонализацию можно переписать в виде &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j, z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_j = 0&amp;lt;/math&amp;gt; для какого-либо &amp;lt;math&amp;gt;j &amp;lt; k&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\Vert T_{ju}\Vert_2 = 0&amp;lt;/math&amp;gt;, а значит, собственные значения &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; в точности совпадают с каким-то собственными значениями &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. В этом случае дальнейшие вычисления прекращаются и либо используется полученная &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; размерности меньшей, чем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, либо процедура запускается заново с другим начальным вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
У алгоритма построения матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; в том виде, как он описан выше, можно выделить два ядра:&lt;br /&gt;
# умножение матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на вектор &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;z_j = A q_j&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; умножений вещественных чисел);&lt;br /&gt;
# переортогонализация: &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j,\; z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(nk^2)&amp;lt;/math&amp;gt; умножений вещественных чисел).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
На макроуровне выделяем 3 основные операции:&lt;br /&gt;
&lt;br /&gt;
1. Умножение исходной матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на очередной вектор базиса &amp;lt;math&amp;gt;q_p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z=Aq_p. &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Повторное проведения процесса  Грамма-Шмидта  для ортогонализации посчитанного вектора &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt; со всеми построенными ранее векторами базиса.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i.      &amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
3.Непосредственное вычисление нового базисного вектора &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; и элементов &amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j&lt;br /&gt;
&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; \beta_{j+1}&lt;br /&gt;
&amp;lt;/math&amp;gt;  трехдиагональной матрицы.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j=q_j^Tz,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{j+1}=z/\beta_{j+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;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; q_1=b/||b||,\\&lt;br /&gt;
&amp;amp; \beta_1=0,\\&lt;br /&gt;
&amp;amp;q_0=0, \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&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;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&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;&lt;br /&gt;
1.z=Aq_j, &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j}&amp;lt;/math&amp;gt; конечной матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
2.\alpha_j=q_j^Tz,&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;&lt;br /&gt;
3.z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;4.z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,      &amp;lt;/math&amp;gt; &lt;br /&gt;
  &lt;br /&gt;
После ортогонализации процедура продолжается следующим образом.                      &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;5.z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j+1}&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;t_{j+1,j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;6.\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_{j+1}=0&amp;lt;/math&amp;gt;, то алгоритм завершается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;7.q_{j+1}=z/\beta_{j+1}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В конце каждой итерации получаем очередной вектор &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; базиса с единичной нормой, который ортогонален всем предыдущим векторам базиса,&lt;br /&gt;
&lt;br /&gt;
и элементы &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\beta_{j+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;
На &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ой итерации алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2 + n + 4nj + n + n = n^2 + 3n + 4nj&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;n(n - 1) + (n - 1) + (4n - 2)j + (n - 1) = n^2 + (n - 2) + (4n - 2)j&amp;lt;/math&amp;gt; сложений и вычитаний;&lt;br /&gt;
* одно извлечение квадратного корня.&lt;br /&gt;
&lt;br /&gt;
Всего за &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; итераций алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;(n + 3)nk + 2nk(k + 1)&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;(n^2 + n - 2)k + (2n - 1)k(k + 1)&amp;lt;/math&amp;gt; сложений и вычитаний.&lt;br /&gt;
&lt;br /&gt;
Таким образом, алгоритм имеет последовательную сложность &amp;lt;math&amp;gt;O(n^2k + nk^2)&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;
[[Файл:Lanczoc-full-orth-macro.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 1. Информационный граф алгоритма Ланцоша на уровне итераций с входными и выходными данными. In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и вектор &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), nrm — вычисление еклидовой нормы вектора, / — деление вектора на число, Iter — итерации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Информационный граф на уровне одной итерации с входными и выходными данными====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Lanczoc-full-orth-iter.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 2. Информационный граф итерации алгоритма Ланцоша на уровне макроопераций. In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), dprod — скалярное произведение векторов, mprod — произведение матрицы на вектор, - — разность векторов, nrm — вычисление еклидовой нормы вектора, / — деление вектора на число.]]&lt;br /&gt;
&lt;br /&gt;
====Общий информационный граф===&lt;br /&gt;
[[Файл:photo.jpg]]Здесь показаны первые три итерации алгоритма, при больших итерациях граф строится аналогичным образом.&lt;br /&gt;
* Вершина черного цвета соответствует операции  &amp;lt;math&amp;gt;Aq_j,&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина красного цвета соответствует операции скалярного произведения &amp;lt;math&amp;gt;q_j^Tz&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина сиреневого цвета соответствует операции &amp;lt;math&amp;gt;z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина желтого цвета соответствует операции &amp;lt;math&amp;gt;z-\alpha_jq_j-\beta_{j-1}q_{j-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина синего цвета соответствует операции &amp;lt;math&amp;gt;||z||&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина зеленого цвета соответствует операции &amp;lt;math&amp;gt;z/\beta_j&amp;lt;/math&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22585</id>
		<title>Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22585"/>
		<updated>2017-05-03T13:14:43Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Свойства и структура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Sagak|С.А.Айвазян]], [[Участник:Kozlov_Vladimir|В.Козлов]] (Часть 1), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (компоновка и редактирование), [[Участник:ASA|А.С.Антонов]] (предварительная проверка).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
Алгоритм  Ланцоша – итерационный метод , созданный Корнелиусом Ланцошем, для нахождения собственных значений и собственных векторов симметричной матрицы. Суть алгоритма в том, что он сводит частичную проблему собственных значений симметричной вещественной матрицы  к полной проблеме собственных значений для симметричной трехдиагональной матрицы  меньшей размерности. Алгоритм применяется  к матрицам большой размерности, к которым не применимы никакие прямые методы. &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;QR&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;QL&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; — это итерационный алгоритм поиска &amp;lt;math&amp;gt;k&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;. Алгоритм применяется, когда матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; слишком велика, чтобы к ней можно было применять точные прямые методы вычисления собственных значений. Алгоритм комбинирует &#039;&#039;&#039;метод Рэлея — Ритца&#039;&#039;&#039; поиска приближённых собственных значений и &#039;&#039;&#039;метод Ланцоша&#039;&#039;&#039; построения крыловского подпространства.&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца является методом поиска &amp;lt;math&amp;gt;k&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;. Если &amp;lt;math&amp;gt;Q = [Q_k, Q_u]&amp;lt;/math&amp;gt; — ортонормированная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_k&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_u&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times n - k&amp;lt;/math&amp;gt;, то можно записать равенство&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;T = Q^T A Q = [Q_k, Q_u]^T A [Q_k, Q_u] = &lt;br /&gt;
\left[ \begin{array}{cc}&lt;br /&gt;
Q_k^T A Q_k &amp;amp; Q_k^T A Q_u\\&lt;br /&gt;
Q_u^T A Q_k &amp;amp; Q_u^T A Q_u&lt;br /&gt;
\end{array} \right]&lt;br /&gt;
= \left[ \begin{array}{cc}&lt;br /&gt;
T_{k} &amp;amp; T_{ku}^T\\&lt;br /&gt;
T_{ku} &amp;amp; T_{u}&lt;br /&gt;
\end{array} \right].&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца заключается в том, что собственные значения матрицы &amp;lt;math&amp;gt;T_k = Q_k^T A Q_k&amp;lt;/math&amp;gt; объявляются приближёнными собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Такое приближение является в некотором смысле «наилучшим»: можно показать, что если &amp;lt;math&amp;gt;T_k = V \Lambda V^{-1}&amp;lt;/math&amp;gt; — спектральное разложение &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;, то пара &amp;lt;math&amp;gt;(Q_k V, \Lambda)&amp;lt;/math&amp;gt; минимизирует функционал &amp;lt;math&amp;gt;L(P_k, D) = \Vert A P_k - P_k D \Vert_2&amp;lt;/math&amp;gt;, причём &amp;lt;math&amp;gt;L(Q_k V, \Lambda) = \Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;, то есть &amp;lt;math&amp;gt;A \approx (Q_k V) \Lambda (Q_k V)^{-1}&amp;lt;/math&amp;gt;. Из этого также видно, что метод Рэлея — Ритца позволяет получать приближения для собственных векторов матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Более того, можно показать, что собственные значения &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; отличаются от некоторых собственных значений &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не более чем на &amp;lt;math&amp;gt;\Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Метод Ланцоша — это метод построения матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, при использовании которого, во-первых, матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; оказывается симметричной трёхдиагональной, во-вторых, столбцы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются последовательно. Трёхдиагональность &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; приводит к следующим явлениям:&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; является трёхдиагональной матрицей меньшей размерности, а для трёхдиагональных матриц существуют высокоэффективные методы поиска собственных значений;&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_{ku}&amp;lt;/math&amp;gt; имеет только один ненулевой (возможно) элемент — правый верхний, а значит, для оценки погрешности полученных собственных значений достаточно знать только этот элемент.&lt;br /&gt;
&lt;br /&gt;
В теории в методе Ланцоша для вычисления каждого следующего столбца &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; достаточно знать только &amp;lt;math&amp;gt;q_{j - 1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_{j}&amp;lt;/math&amp;gt; в силу трёхдиагональности матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;. На практике из-за ошибок округления, если не предпринимать специальных мер, набор векторов &amp;lt;math&amp;gt;q_{1}, \dots, q_{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;b&amp;lt;/math&amp;gt; — начальное приближение для метода Ланцоша.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: трёхдиагональная симметричная вещественная матрица &amp;lt;math&amp;gt;T_k = \left[ \begin{array}{cccc}&lt;br /&gt;
\alpha_1 &amp;amp; \beta_1 &amp;amp; &amp;amp; \\&lt;br /&gt;
\beta_1 &amp;amp; \ddots &amp;amp; \ddots &amp;amp; \\&lt;br /&gt;
&amp;amp; \ddots &amp;amp; \ddots &amp;amp; \beta_{k - 1}\\&lt;br /&gt;
&amp;amp; &amp;amp; \beta_{k - 1} &amp;amp; \alpha_k&lt;br /&gt;
\end{array} \right]&amp;lt;/math&amp;gt;, ортонормированный набор векторов &amp;lt;math&amp;gt;q_1, \dots, q_k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;T_k = [q_1, \dots, q_k]^T A [q_1, \dots, q_k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Формулы метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{l}&lt;br /&gt;
q_1 = b / \Vert b \Vert_2\\&lt;br /&gt;
j = \overline{1, k}:\\&lt;br /&gt;
\quad z_j = A q_j \\&lt;br /&gt;
\quad \alpha_j = q_j^T A q_j = q_j^T z_j \\&lt;br /&gt;
\quad z_j&#039; = z_j - \sum_{i=1}^j (z_j^T q_i) q_i \\&lt;br /&gt;
\quad z_j&#039;&#039; = z_j&#039; - \sum_{i=1}^j (z_j&#039;^T q_i) q_i\\&lt;br /&gt;
\quad \beta_j = \Vert z_j&#039;&#039; \Vert_2\\&lt;br /&gt;
\quad q_{j+1} = z_j&#039;&#039; / \Vert z_j&#039;&#039; \Vert_2 = z_j&#039;&#039;/\beta_j&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Собственные значения и собственные векторы матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; ищутся любым прямым алгоритмом.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;z_j&#039;, z_j&#039;&#039;&amp;lt;/math&amp;gt; — это полная переортогонализация &amp;lt;math&amp;gt;z_j&amp;lt;/math&amp;gt; методом Грама — Шмидта. Двойной запуск практически гарантирует, что &amp;lt;math&amp;gt;z_j&#039;&#039;&amp;lt;/math&amp;gt; будет ортогонален &amp;lt;math&amp;gt;q_1, \dots, q_j&amp;lt;/math&amp;gt;. Заметим, что &amp;lt;math&amp;gt;\sum_{i=1}^j (z^T q_i) q_i = Q_j Q_j^T z&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_j = [q_1, \dots, q_j]&amp;lt;/math&amp;gt;, поэтому переортогонализацию можно переписать в виде &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j, z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_j = 0&amp;lt;/math&amp;gt; для какого-либо &amp;lt;math&amp;gt;j &amp;lt; k&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\Vert T_{ju}\Vert_2 = 0&amp;lt;/math&amp;gt;, а значит, собственные значения &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; в точности совпадают с каким-то собственными значениями &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. В этом случае дальнейшие вычисления прекращаются и либо используется полученная &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; размерности меньшей, чем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, либо процедура запускается заново с другим начальным вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
У алгоритма построения матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; в том виде, как он описан выше, можно выделить два ядра:&lt;br /&gt;
# умножение матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на вектор &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;z_j = A q_j&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; умножений вещественных чисел);&lt;br /&gt;
# переортогонализация: &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j,\; z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(nk^2)&amp;lt;/math&amp;gt; умножений вещественных чисел).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
На макроуровне выделяем 3 основные операции:&lt;br /&gt;
&lt;br /&gt;
1. Умножение исходной матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на очередной вектор базиса &amp;lt;math&amp;gt;q_p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z=Aq_p. &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Повторное проведения процесса  Грамма-Шмидта  для ортогонализации посчитанного вектора &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt; со всеми построенными ранее векторами базиса.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i.      &amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
3.Непосредственное вычисление нового базисного вектора &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; и элементов &amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j&lt;br /&gt;
&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; \beta_{j+1}&lt;br /&gt;
&amp;lt;/math&amp;gt;  трехдиагональной матрицы.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j=q_j^Tz,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{j+1}=z/\beta_{j+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;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; q_1=b/||b||,\\&lt;br /&gt;
&amp;amp; \beta_1=0,\\&lt;br /&gt;
&amp;amp;q_0=0, \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&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;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&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;&lt;br /&gt;
1.z=Aq_j, &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j}&amp;lt;/math&amp;gt; конечной матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
2.\alpha_j=q_j^Tz,&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;&lt;br /&gt;
3.z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;4.z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,      &amp;lt;/math&amp;gt; &lt;br /&gt;
  &lt;br /&gt;
После ортогонализации процедура продолжается следующим образом.                      &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;5.z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j+1}&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;t_{j+1,j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;6.\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_{j+1}=0&amp;lt;/math&amp;gt;, то алгоритм завершается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;7.q_{j+1}=z/\beta_{j+1}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В конце каждой итерации получаем очередной вектор &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; базиса с единичной нормой, который ортогонален всем предыдущим векторам базиса,&lt;br /&gt;
&lt;br /&gt;
и элементы &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\beta_{j+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;
На &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ой итерации алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2 + n + 4nj + n + n = n^2 + 3n + 4nj&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;n(n - 1) + (n - 1) + (4n - 2)j + (n - 1) = n^2 + (n - 2) + (4n - 2)j&amp;lt;/math&amp;gt; сложений и вычитаний;&lt;br /&gt;
* одно извлечение квадратного корня.&lt;br /&gt;
&lt;br /&gt;
Всего за &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; итераций алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;(n + 3)nk + 2nk(k + 1)&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;(n^2 + n - 2)k + (2n - 1)k(k + 1)&amp;lt;/math&amp;gt; сложений и вычитаний.&lt;br /&gt;
&lt;br /&gt;
Таким образом, алгоритм имеет последовательную сложность &amp;lt;math&amp;gt;O(n^2k + nk^2)&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;
[[Файл:Lanczoc-full-orth-macro.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 1. Информационный граф алгоритма Ланцоша на уровне итераций с входными и выходными данными. In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и вектор &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), nrm — вычисление еклидовой нормы вектора, / — деление вектора на число, Iter — итерации алгоритма.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Информационный граф на уровне одной итерации с входными и выходными данными====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Файл:Lanczoc-full-orth-iter.png|thumb|1000px|center|alt=Информационный граф алгоритма Ланцоша на уровне отдельных итераций|Рисунок 2. Информационный граф итерации алгоритма Ланцоша на уровне макроопераций. In — входные данные (матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;), Out — выходные данные (&amp;lt;math&amp;gt;\alpha_j, \beta_j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;), dprod — скалярное произведение векторов, mprod — произведение матрицы на вектор, - — разность векторов, nrm — вычисление еклидовой нормы вектора, / — деление вектора на число.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Общий информационный граф===&lt;br /&gt;
[[Файл:photo.jpg]]Здесь показаны первые три итерации алгоритма, при больших итерациях граф строится аналогичным образом.&lt;br /&gt;
* Вершина черного цвета соответствует операции  &amp;lt;math&amp;gt;Aq_j,&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина красного цвета соответствует операции скалярного произведения &amp;lt;math&amp;gt;q_j^Tz&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина сиреневого цвета соответствует операции &amp;lt;math&amp;gt;z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина желтого цвета соответствует операции &amp;lt;math&amp;gt;z-\alpha_jq_j-\beta_{j-1}q_{j-1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина синего цвета соответствует операции &amp;lt;math&amp;gt;||z||&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Вершина зеленого цвета соответствует операции &amp;lt;math&amp;gt;z/\beta_j&amp;lt;/math&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22584</id>
		<title>Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22584"/>
		<updated>2017-05-03T13:06:22Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Свойства и структура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Sagak|С.А.Айвазян]], [[Участник:Kozlov_Vladimir|В.Козлов]] (Часть 1), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (компоновка и редактирование), [[Участник:ASA|А.С.Антонов]] (предварительная проверка).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
Алгоритм  Ланцоша – итерационный метод , созданный Корнелиусом Ланцошем, для нахождения собственных значений и собственных векторов симметричной матрицы. Суть алгоритма в том, что он сводит частичную проблему собственных значений симметричной вещественной матрицы  к полной проблеме собственных значений для симметричной трехдиагональной матрицы  меньшей размерности. Алгоритм применяется  к матрицам большой размерности, к которым не применимы никакие прямые методы. &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;QR&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;QL&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; — это итерационный алгоритм поиска &amp;lt;math&amp;gt;k&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;. Алгоритм применяется, когда матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; слишком велика, чтобы к ней можно было применять точные прямые методы вычисления собственных значений. Алгоритм комбинирует &#039;&#039;&#039;метод Рэлея — Ритца&#039;&#039;&#039; поиска приближённых собственных значений и &#039;&#039;&#039;метод Ланцоша&#039;&#039;&#039; построения крыловского подпространства.&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца является методом поиска &amp;lt;math&amp;gt;k&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;. Если &amp;lt;math&amp;gt;Q = [Q_k, Q_u]&amp;lt;/math&amp;gt; — ортонормированная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_k&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_u&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times n - k&amp;lt;/math&amp;gt;, то можно записать равенство&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;T = Q^T A Q = [Q_k, Q_u]^T A [Q_k, Q_u] = &lt;br /&gt;
\left[ \begin{array}{cc}&lt;br /&gt;
Q_k^T A Q_k &amp;amp; Q_k^T A Q_u\\&lt;br /&gt;
Q_u^T A Q_k &amp;amp; Q_u^T A Q_u&lt;br /&gt;
\end{array} \right]&lt;br /&gt;
= \left[ \begin{array}{cc}&lt;br /&gt;
T_{k} &amp;amp; T_{ku}^T\\&lt;br /&gt;
T_{ku} &amp;amp; T_{u}&lt;br /&gt;
\end{array} \right].&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца заключается в том, что собственные значения матрицы &amp;lt;math&amp;gt;T_k = Q_k^T A Q_k&amp;lt;/math&amp;gt; объявляются приближёнными собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Такое приближение является в некотором смысле «наилучшим»: можно показать, что если &amp;lt;math&amp;gt;T_k = V \Lambda V^{-1}&amp;lt;/math&amp;gt; — спектральное разложение &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;, то пара &amp;lt;math&amp;gt;(Q_k V, \Lambda)&amp;lt;/math&amp;gt; минимизирует функционал &amp;lt;math&amp;gt;L(P_k, D) = \Vert A P_k - P_k D \Vert_2&amp;lt;/math&amp;gt;, причём &amp;lt;math&amp;gt;L(Q_k V, \Lambda) = \Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;, то есть &amp;lt;math&amp;gt;A \approx (Q_k V) \Lambda (Q_k V)^{-1}&amp;lt;/math&amp;gt;. Из этого также видно, что метод Рэлея — Ритца позволяет получать приближения для собственных векторов матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Более того, можно показать, что собственные значения &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; отличаются от некоторых собственных значений &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не более чем на &amp;lt;math&amp;gt;\Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Метод Ланцоша — это метод построения матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, при использовании которого, во-первых, матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; оказывается симметричной трёхдиагональной, во-вторых, столбцы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются последовательно. Трёхдиагональность &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; приводит к следующим явлениям:&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; является трёхдиагональной матрицей меньшей размерности, а для трёхдиагональных матриц существуют высокоэффективные методы поиска собственных значений;&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_{ku}&amp;lt;/math&amp;gt; имеет только один ненулевой (возможно) элемент — правый верхний, а значит, для оценки погрешности полученных собственных значений достаточно знать только этот элемент.&lt;br /&gt;
&lt;br /&gt;
В теории в методе Ланцоша для вычисления каждого следующего столбца &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; достаточно знать только &amp;lt;math&amp;gt;q_{j - 1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_{j}&amp;lt;/math&amp;gt; в силу трёхдиагональности матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;. На практике из-за ошибок округления, если не предпринимать специальных мер, набор векторов &amp;lt;math&amp;gt;q_{1}, \dots, q_{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;b&amp;lt;/math&amp;gt; — начальное приближение для метода Ланцоша.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: трёхдиагональная симметричная вещественная матрица &amp;lt;math&amp;gt;T_k = \left[ \begin{array}{cccc}&lt;br /&gt;
\alpha_1 &amp;amp; \beta_1 &amp;amp; &amp;amp; \\&lt;br /&gt;
\beta_1 &amp;amp; \ddots &amp;amp; \ddots &amp;amp; \\&lt;br /&gt;
&amp;amp; \ddots &amp;amp; \ddots &amp;amp; \beta_{k - 1}\\&lt;br /&gt;
&amp;amp; &amp;amp; \beta_{k - 1} &amp;amp; \alpha_k&lt;br /&gt;
\end{array} \right]&amp;lt;/math&amp;gt;, ортонормированный набор векторов &amp;lt;math&amp;gt;q_1, \dots, q_k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;T_k = [q_1, \dots, q_k]^T A [q_1, \dots, q_k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Формулы метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{l}&lt;br /&gt;
q_1 = b / \Vert b \Vert_2\\&lt;br /&gt;
j = \overline{1, k}:\\&lt;br /&gt;
\quad z_j = A q_j \\&lt;br /&gt;
\quad \alpha_j = q_j^T A q_j = q_j^T z_j \\&lt;br /&gt;
\quad z_j&#039; = z_j - \sum_{i=1}^j (z_j^T q_i) q_i \\&lt;br /&gt;
\quad z_j&#039;&#039; = z_j&#039; - \sum_{i=1}^j (z_j&#039;^T q_i) q_i\\&lt;br /&gt;
\quad \beta_j = \Vert z_j&#039;&#039; \Vert_2\\&lt;br /&gt;
\quad q_{j+1} = z_j&#039;&#039; / \Vert z_j&#039;&#039; \Vert_2 = z_j&#039;&#039;/\beta_j&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Собственные значения и собственные векторы матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; ищутся любым прямым алгоритмом.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;z_j&#039;, z_j&#039;&#039;&amp;lt;/math&amp;gt; — это полная переортогонализация &amp;lt;math&amp;gt;z_j&amp;lt;/math&amp;gt; методом Грама — Шмидта. Двойной запуск практически гарантирует, что &amp;lt;math&amp;gt;z_j&#039;&#039;&amp;lt;/math&amp;gt; будет ортогонален &amp;lt;math&amp;gt;q_1, \dots, q_j&amp;lt;/math&amp;gt;. Заметим, что &amp;lt;math&amp;gt;\sum_{i=1}^j (z^T q_i) q_i = Q_j Q_j^T z&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_j = [q_1, \dots, q_j]&amp;lt;/math&amp;gt;, поэтому переортогонализацию можно переписать в виде &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j, z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_j = 0&amp;lt;/math&amp;gt; для какого-либо &amp;lt;math&amp;gt;j &amp;lt; k&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\Vert T_{ju}\Vert_2 = 0&amp;lt;/math&amp;gt;, а значит, собственные значения &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; в точности совпадают с каким-то собственными значениями &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. В этом случае дальнейшие вычисления прекращаются и либо используется полученная &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; размерности меньшей, чем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, либо процедура запускается заново с другим начальным вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
У алгоритма построения матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; в том виде, как он описан выше, можно выделить два ядра:&lt;br /&gt;
# умножение матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на вектор &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;z_j = A q_j&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; умножений вещественных чисел);&lt;br /&gt;
# переортогонализация: &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j,\; z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(nk^2)&amp;lt;/math&amp;gt; умножений вещественных чисел).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
На макроуровне выделяем 3 основные операции:&lt;br /&gt;
&lt;br /&gt;
1. Умножение исходной матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на очередной вектор базиса &amp;lt;math&amp;gt;q_p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z=Aq_p. &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Повторное проведения процесса  Грамма-Шмидта  для ортогонализации посчитанного вектора &amp;lt;math&amp;gt;z&amp;lt;/math&amp;gt; со всеми построенными ранее векторами базиса.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i.      &amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
3.Непосредственное вычисление нового базисного вектора &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; и элементов &amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j&lt;br /&gt;
&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt; \beta_{j+1}&lt;br /&gt;
&amp;lt;/math&amp;gt;  трехдиагональной матрицы.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\alpha_j=q_j^Tz,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{j+1}=z/\beta_{j+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;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
&amp;amp; q_1=b/||b||,\\&lt;br /&gt;
&amp;amp; \beta_1=0,\\&lt;br /&gt;
&amp;amp;q_0=0, \\&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&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;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&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;&lt;br /&gt;
1.z=Aq_j, &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j}&amp;lt;/math&amp;gt; конечной матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
2.\alpha_j=q_j^Tz,&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;&lt;br /&gt;
3.z =z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,     &amp;lt;/math&amp;gt;  &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;math&amp;gt;4.z=z-\sum\nolimits_{i=1}^{j-1}(z^Tq_i)q_i,      &amp;lt;/math&amp;gt; &lt;br /&gt;
  &lt;br /&gt;
После ортогонализации процедура продолжается следующим образом.                      &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;5.z=z-\alpha_jq_j-\beta_{j}q_{j-1}, &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляем элемент, который будет находится на позиции &amp;lt;math&amp;gt;t_{j,j+1}&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;t_{j+1,j}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;6.\beta_{j+1}=||z||,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_{j+1}=0&amp;lt;/math&amp;gt;, то алгоритм завершается.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;7.q_{j+1}=z/\beta_{j+1}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В конце каждой итерации получаем очередной вектор &amp;lt;math&amp;gt;q_{j+1}&amp;lt;/math&amp;gt; базиса с единичной нормой, который ортогонален всем предыдущим векторам базиса,&lt;br /&gt;
&lt;br /&gt;
и элементы &amp;lt;math&amp;gt;\alpha_j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\beta_{j+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;
На &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-ой итерации алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2 + n + 4nj + n + n = n^2 + 3n + 4nj&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;n(n - 1) + (n - 1) + (4n - 2)j + (n - 1) = n^2 + (n - 2) + (4n - 2)j&amp;lt;/math&amp;gt; сложений и вычитаний;&lt;br /&gt;
* одно извлечение квадратного корня.&lt;br /&gt;
&lt;br /&gt;
Всего за &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; итераций алгоритм выполняет&lt;br /&gt;
* &amp;lt;math&amp;gt;(n + 3)nk + 2nk(k + 1)&amp;lt;/math&amp;gt; умножений и делений;&lt;br /&gt;
* &amp;lt;math&amp;gt;(n^2 + n - 2)k + (2n - 1)k(k + 1)&amp;lt;/math&amp;gt; сложений и вычитаний.&lt;br /&gt;
&lt;br /&gt;
Таким образом, алгоритм имеет последовательную сложность &amp;lt;math&amp;gt;O(n^2k + nk^2)&amp;lt;/math&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22583</id>
		<title>Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22583"/>
		<updated>2017-05-03T13:02:13Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Свойства и структура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Sagak|С.А.Айвазян]], [[Участник:Kozlov_Vladimir|В.Козлов]] (Часть 1), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (компоновка и редактирование), [[Участник:ASA|А.С.Антонов]] (предварительная проверка).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
Алгоритм  Ланцоша – итерационный метод , созданный Корнелиусом Ланцошем, для нахождения собственных значений и собственных векторов симметричной матрицы. Суть алгоритма в том, что он сводит частичную проблему собственных значений симметричной вещественной матрицы  к полной проблеме собственных значений для симметричной трехдиагональной матрицы  меньшей размерности. Алгоритм применяется  к матрицам большой размерности, к которым не применимы никакие прямые методы. &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;QR&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;QL&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; — это итерационный алгоритм поиска &amp;lt;math&amp;gt;k&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;. Алгоритм применяется, когда матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; слишком велика, чтобы к ней можно было применять точные прямые методы вычисления собственных значений. Алгоритм комбинирует &#039;&#039;&#039;метод Рэлея — Ритца&#039;&#039;&#039; поиска приближённых собственных значений и &#039;&#039;&#039;метод Ланцоша&#039;&#039;&#039; построения крыловского подпространства.&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца является методом поиска &amp;lt;math&amp;gt;k&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;. Если &amp;lt;math&amp;gt;Q = [Q_k, Q_u]&amp;lt;/math&amp;gt; — ортонормированная матрица размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_k&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times k&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q_u&amp;lt;/math&amp;gt; имеет размер &amp;lt;math&amp;gt;n \times n - k&amp;lt;/math&amp;gt;, то можно записать равенство&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;T = Q^T A Q = [Q_k, Q_u]^T A [Q_k, Q_u] = &lt;br /&gt;
\left[ \begin{array}{cc}&lt;br /&gt;
Q_k^T A Q_k &amp;amp; Q_k^T A Q_u\\&lt;br /&gt;
Q_u^T A Q_k &amp;amp; Q_u^T A Q_u&lt;br /&gt;
\end{array} \right]&lt;br /&gt;
= \left[ \begin{array}{cc}&lt;br /&gt;
T_{k} &amp;amp; T_{ku}^T\\&lt;br /&gt;
T_{ku} &amp;amp; T_{u}&lt;br /&gt;
\end{array} \right].&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Метод Рэлея — Ритца заключается в том, что собственные значения матрицы &amp;lt;math&amp;gt;T_k = Q_k^T A Q_k&amp;lt;/math&amp;gt; объявляются приближёнными собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Такое приближение является в некотором смысле «наилучшим»: можно показать, что если &amp;lt;math&amp;gt;T_k = V \Lambda V^{-1}&amp;lt;/math&amp;gt; — спектральное разложение &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt;, то пара &amp;lt;math&amp;gt;(Q_k V, \Lambda)&amp;lt;/math&amp;gt; минимизирует функционал &amp;lt;math&amp;gt;L(P_k, D) = \Vert A P_k - P_k D \Vert_2&amp;lt;/math&amp;gt;, причём &amp;lt;math&amp;gt;L(Q_k V, \Lambda) = \Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;, то есть &amp;lt;math&amp;gt;A \approx (Q_k V) \Lambda (Q_k V)^{-1}&amp;lt;/math&amp;gt;. Из этого также видно, что метод Рэлея — Ритца позволяет получать приближения для собственных векторов матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Более того, можно показать, что собственные значения &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; отличаются от некоторых собственных значений &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не более чем на &amp;lt;math&amp;gt;\Vert T_{ku} \Vert_2&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Метод Ланцоша — это метод построения матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, при использовании которого, во-первых, матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; оказывается симметричной трёхдиагональной, во-вторых, столбцы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются последовательно. Трёхдиагональность &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; приводит к следующим явлениям:&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; является трёхдиагональной матрицей меньшей размерности, а для трёхдиагональных матриц существуют высокоэффективные методы поиска собственных значений;&lt;br /&gt;
# матрица &amp;lt;math&amp;gt;T_{ku}&amp;lt;/math&amp;gt; имеет только один ненулевой (возможно) элемент — правый верхний, а значит, для оценки погрешности полученных собственных значений достаточно знать только этот элемент.&lt;br /&gt;
&lt;br /&gt;
В теории в методе Ланцоша для вычисления каждого следующего столбца &amp;lt;math&amp;gt;q_{j + 1}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; достаточно знать только &amp;lt;math&amp;gt;q_{j - 1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;q_{j}&amp;lt;/math&amp;gt; в силу трёхдиагональности матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;. На практике из-за ошибок округления, если не предпринимать специальных мер, набор векторов &amp;lt;math&amp;gt;q_{1}, \dots, q_{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;b&amp;lt;/math&amp;gt; — начальное приближение для метода Ланцоша.&lt;br /&gt;
&lt;br /&gt;
Выходные данные: трёхдиагональная симметричная вещественная матрица &amp;lt;math&amp;gt;T_k = \left[ \begin{array}{cccc}&lt;br /&gt;
\alpha_1 &amp;amp; \beta_1 &amp;amp; &amp;amp; \\&lt;br /&gt;
\beta_1 &amp;amp; \ddots &amp;amp; \ddots &amp;amp; \\&lt;br /&gt;
&amp;amp; \ddots &amp;amp; \ddots &amp;amp; \beta_{k - 1}\\&lt;br /&gt;
&amp;amp; &amp;amp; \beta_{k - 1} &amp;amp; \alpha_k&lt;br /&gt;
\end{array} \right]&amp;lt;/math&amp;gt;, ортонормированный набор векторов &amp;lt;math&amp;gt;q_1, \dots, q_k&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;T_k = [q_1, \dots, q_k]^T A [q_1, \dots, q_k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Формулы метода:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{array}{l}&lt;br /&gt;
q_1 = b / \Vert b \Vert_2\\&lt;br /&gt;
j = \overline{1, k}:\\&lt;br /&gt;
\quad z_j = A q_j \\&lt;br /&gt;
\quad \alpha_j = q_j^T A q_j = q_j^T z_j \\&lt;br /&gt;
\quad z_j&#039; = z_j - \sum_{i=1}^j (z_j^T q_i) q_i \\&lt;br /&gt;
\quad z_j&#039;&#039; = z_j&#039; - \sum_{i=1}^j (z_j&#039;^T q_i) q_i\\&lt;br /&gt;
\quad \beta_j = \Vert z_j&#039;&#039; \Vert_2\\&lt;br /&gt;
\quad q_{j+1} = z_j&#039;&#039; / \Vert z_j&#039;&#039; \Vert_2 = z_j&#039;&#039;/\beta_j&lt;br /&gt;
\end{array}&lt;br /&gt;
&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Собственные значения и собственные векторы матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; ищутся любым прямым алгоритмом.&lt;br /&gt;
&lt;br /&gt;
Вычисление &amp;lt;math&amp;gt;z_j&#039;, z_j&#039;&#039;&amp;lt;/math&amp;gt; — это полная переортогонализация &amp;lt;math&amp;gt;z_j&amp;lt;/math&amp;gt; методом Грама — Шмидта. Двойной запуск практически гарантирует, что &amp;lt;math&amp;gt;z_j&#039;&#039;&amp;lt;/math&amp;gt; будет ортогонален &amp;lt;math&amp;gt;q_1, \dots, q_j&amp;lt;/math&amp;gt;. Заметим, что &amp;lt;math&amp;gt;\sum_{i=1}^j (z^T q_i) q_i = Q_j Q_j^T z&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;Q_j = [q_1, \dots, q_j]&amp;lt;/math&amp;gt;, поэтому переортогонализацию можно переписать в виде &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j, z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\beta_j = 0&amp;lt;/math&amp;gt; для какого-либо &amp;lt;math&amp;gt;j &amp;lt; k&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\Vert T_{ju}\Vert_2 = 0&amp;lt;/math&amp;gt;, а значит, собственные значения &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; в точности совпадают с каким-то собственными значениями &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. В этом случае дальнейшие вычисления прекращаются и либо используется полученная &amp;lt;math&amp;gt;T_j&amp;lt;/math&amp;gt; размерности меньшей, чем &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;, либо процедура запускается заново с другим начальным вектором &amp;lt;math&amp;gt;b&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
У алгоритма построения матрицы &amp;lt;math&amp;gt;T_k&amp;lt;/math&amp;gt; в том виде, как он описан выше, можно выделить два ядра:&lt;br /&gt;
# умножение матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на вектор &amp;lt;math&amp;gt;q_j&amp;lt;/math&amp;gt;: &amp;lt;math&amp;gt;z_j = A q_j&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; умножений вещественных чисел);&lt;br /&gt;
# переортогонализация: &amp;lt;math&amp;gt;z&#039;_j = z_j - Q_j Q_j^T z_j,\; z_j&#039;&#039; = z_j&#039; - Q_j Q_j^T z_j&#039;&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;O(nk^2)&amp;lt;/math&amp;gt; умножений вещественных чисел).&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22582</id>
		<title>Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22582"/>
		<updated>2017-05-03T12:59:59Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Sagak|С.А.Айвазян]], [[Участник:Kozlov_Vladimir|В.Козлов]] (Часть 1), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (компоновка и редактирование), [[Участник:ASA|А.С.Антонов]] (предварительная проверка).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
===Общее описание алгоритма===&lt;br /&gt;
Алгоритм  Ланцоша – итерационный метод , созданный Корнелиусом Ланцошем, для нахождения собственных значений и собственных векторов симметричной матрицы. Суть алгоритма в том, что он сводит частичную проблему собственных значений симметричной вещественной матрицы  к полной проблеме собственных значений для симметричной трехдиагональной матрицы  меньшей размерности. Алгоритм применяется  к матрицам большой размерности, к которым не применимы никакие прямые методы. &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;QR&amp;lt;/math&amp;gt; и  &amp;lt;math&amp;gt;QL&amp;lt;/math&amp;gt; преобразования, методы вращений (вращения Якоби), которые потеряли значение как самостоятельные методы поиска собственных&lt;br /&gt;
значений  матриц большого размера. Также нужно заметить, что метод Ланцоша практически всегда  эффективнее  других методов аппроксимаций.&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22581</id>
		<title>Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22581"/>
		<updated>2017-05-03T12:47:47Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: Новая страница: «Основные авторы описания: С.А.Айвазян, В.Козлов (Часть…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Sagak|С.А.Айвазян]], [[Участник:Kozlov_Vladimir|В.Козлов]] (Часть 1), [[Участник:Chernyavskiy|А.Ю.Чернявский]] (компоновка и редактирование), [[Участник:ASA|А.С.Антонов]] (предварительная проверка).&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22580</id>
		<title>Метод «разделяй и властвуй» вычисления собственных значений и векторов симметричной трехдиагональной матрицы</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22580"/>
		<updated>2017-04-29T20:44:24Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Роман_Землянский|Р.Землянский]] (Разделы &lt;br /&gt;
[[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]]), В.Завольсков (Разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Существующие реализации алгоритма|2.7]]), [[Участник:IgorS]] (предварительная проверка), [[Участник:Chernyavskiy|А.Ю. Чернявский]] (проверка, редактирование).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод &amp;quot;Разделяй и властвуй&amp;quot; вычисления собственных значений и векторов трёхдиагональной матрицы&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt; c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt; O(n^{2.3}) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
крайне редко: &amp;lt;math&amp;gt;  O(n^{2}) &amp;lt;/math&amp;gt; &lt;br /&gt;
| pf_width          = &lt;br /&gt;
| input_data        =  &amp;lt;math&amp;gt; 2n + 1 &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       =  &amp;lt;math&amp;gt; n(n + 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; - это наиболее быстрый из существующих методов, если нужны все собственные значения и собственные векторы трехдиагональной матрицы, начиная с порядка n, примерно равного 26. (Точное значение этого порогового порядка зависит от компьютера.) Его численно устойчивая реализация весьма не тривиальна. В самом деле, хотя впервые метод был предложен еще в 1981 г., &amp;quot;правильный&amp;quot; способ его реализации был найден лишь в 1992 г. Этот способ воплощен LAPACK-программами ssyevd (для плотных матриц) и sstevd (для трехдиагональных матриц). В них стратегия &amp;quot;разделяй-и-влавствуй&amp;quot; используется для матриц порядка, большего чем 25. Для матриц меньшего порядка (или если нужны только собственные значения) происходит автоматический переход к QR-итерации.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Пусть &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
T = \begin{bmatrix}&lt;br /&gt;
 a_{1} &amp;amp; b_{1}&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp; b_{m} &amp;amp; a_{m+1} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
= \begin{bmatrix}&lt;br /&gt;
  a_{1} &amp;amp; b_{1} &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} - b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; a_{m+1} - b_{m} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix} +&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
+ \begin{bmatrix}&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 &amp;amp;&amp;amp;b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&lt;br /&gt;
= \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m} * \begin{bmatrix} 0 \\ \vdots \\ 0 \\ 1 \\ 1 \\ 0 \\ \vdots \\ 0 \end{bmatrix} \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix} &lt;br /&gt;
&lt;br /&gt;
\equiv \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Предположим, что нам известны спектральные разложения матриц &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; T_{2} &amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; T_{i} = Q_{i} \Lambda_{i} Q_{i}^{T} &amp;lt;/math&amp;gt;. В действительности, они будут рекурсивно вычисляться тем же самым алгоритмом. Установим связь между собственными значениями матрицы Т и собственными значениями матриц&lt;br /&gt;
&amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;. Имеем:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt; &lt;br /&gt;
T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} \Lambda_{1} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2} \Lambda_{2} Q_{2}^{T}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}(\begin{bmatrix} \Lambda_{1} &amp;amp; \\  &amp;amp; \Lambda_{2}\end{bmatrix} + b_{m}uu^{T})\begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}&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;&lt;br /&gt;
u = \begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}v&lt;br /&gt;
  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
так как &amp;lt;math&amp;gt;v = \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix}^T&amp;lt;/math&amp;gt;, получим матрицу, состоящую из последнего столбца матрицы &amp;lt;math&amp;gt; Q_{1}^{T}&amp;lt;/math&amp;gt; и первого столбца матрицы &amp;lt;math&amp;gt; Q_{2}^{T}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Следовательно, &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; имеет те же собственные значения, что и подобная ей матрица &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;D = \begin{bmatrix} \Lambda_{1} &amp;amp; 0 \\ 0 &amp;amp; \Lambda_{2}\end{bmatrix}&amp;lt;/math&amp;gt; - диагональная матрица, &lt;br /&gt;
&amp;lt;math&amp;gt;\rho = b_{m}&amp;lt;/math&amp;gt; - число, а &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - вектор. &lt;br /&gt;
&lt;br /&gt;
Будем предполагать, не ограничивая общности, что диагональные элементы &amp;lt;math&amp;gt;d_{1}, \ldots, d_{n}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; упорядочены по убыванию: &amp;lt;math&amp;gt;d_{n} &amp;lt;= \ldots &amp;lt;=d_{1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Чтобы найти собственные значения матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, вычислим её характеристический многочлен, считая пока матрицу &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденной.&lt;br /&gt;
Тогда&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;det(D + \rho uu^{T} - \lambda I) = det((D - \lambda I)(I + \rho (D- \lambda I)^{-1} uu^{T}))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Поскольку &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденна, &amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 0&amp;lt;/math&amp;gt; тогда и только тогда, когда &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; - собственное значение. Заметим, что матрица &amp;lt;math&amp;gt;I + \rho (D - \lambda I)^{-1}uu^{T}&amp;lt;/math&amp;gt; получается из единичной добавлением матрицы ранга 1. Определитель такой матрицы легко вычислить.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;&#039;Лемма 1.&#039;&#039;&#039; Справедливо равенство &amp;lt;math&amp;gt;det(I + xy^{T}) = 1 + y^{T}x&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; - векторы.&lt;br /&gt;
&lt;br /&gt;
Таким образом,&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 1 + \rho u^{T}(D - \lambda I)^{-1}u&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; = 1 + \rho \sum_{i=1, n} \frac{u_{i}^{2}} {d_{i}-\lambda} \equiv f(\lambda)&amp;lt;/math&amp;gt; , &lt;br /&gt;
&lt;br /&gt;
т.е. собственные значения матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; есть корни так называемого векового уравнения &amp;lt;math&amp;gt;f(\lambda) = 0&amp;lt;/math&amp;gt;. Если все числа &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; различны и все &amp;lt;math&amp;gt;u_{i} &amp;lt;&amp;gt; 0&amp;lt;/math&amp;gt; (случай общего положения), то &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; имеет график типа показанного на рис.1(где &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\rho &amp;gt; 0&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
[[File:Graphics.PNG|thumb|center|800px|Рис. 1. График функции &amp;lt;math&amp;gt; f(\lambda) = 1 + \frac{0.5}{1 - \lambda} + \frac{0.5}{2 - \lambda} + \frac{0.5}{3 - \lambda} + \frac{0.5}{4 - \lambda}&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Можно видеть, что прямая &amp;lt;math&amp;gt;y = 1&amp;lt;/math&amp;gt; является горизонтальной асимптотой для этого графика, а прямые &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt; есть вертикальные асимптоты. Поскольку &amp;lt;math&amp;gt;f^{&#039;}(\lambda) =  \rho \sum_{i=1, n} \frac{u_{i}^{2}} {(d_{i}-\lambda)^{2}}&amp;gt; 0 &amp;lt;/math&amp;gt;, функция возрастает всюду, кроме точек &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt;. Поэтому корни функции разделяются числами &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; и ещё один корень находится справа от точки &amp;lt;math&amp;gt;d_{1}&amp;lt;/math&amp;gt; (на рис. 1 &amp;lt;math&amp;gt;d_{1} = 4&amp;lt;/math&amp;gt;). (При &amp;lt;math&amp;gt;\rho&amp;lt;0&amp;lt;/math&amp;gt; функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; всюду убывает и соответствующий корень находится слева от точки &amp;lt;math&amp;gt;d_{n}&amp;lt;/math&amp;gt;). Для функции &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt;, монотонной и гладкой на каждом из интервалов &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;, можно найти вариант метода Ньютона, который быстро и монотонно сходится к каждому из корней, если начальная точка взята в &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;. Нам достаточно знать, что на практике метод сходится к каждому собственному значению за ограниченное число шагов. Поскольку вычисление &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;f^{&#039;}(\lambda)&amp;lt;/math&amp;gt; стоит &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов, для вычисления одного собственного значения достаточно &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, а для вычисления всех &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; собственных значений матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt;O(n^{2})&amp;lt;/math&amp;gt; флопов.&lt;br /&gt;
Для собственных векторов матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; мы легко можем получить явные выражения.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;&#039;Лемма 2.&#039;&#039;&#039; Если &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - собственное значение матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, то соответствующий вектор равен &amp;lt;math&amp;gt;(D - \alpha I)^{-1}u&amp;lt;/math&amp;gt;. Поскольку матрица &amp;lt;math&amp;gt;D - \alpha I&amp;lt;/math&amp;gt; диагональная, для вычисления такого вектора достаточно &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов.&lt;br /&gt;
&lt;br /&gt;
Доказательство.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;(D + \rho uu^{T})[(D - \alpha I)^{-1}u] = (D - \alpha I + \alpha I + \rho uu^{T})(D - \alpha I)^{-1}u&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=u + \alpha (D - \alpha I)^{-1}u + u[\rho u^{T}(D - \alpha I)^{-1}u] &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=u + \alpha(D - \alpha I)^{-1}u - u&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
                                                       поскольку &amp;lt;math&amp;gt; \rho u^{T}(D - \alpha I)^{-1}u + 1 = f(\alpha) = 0 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=\alpha [(D - \alpha I)^{-1}u]&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; собственных векторов требуется &amp;lt;math&amp;gt;O(n^{2})&amp;lt;/math&amp;gt; флопов. К сожалению, формула не обеспечивает численной устойчивости, так как для двух очень близких значений &amp;lt;math&amp;gt;\alpha_{i}&amp;lt;/math&amp;gt; может давать неортогональные приближенные собственные векторы &amp;lt;math&amp;gt;u_{i}&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;d_{i}&amp;lt;/math&amp;gt; различны и все &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt; отличны от нуля. Если это не так, вековое уравнение &amp;lt;math&amp;gt;f(\lambda)=0&amp;lt;/math&amp;gt; имеет &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вертикальных асимптот, где &amp;lt;math&amp;gt;k&amp;lt;n&amp;lt;/math&amp;gt;, а потому &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; корней. Однако оказывается, что остальные &amp;lt;math&amp;gt;n - k&amp;lt;/math&amp;gt; собственных значений могут быть определены без каких-либо усилий: если &amp;lt;math&amp;gt;d_{i}=d_{i+1}&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;u_{i}=0&amp;lt;/math&amp;gt;, то легко показать, что &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; является собственным значением и для матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;. В такой ситуации мы говорим о &#039;&#039;дефляции&#039;&#039;. На практике выбирается некоторое пороговое значение и дефляция для числа &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; регистрируется, если в смысле этого порога &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; достаточно близко к &amp;lt;math&amp;gt;d_{i+1}&amp;lt;/math&amp;gt; либо &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&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;u_{i}=0&amp;lt;/math&amp;gt;, то соответствующий собственный вектор есть i-й столбец &amp;lt;math&amp;gt;e_{i}&amp;lt;/math&amp;gt; единичной матрицы. Это означает, что &amp;lt;math&amp;gt;e_{i}&amp;lt;/math&amp;gt; является i-м столбцом в матрице &amp;lt;math&amp;gt;Q_{&#039;}&amp;lt;/math&amp;gt;, поэтому при формировании матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; посредством левого умножения &amp;lt;math&amp;gt;Q_{1}&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;Q_{2}&amp;lt;/math&amp;gt; вычисление i-го столбца не требует никаких затрат. Аналогичное упрощение имеет место в случае &amp;lt;math&amp;gt;d_{i} = d_{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;
Предположим, что некоторое &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt;, хотя и мало, все же недостаточно мало для того, чтобы была зарегистрирована дефляция. В этом случае применение метода Ньютона к решению векового уравнения встречается с затруднениями. Вспомним, что пересчет приближённого решения &amp;lt;math&amp;gt;u_{j}&amp;lt;/math&amp;gt; уравнения &amp;lt;math&amp;gt;f(\lambda) = 0&amp;lt;/math&amp;gt; в методе Ньютона основан на следующих положениях:&lt;br /&gt;
&lt;br /&gt;
 1. Вблизи точки &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt; функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; аппроксимируется линейной функцией &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt;; график есть прямая линия, касающаяся графика функции &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 2. В качестве &amp;lt;math&amp;gt;\lambda_{j+1}&amp;lt;/math&amp;gt; берётся нуль этого линейного приближения, т.е. &amp;lt;math&amp;gt;l(\lambda_{j+1})=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Функция, показанная на рис.1, не доставляет видимых трудностей методу Ньютона, поскольку вблизи каждого своего нуля &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; достаточно хорошо аппроксимируется линейными функциями. Однако рассмотрим график функции на рис.2. Она получена из функции на рис. 1 заменой значения .5 для &amp;lt;math&amp;gt;u_{i}^{2}&amp;lt;/math&amp;gt; на .001. Это новое значение недостаточно мало для того, чтобы вызвать дефляцию. График функции в левой части рис.2 визуально не отличим от её вертикальных и горизонтальных асимптот, поэтому в правой части укрупненно воспроизведён фрагмент графика, прилегающий к вертикальной асимптоте &amp;lt;math&amp;gt;\lambda = 2&amp;lt;/math&amp;gt;. Видно, что график слишком быстро &amp;quot;выполняет поворот&amp;quot; и для большей части значений &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; почти горизонтален. Поэтому, применяя метод Ньютона почти к любому начальному приближению &amp;lt;math&amp;gt;\lambda_{0}&amp;lt;/math&amp;gt;, мы получаем линейное приближение &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt; с почти горизонтальным графиком и малым положительным угловым коэффициентом. В результате &amp;lt;math&amp;gt;\lambda_{1}&amp;lt;/math&amp;gt; является отрицательным числом, огромным по абсолютной величине, которое совершенно бесполезно в качестве приближения к истинному корню.&lt;br /&gt;
&lt;br /&gt;
[[File:GraphNewton.png|thumb|center|800px|Рис. 2. График функции &amp;lt;math&amp;gt; f(\lambda) = 1 + \frac{10^{-3}}{1 - \lambda} + \frac{10^{-3}}{2 - \lambda} + \frac{10^{-3}}{3 - \lambda} + \frac{10^{-3}}{4 - \lambda}&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Чтобы найти выход из этого положения, можно модифицировать метод Ньютона следующим образом: раз &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; нельзя хорошо приблизить линейной функцией &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt;, попробуем взять в качестве приближения какую-нибудь другую простую функцию &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;. Нет ничего особого именно в прямых линиях: для метода Ньютона вместо &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt; можно взять любое приближение &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;, значения и нули которого легко вычисляются. Функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; имеет полюсы в точках &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;d_{i+1}&amp;lt;/math&amp;gt;, которые определяют её поведение в соответствующих окрестностях. Поэтому при поиске корня в интервале &amp;lt;math&amp;gt;(d_{i+1}, d_{i})&amp;lt;/math&amp;gt; естественно выбрать функцию &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;, также имеющую эти полюсы, т.е. функцию вида&lt;br /&gt;
 &amp;lt;math&amp;gt;h(\lambda)= \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} + c_{3}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Константы &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; обеспечивающие, что &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt; есть приближение к &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt;, можно выбрать несколькими способами. Отметим, что если &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; уже известны, то уравнение &amp;lt;math&amp;gt;h(\lambda)=0&amp;lt;/math&amp;gt; легко решается относительно &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt;, поскольку сводится к эквивалентному квадратному уравнению&lt;br /&gt;
 &amp;lt;math&amp;gt;c_{1}(d_{i+1}-\lambda)+c_{2}(d_{i}-\lambda)+c_{3}(d_{i}-\lambda)(d_{i+1}-\lambda)=0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;\lambda_{j}&amp;lt;/math&amp;gt; - приближённое значение корня. определим &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; так, чтобы&lt;br /&gt;
 &amp;lt;math&amp;gt;\frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} + c_{3} = h(\lambda) \approx f(\lambda) = 1 + \rho \sum_{k=1, n} \frac{u_{k}^{2}} {d_{k}-\lambda} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
для &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; в окрестности &amp;lt;math&amp;gt;\lambda_{j}&amp;lt;/math&amp;gt;. Заметим, что&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;f(\lambda) = 1 + \rho \sum_{k=1, i} \frac{u_{k}^{2}} {d_{k}-\lambda} + \rho \sum_{k=i+1, n} \frac{u_{k}^{2}} {d_{k}-\lambda} \equiv 1 + \psi_{1}(\lambda) + \psi_{2}(\lambda)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\lambda \in (d_{i+1},d_{i})&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\psi_{1}(\lambda)&amp;lt;/math&amp;gt; есть сумма положительных слагаемых, а &amp;lt;math&amp;gt;\psi_{2}(\lambda)&amp;lt;/math&amp;gt; - сумма отрицательных. Поэтому и &amp;lt;math&amp;gt;\psi_{1}(\lambda)&amp;lt;/math&amp;gt;, и &amp;lt;math&amp;gt;\psi_{2}(\lambda)&amp;lt;/math&amp;gt; могут быть вычислены с высокой точностью; однако при их сложении вполне вероятно взаимное уничтожение верных разрядов и потеря относительной точности в сумме. Возьмем числа &amp;lt;math&amp;gt;c_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{1}}&amp;lt;/math&amp;gt;, такие, что функция &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h_{1}(\lambda) \equiv \hat{c_{1}} + \frac{c_{1}}{d_{i}-\lambda}&amp;lt;/math&amp;gt;   удовлетворяет условиям  &amp;lt;math&amp;gt;h_{1}(\lambda_{j}) = \psi_{1}(\lambda_{j})&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;h_{1}^{&#039;}(\lambda_{j})=\psi_{1}^{&#039;}(\lambda_{j})&amp;lt;/math&amp;gt; (1)&lt;br /&gt;
&lt;br /&gt;
Это означает, что гипербола, являющаяся графиком функции &amp;lt;math&amp;gt;h_{1}(\lambda)&amp;lt;/math&amp;gt;, касается графика функции &amp;lt;math&amp;gt;\psi_{i}(\lambda)&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt;. Два условия в (1) - это обычные условия метода Ньютона, за исключением того, что вместо прямой в качестве приближения используется гипербола. Легко проверить, что &amp;lt;math&amp;gt;c_{1}=\psi_{1}^{&#039;}(\lambda_{j})(d_{i} - \lambda_{j})^{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{1}}=\psi_{1}(\lambda_{j}) - \psi_{1}^{&#039;}(\lambda_{j})(d_{i} - \lambda_{j})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подобным же образом выбираем &amp;lt;math&amp;gt;c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{2}}&amp;lt;/math&amp;gt; так, чтобы функция &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h_{2}(\lambda) \equiv \hat{c_{2}} + \frac{c_{2}}{d_{i+1}-\lambda}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Удовлетворяла условиям&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;h_{2}(\lambda_{j}) = \psi_{2}(\lambda_{j})&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;h_{2}^{&#039;}(\lambda_{j})=\psi_{2}^{&#039;}(\lambda_{j})&amp;lt;/math&amp;gt; (2)&lt;br /&gt;
&lt;br /&gt;
Наконец, полагаем&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h(\lambda) = 1 + h_{1}(\lambda) + h_{2}(\lambda) = (1 + \hat{c_{1}} + \hat{c_{2}} + \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;\equiv c_{3} + \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром последовательной схемы решения является вычисление матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; собственных векторов путём умножения матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; Данная операция имеет сложность &amp;lt;math&amp;gt;cn^{3}&amp;lt;/math&amp;gt; о чём и говорится в разделе [[#Последовательная сложность алгоритма]] .&lt;br /&gt;
Ей предшествует вычисление собственных значений и векторов матрицы &amp;lt;math&amp;gt; D + \rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Ниже описана структура алгоритма, в которой есть блок умножения матриц для вычисления собственных векторов, являющийся вычислительным ядром алгоритма. В соответствующем разделе ([[#Вычислительное ядро алгоритма]]) мы упоминали о том, что данному блоку предшествует вычисление собственных значений, которое производится [https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%9D%D1%8C%D1%8E%D1%82%D0%BE%D0%BD%D0%B0 методом Ньютона].&lt;br /&gt;
&lt;br /&gt;
[[File:DivideAndConquerTree.png|thumb|center|left|800px|Рис. 3. Дерево алгоритма &amp;quot;Разделяй и властвуй&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
[[File:InfoGraph.jpg|thumb|center|1200px|Рис. 4. Детальное описание одного блока алгоритма]]&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&#039;&#039;Вычисление собственных значений и собственных векторов симметричной трехдиагональной матрицы посредством стратегии &amp;quot;разделяй и властвуй&amp;quot;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;proc dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T,Q,\Lambda)...&amp;lt;/math&amp;gt; по входной матрице &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются выходные матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;T = Q\Lambda Q^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Если &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - матрица размера &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; x &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  1. Присвоить выходным параметрам значения &amp;lt;math&amp;gt; Q = 1, \Lambda = T&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Иначе&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  1. Представить &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; в виде &amp;lt;math&amp;gt; T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  2. &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{1},Q_{1},\Lambda_{1})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  3. &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{2},Q_{2},\Lambda_{2})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  4. Построить &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt; по &amp;lt;math&amp;gt; \Lambda_{1},\Lambda_{2}, Q_{1}, Q_{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  5. Найти матрицу собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  6. Найти матрицу собственных векторов &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  7. Построить матрицу собственных векторов &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; : &amp;lt;math&amp;gt; Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}* Q^{&#039;} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  8. Присвоить выходным параметрам значения &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;endif&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Проанализируем сложность алгоритма. Пусть &amp;lt;math&amp;gt;t(n)&amp;lt;/math&amp;gt; - число флопов при обработке матрицы размера &amp;lt;math&amp;gt; n x n&amp;lt;/math&amp;gt; процедурой &#039;&#039;dc_eig&#039;&#039;. Тогда &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; t(n) = 2t(n/2) &amp;lt;/math&amp;gt; два рекурсивных обращения к &#039;&#039;dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{i},Q_{i},\Lambda_{i})&amp;lt;/math&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;D+\rho uu^{T}&amp;lt;/math&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;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; +c*n^{3}&amp;lt;/math&amp;gt; вычисление матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}*Q^{&#039;}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; Q_{1}, Q_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; рассматриваются как плотные матрицы и используется стандартный алгоритм матричного умножения, то константа &amp;lt;math&amp;gt; c &amp;lt;/math&amp;gt; в последней строке равна 1. Таким образом, именно это умножение составляет наиболее трудоёмкую часть алгоритма в целом. Игнорируя члены порядка &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;, получаем &amp;lt;math&amp;gt;t(n) = 2t(n/2) + cn^{3}&amp;lt;/math&amp;gt;. Решая это разностное уравнение, находим &amp;lt;math&amp;gt; t \approx c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На практике константа &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; обычно гораздо меньше 1, потому что матрица &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; весьма разрежена вследствие явления, называемого дефляцией.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
В данном разделе на рисунке 5 представлен информационный граф алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[File:InfoGraphSC.jpg|thumb|center|left|1200px|Рис. 5. Информационный граф алгоритма &amp;quot;Разделяй и властвуй&amp;quot; - шаг &amp;lt;b&amp;gt;Divide&amp;lt;/b&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Операции: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; - операция Divide разделения матрицы &amp;lt;math&amp;gt; T &amp;lt;/math&amp;gt; на матрицы &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Индексы - размерность &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{k}&amp;lt;/math&amp;gt; - операция Conquer сбора матрицы &amp;lt;math&amp;gt; D &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_{k} &amp;lt;/math&amp;gt; - операция поиска собственных значений &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; S^{&#039;} &amp;lt;/math&amp;gt; - операция поиска собственных векторов матрицы &amp;lt;math&amp;gt; Q^{&#039;} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; S &amp;lt;/math&amp;gt; - операция поиска собственных векторов матрицы &amp;lt;math&amp;gt; Q &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Рассмотрев информационный граф алгоритма, можно заметить, что в структуре имеется два параллельных блока - вызов рекурсивных функций &#039;&#039;dc_eig&#039;&#039; для вычисления собственных значений и векторов матриц &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&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;dc_eig&#039;&#039; отрабатывают последовательно - сначала со входными параметрами &amp;lt;math&amp;gt;T_{1}, Q_{1}, \Lambda_{1}&amp;lt;/math&amp;gt;, затем - &amp;lt;math&amp;gt;T_{2}, Q_{2}, \Lambda_{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, благодаря параллелизму высота алгоритма параллельного составляет &amp;lt;math&amp;gt;log_{2}(n)&amp;lt;/math&amp;gt;, когда как при последовательной реализации высота алгоритма равна сумме геометрической прогрессии &amp;lt;math&amp;gt;1+2+4+8+...+2^{n-1} = 2^{n} - 1&amp;lt;/math&amp;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;
&amp;lt;math&amp;gt;&lt;br /&gt;
L = \begin{bmatrix}&lt;br /&gt;
 a_{1} &amp;amp; b_{1}&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp; b_{m} &amp;amp; a_{m+1} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&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;2n + 1&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; n &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;
&lt;br /&gt;
&amp;lt;math&amp;gt; n + n^{2} = n(n + 1) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Описанный в данной статье алгоритм является самым быстрым алгоритмом, среди существующих: QR / Бисекция и обратная итерация / Разделяй и властвуй.&lt;br /&gt;
&lt;br /&gt;
Последовательная сложность алгоритма (не принимая во внимание дефляцию) удовлетворяет рекурсивному соотношению: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;t(n) = n^3 +2t(\frac{n}{2})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решение которого имеет вид:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt; t = c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На практике же, параллельная сложность алгоритма в силу использования дефляции, позволяющей получить выигрыш в количестве операций, который заключается в ускорении матричного умножения на последнем шаге алгоритма (см. [[#Дефляция]]), имеет следующий вид: &amp;lt;math&amp;gt; O(n^{2.3})&amp;lt;/math&amp;gt;  или в самых редких случаях &amp;lt;math&amp;gt; O(n^{2}) &amp;lt;/math&amp;gt; (см. [3] стр. 8).&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;
= Программная реализация алгоритма =&lt;br /&gt;
Вторая часть описания алгоритмов в рамках AlgoWiki рассматривает все составные части процесса их реализации. Рассматривается как последовательная реализация алгоритма, так и параллельная. Описывается взаимосвязь свойств программ, реализующих алгоритм, и особенностей архитектуры компьютера, на которой они выполняются. Исследуется работа с памятью, локальность данных и вычислений, описывается масштабируемость и эффективность параллельных программ, производительность компьютеров, достигаемая на данной программе. Обсуждаются особенности реализации для разных классов архитектур компьютеров, приводятся ссылки на реализации в существующих библиотеках.&lt;br /&gt;
&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;
*	число процессоров [1 : 8] (1,2,3,4,8);&lt;br /&gt;
*	размер матрицы [4 : 8192].&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости алгоритм был реализован на библиотеке OpenMP 1.5.5 для языка C++(компилятор g++) на cуперкомпьютере Ломоносов на узле compiler. Для данного узла максимально возможное число потоков - 8. В ходе оценки масштабируемости, программа была запущена в 1, 2, 4, 8 потока. &lt;br /&gt;
Параметры компиляции и запуска: &lt;br /&gt;
&lt;br /&gt;
 ssh compiler &lt;br /&gt;
 module add slurm&lt;br /&gt;
 module add openmpi/1.5.5-icc&lt;br /&gt;
 g++ _scratch/test.c++ -fopenmp -std=c++0x -o test &lt;br /&gt;
 sbatch -p test -n1 run ./test&lt;br /&gt;
&lt;br /&gt;
Для управления количеством потоков использовалась операция OpenMP omp_set_num_threads();&lt;br /&gt;
&lt;br /&gt;
[[File:ResultsDiagram.jpg|thumb|center|left|800px|Рис. 6. График времени работы программы в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Масштабируемость рассматриваемой реализации алгоритма &#039;&#039;&#039;&amp;quot;Разделяй и властвуй&amp;quot;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* При увеличении числа процессов общая эффективность программы увеличивается, т.к. время чтения и подготовки исходной матрицы остаётся неизменным, а время работы алгоритма уменьшается, однако рост незначительный.&lt;br /&gt;
* При увеличении размерности матрицы общая эффективность программы постепенно уменьшается, т.к. время чтения и подготовки исходных данных растёт быстрее, чем время работы исследуемого алгоритма.&lt;br /&gt;
* При одновременном увеличении как числа процессов, так и размерности матрицы общая эффективность программы уменьшается.&lt;br /&gt;
&lt;br /&gt;
Код исследуемой реализации представлен здесь [http://pastebin.com/QpfYZGkK pastebin.com]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Описываемый метод реализован в пакете LAPACK, описание которого можно найти в [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf этой статье] на страницах 7, 19 и 20, которая указана в списке литературы.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Дж. Деммель, «Вычислительная линейная алгебра» //С. 230-235&lt;br /&gt;
&lt;br /&gt;
[2] [http://www.netlib.org/utk/people/JackDongarra/PAPERS/104_1999_a-parallel-divide-and-conquer-algorithm.pdf Francoise Tisseury, Jack Dongarra, A Parallel Divide and Conquer Algorithm for the Symmetric Eigenvalue Problem on Distributed Memory Architectures]&lt;br /&gt;
&lt;br /&gt;
[3] [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf Francoise Tisseury, Jack Dongarra, Parallelizing the Divide and Conquer Algorithm for the Symmetric Tridiagonal Eigenvalue Problem on Distributed Memory Architectures]&lt;br /&gt;
&lt;br /&gt;
[4] [https://en.wikipedia.org/wiki/Divide-and-conquer_eigenvalue_algorithm Алгоритм &amp;quot;Разделяй и властвуй&amp;quot; - Wikipedia]&lt;br /&gt;
&lt;br /&gt;
[5] [http://www.cscamm.umd.edu/tadmor/pub/linear-stability/Gill_Tadmor_SISC90.pdf Doron Grill and Eitan Tadmor AN &amp;lt;math&amp;gt;O(N2)&amp;lt;/math&amp;gt; METHOD FOR COMPUTING THE EIGENSYSTEM OF &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;x&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; SYMMETRIC TRIDIAGONAL MATRICES BY THE DIVIDE AND CONQUER APPROACH]&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория:Статьи в работе]]&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22579</id>
		<title>Метод «разделяй и властвуй» вычисления собственных значений и векторов симметричной трехдиагональной матрицы</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22579"/>
		<updated>2017-04-29T20:28:01Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Макроструктура алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Роман_Землянский|Р.Землянский]] (Разделы &lt;br /&gt;
[[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]]), В.Завольсков (Разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Существующие реализации алгоритма|2.7]]), [[Участник:IgorS]] (предварительная проверка), [[Участник:Chernyavskiy|А.Ю. Чернявский]] (проверка, редактирование).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод &amp;quot;Разделяй и властвуй&amp;quot; вычисления собственных значений и векторов трёхдиагональной матрицы&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt; c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt; O(n^{2.3}) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
крайне редко: &amp;lt;math&amp;gt;  O(n^{2}) &amp;lt;/math&amp;gt; &lt;br /&gt;
| pf_width          = &lt;br /&gt;
| input_data        =  &amp;lt;math&amp;gt; 2n + 1 &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       =  &amp;lt;math&amp;gt; n(n + 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; - это наиболее быстрый из существующих методов, если нужны все собственные значения и собственные векторы трехдиагональной матрицы, начиная с порядка n, примерно равного 26. (Точное значение этого порогового порядка зависит от компьютера.) Его численно устойчивая реализация весьма не тривиальна. В самом деле, хотя впервые метод был предложен еще в 1981 г., &amp;quot;правильный&amp;quot; способ его реализации был найден лишь в 1992 г. Этот способ воплощен LAPACK-программами ssyevd (для плотных матриц) и sstevd (для трехдиагональных матриц). В них стратегия &amp;quot;разделяй-и-влавствуй&amp;quot; используется для матриц порядка, большего чем 25. Для матриц меньшего порядка (или если нужны только собственные значения) происходит автоматический переход к QR-итерации.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Пусть &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
T = \begin{bmatrix}&lt;br /&gt;
 a_{1} &amp;amp; b_{1}&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp; b_{m} &amp;amp; a_{m+1} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
= \begin{bmatrix}&lt;br /&gt;
  a_{1} &amp;amp; b_{1} &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} - b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; a_{m+1} - b_{m} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix} +&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
+ \begin{bmatrix}&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 &amp;amp;&amp;amp;b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&lt;br /&gt;
= \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m} * \begin{bmatrix} 0 \\ \vdots \\ 0 \\ 1 \\ 1 \\ 0 \\ \vdots \\ 0 \end{bmatrix} \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix} &lt;br /&gt;
&lt;br /&gt;
\equiv \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Предположим, что нам известны спектральные разложения матриц &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; T_{2} &amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; T_{i} = Q_{i} \Lambda_{i} Q_{i}^{T} &amp;lt;/math&amp;gt;. В действительности, они будут рекурсивно вычисляться тем же самым алгоритмом. Установим связь между собственными значениями матрицы Т и собственными значениями матриц&lt;br /&gt;
&amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;. Имеем:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt; &lt;br /&gt;
T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} \Lambda_{1} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2} \Lambda_{2} Q_{2}^{T}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}(\begin{bmatrix} \Lambda_{1} &amp;amp; \\  &amp;amp; \Lambda_{2}\end{bmatrix} + b_{m}uu^{T})\begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}&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;&lt;br /&gt;
u = \begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}v&lt;br /&gt;
  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
так как &amp;lt;math&amp;gt;v = \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix}^T&amp;lt;/math&amp;gt;, получим матрицу, состоящую из последнего столбца матрицы &amp;lt;math&amp;gt; Q_{1}^{T}&amp;lt;/math&amp;gt; и первого столбца матрицы &amp;lt;math&amp;gt; Q_{2}^{T}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Следовательно, &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; имеет те же собственные значения, что и подобная ей матрица &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;D = \begin{bmatrix} \Lambda_{1} &amp;amp; 0 \\ 0 &amp;amp; \Lambda_{2}\end{bmatrix}&amp;lt;/math&amp;gt; - диагональная матрица, &lt;br /&gt;
&amp;lt;math&amp;gt;\rho = b_{m}&amp;lt;/math&amp;gt; - число, а &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - вектор. &lt;br /&gt;
&lt;br /&gt;
Будем предполагать, не ограничивая общности, что диагональные элементы &amp;lt;math&amp;gt;d_{1}, \ldots, d_{n}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; упорядочены по убыванию: &amp;lt;math&amp;gt;d_{n} &amp;lt;= \ldots &amp;lt;=d_{1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Чтобы найти собственные значения матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, вычислим её характеристический многочлен, считая пока матрицу &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденной.&lt;br /&gt;
Тогда&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;det(D + \rho uu^{T} - \lambda I) = det((D - \lambda I)(I + \rho (D- \lambda I)^{-1} uu^{T}))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Поскольку &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденна, &amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 0&amp;lt;/math&amp;gt; тогда и только тогда, когда &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; - собственное значение. Заметим, что матрица &amp;lt;math&amp;gt;I + \rho (D - \lambda I)^{-1}uu^{T}&amp;lt;/math&amp;gt; получается из единичной добавлением матрицы ранга 1. Определитель такой матрицы легко вычислить.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;&#039;Лемма 1.&#039;&#039;&#039; Справедливо равенство &amp;lt;math&amp;gt;det(I + xy^{T}) = 1 + y^{T}x&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; - векторы.&lt;br /&gt;
&lt;br /&gt;
Таким образом,&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 1 + \rho u^{T}(D - \lambda I)^{-1}u&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; = 1 + \rho \sum_{i=1, n} \frac{u_{i}^{2}} {d_{i}-\lambda} \equiv f(\lambda)&amp;lt;/math&amp;gt; , &lt;br /&gt;
&lt;br /&gt;
т.е. собственные значения матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; есть корни так называемого векового уравнения &amp;lt;math&amp;gt;f(\lambda) = 0&amp;lt;/math&amp;gt;. Если все числа &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; различны и все &amp;lt;math&amp;gt;u_{i} &amp;lt;&amp;gt; 0&amp;lt;/math&amp;gt; (случай общего положения), то &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; имеет график типа показанного на рис.1(где &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\rho &amp;gt; 0&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
[[File:Graphics.PNG|thumb|center|800px|Рис. 1. График функции &amp;lt;math&amp;gt; f(\lambda) = 1 + \frac{0.5}{1 - \lambda} + \frac{0.5}{2 - \lambda} + \frac{0.5}{3 - \lambda} + \frac{0.5}{4 - \lambda}&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Можно видеть, что прямая &amp;lt;math&amp;gt;y = 1&amp;lt;/math&amp;gt; является горизонтальной асимптотой для этого графика, а прямые &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt; есть вертикальные асимптоты. Поскольку &amp;lt;math&amp;gt;f^{&#039;}(\lambda) =  \rho \sum_{i=1, n} \frac{u_{i}^{2}} {(d_{i}-\lambda)^{2}}&amp;gt; 0 &amp;lt;/math&amp;gt;, функция возрастает всюду, кроме точек &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt;. Поэтому корни функции разделяются числами &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; и ещё один корень находится справа от точки &amp;lt;math&amp;gt;d_{1}&amp;lt;/math&amp;gt; (на рис. 1 &amp;lt;math&amp;gt;d_{1} = 4&amp;lt;/math&amp;gt;). (При &amp;lt;math&amp;gt;\rho&amp;lt;0&amp;lt;/math&amp;gt; функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; всюду убывает и соответствующий корень находится слева от точки &amp;lt;math&amp;gt;d_{n}&amp;lt;/math&amp;gt;). Для функции &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt;, монотонной и гладкой на каждом из интервалов &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;, можно найти вариант метода Ньютона, который быстро и монотонно сходится к каждому из корней, если начальная точка взята в &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;. Нам достаточно знать, что на практике метод сходится к каждому собственному значению за ограниченное число шагов. Поскольку вычисление &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;f^{&#039;}(\lambda)&amp;lt;/math&amp;gt; стоит &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов, для вычисления одного собственного значения достаточно &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, а для вычисления всех &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; собственных значений матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt;O(n^{2})&amp;lt;/math&amp;gt; флопов.&lt;br /&gt;
Для собственных векторов матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; мы легко можем получить явные выражения.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;&#039;Лемма 2.&#039;&#039;&#039; Если &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - собственное значение матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, то соответствующий вектор равен &amp;lt;math&amp;gt;(D - \alpha I)^{-1}u&amp;lt;/math&amp;gt;. Поскольку матрица &amp;lt;math&amp;gt;D - \alpha I&amp;lt;/math&amp;gt; диагональная, для вычисления такого вектора достаточно &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов.&lt;br /&gt;
&lt;br /&gt;
Доказательство.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;(D + \rho uu^{T})[(D - \alpha I)^{-1}u] = (D - \alpha I + \alpha I + \rho uu^{T})(D - \alpha I)^{-1}u&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=u + \alpha (D - \alpha I)^{-1}u + u[\rho u^{T}(D - \alpha I)^{-1}u] &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=u + \alpha(D - \alpha I)^{-1}u - u&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
                                                       поскольку &amp;lt;math&amp;gt; \rho u^{T}(D - \alpha I)^{-1}u + 1 = f(\alpha) = 0 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=\alpha [(D - \alpha I)^{-1}u]&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; собственных векторов требуется &amp;lt;math&amp;gt;O(n^{2})&amp;lt;/math&amp;gt; флопов. К сожалению, формула не обеспечивает численной устойчивости, так как для двух очень близких значений &amp;lt;math&amp;gt;\alpha_{i}&amp;lt;/math&amp;gt; может давать неортогональные приближенные собственные векторы &amp;lt;math&amp;gt;u_{i}&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;d_{i}&amp;lt;/math&amp;gt; различны и все &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt; отличны от нуля. Если это не так, вековое уравнение &amp;lt;math&amp;gt;f(\lambda)=0&amp;lt;/math&amp;gt; имеет &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вертикальных асимптот, где &amp;lt;math&amp;gt;k&amp;lt;n&amp;lt;/math&amp;gt;, а потому &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; корней. Однако оказывается, что остальные &amp;lt;math&amp;gt;n - k&amp;lt;/math&amp;gt; собственных значений могут быть определены без каких-либо усилий: если &amp;lt;math&amp;gt;d_{i}=d_{i+1}&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;u_{i}=0&amp;lt;/math&amp;gt;, то легко показать, что &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; является собственным значением и для матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;. В такой ситуации мы говорим о &#039;&#039;дефляции&#039;&#039;. На практике выбирается некоторое пороговое значение и дефляция для числа &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; регистрируется, если в смысле этого порога &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; достаточно близко к &amp;lt;math&amp;gt;d_{i+1}&amp;lt;/math&amp;gt; либо &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&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;u_{i}=0&amp;lt;/math&amp;gt;, то соответствующий собственный вектор есть i-й столбец &amp;lt;math&amp;gt;e_{i}&amp;lt;/math&amp;gt; единичной матрицы. Это означает, что &amp;lt;math&amp;gt;e_{i}&amp;lt;/math&amp;gt; является i-м столбцом в матрице &amp;lt;math&amp;gt;Q_{&#039;}&amp;lt;/math&amp;gt;, поэтому при формировании матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; посредством левого умножения &amp;lt;math&amp;gt;Q_{1}&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;Q_{2}&amp;lt;/math&amp;gt; вычисление i-го столбца не требует никаких затрат. Аналогичное упрощение имеет место в случае &amp;lt;math&amp;gt;d_{i} = d_{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;
Предположим, что некоторое &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt;, хотя и мало, все же недостаточно мало для того, чтобы была зарегистрирована дефляция. В этом случае применение метода Ньютона к решению векового уравнения встречается с затруднениями. Вспомним, что пересчет приближённого решения &amp;lt;math&amp;gt;u_{j}&amp;lt;/math&amp;gt; уравнения &amp;lt;math&amp;gt;f(\lambda) = 0&amp;lt;/math&amp;gt; в методе Ньютона основан на следующих положениях:&lt;br /&gt;
&lt;br /&gt;
 1. Вблизи точки &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt; функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; аппроксимируется линейной функцией &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt;; график есть прямая линия, касающаяся графика функции &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 2. В качестве &amp;lt;math&amp;gt;\lambda_{j+1}&amp;lt;/math&amp;gt; берётся нуль этого линейного приближения, т.е. &amp;lt;math&amp;gt;l(\lambda_{j+1})=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Функция, показанная на рис.1, не доставляет видимых трудностей методу Ньютона, поскольку вблизи каждого своего нуля &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; достаточно хорошо аппроксимируется линейными функциями. Однако рассмотрим график функции на рис.2. Она получена из функции на рис. 1 заменой значения .5 для &amp;lt;math&amp;gt;u_{i}^{2}&amp;lt;/math&amp;gt; на .001. Это новое значение недостаточно мало для того, чтобы вызвать дефляцию. График функции в левой части рис.2 визуально не отличим от её вертикальных и горизонтальных асимптот, поэтому в правой части укрупненно воспроизведён фрагмент графика, прилегающий к вертикальной асимптоте &amp;lt;math&amp;gt;\lambda = 2&amp;lt;/math&amp;gt;. Видно, что график слишком быстро &amp;quot;выполняет поворот&amp;quot; и для большей части значений &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; почти горизонтален. Поэтому, применяя метод Ньютона почти к любому начальному приближению &amp;lt;math&amp;gt;\lambda_{0}&amp;lt;/math&amp;gt;, мы получаем линейное приближение &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt; с почти горизонтальным графиком и малым положительным угловым коэффициентом. В результате &amp;lt;math&amp;gt;\lambda_{1}&amp;lt;/math&amp;gt; является отрицательным числом, огромным по абсолютной величине, которое совершенно бесполезно в качестве приближения к истинному корню.&lt;br /&gt;
&lt;br /&gt;
[[File:GraphNewton.png|thumb|center|800px|Рис. 2. График функции &amp;lt;math&amp;gt; f(\lambda) = 1 + \frac{10^{-3}}{1 - \lambda} + \frac{10^{-3}}{2 - \lambda} + \frac{10^{-3}}{3 - \lambda} + \frac{10^{-3}}{4 - \lambda}&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Чтобы найти выход из этого положения, можно модифицировать метод Ньютона следующим образом: раз &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; нельзя хорошо приблизить линейной функцией &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt;, попробуем взять в качестве приближения какую-нибудь другую простую функцию &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;. Нет ничего особого именно в прямых линиях: для метода Ньютона вместо &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt; можно взять любое приближение &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;, значения и нули которого легко вычисляются. Функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; имеет полюсы в точках &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;d_{i+1}&amp;lt;/math&amp;gt;, которые определяют её поведение в соответствующих окрестностях. Поэтому при поиске корня в интервале &amp;lt;math&amp;gt;(d_{i+1}, d_{i})&amp;lt;/math&amp;gt; естественно выбрать функцию &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;, также имеющую эти полюсы, т.е. функцию вида&lt;br /&gt;
 &amp;lt;math&amp;gt;h(\lambda)= \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} + c_{3}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Константы &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; обеспечивающие, что &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt; есть приближение к &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt;, можно выбрать несколькими способами. Отметим, что если &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; уже известны, то уравнение &amp;lt;math&amp;gt;h(\lambda)=0&amp;lt;/math&amp;gt; легко решается относительно &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt;, поскольку сводится к эквивалентному квадратному уравнению&lt;br /&gt;
 &amp;lt;math&amp;gt;c_{1}(d_{i+1}-\lambda)+c_{2}(d_{i}-\lambda)+c_{3}(d_{i}-\lambda)(d_{i+1}-\lambda)=0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;\lambda_{j}&amp;lt;/math&amp;gt; - приближённое значение корня. определим &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; так, чтобы&lt;br /&gt;
 &amp;lt;math&amp;gt;\frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} + c_{3} = h(\lambda) \approx f(\lambda) = 1 + \rho \sum_{k=1, n} \frac{u_{k}^{2}} {d_{k}-\lambda} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
для &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; в окрестности &amp;lt;math&amp;gt;\lambda_{j}&amp;lt;/math&amp;gt;. Заметим, что&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;f(\lambda) = 1 + \rho \sum_{k=1, i} \frac{u_{k}^{2}} {d_{k}-\lambda} + \rho \sum_{k=i+1, n} \frac{u_{k}^{2}} {d_{k}-\lambda} \equiv 1 + \psi_{1}(\lambda) + \psi_{2}(\lambda)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\lambda \in (d_{i+1},d_{i})&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\psi_{1}(\lambda)&amp;lt;/math&amp;gt; есть сумма положительных слагаемых, а &amp;lt;math&amp;gt;\psi_{2}(\lambda)&amp;lt;/math&amp;gt; - сумма отрицательных. Поэтому и &amp;lt;math&amp;gt;\psi_{1}(\lambda)&amp;lt;/math&amp;gt;, и &amp;lt;math&amp;gt;\psi_{2}(\lambda)&amp;lt;/math&amp;gt; могут быть вычислены с высокой точностью; однако при их сложении вполне вероятно взаимное уничтожение верных разрядов и потеря относительной точности в сумме. Возьмем числа &amp;lt;math&amp;gt;c_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{1}}&amp;lt;/math&amp;gt;, такие, что функция &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h_{1}(\lambda) \equiv \hat{c_{1}} + \frac{c_{1}}{d_{i}-\lambda}&amp;lt;/math&amp;gt;   удовлетворяет условиям  &amp;lt;math&amp;gt;h_{1}(\lambda_{j}) = \psi_{1}(\lambda_{j})&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;h_{1}^{&#039;}(\lambda_{j})=\psi_{1}^{&#039;}(\lambda_{j})&amp;lt;/math&amp;gt; (1)&lt;br /&gt;
&lt;br /&gt;
Это означает, что гипербола, являющаяся графиком функции &amp;lt;math&amp;gt;h_{1}(\lambda)&amp;lt;/math&amp;gt;, касается графика функции &amp;lt;math&amp;gt;\psi_{i}(\lambda)&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt;. Два условия в (1) - это обычные условия метода Ньютона, за исключением того, что вместо прямой в качестве приближения используется гипербола. Легко проверить, что &amp;lt;math&amp;gt;c_{1}=\psi_{1}^{&#039;}(\lambda_{j})(d_{i} - \lambda_{j})^{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{1}}=\psi_{1}(\lambda_{j}) - \psi_{1}^{&#039;}(\lambda_{j})(d_{i} - \lambda_{j})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подобным же образом выбираем &amp;lt;math&amp;gt;c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{2}}&amp;lt;/math&amp;gt; так, чтобы функция &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h_{2}(\lambda) \equiv \hat{c_{2}} + \frac{c_{2}}{d_{i+1}-\lambda}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Удовлетворяла условиям&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;h_{2}(\lambda_{j}) = \psi_{2}(\lambda_{j})&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;h_{2}^{&#039;}(\lambda_{j})=\psi_{2}^{&#039;}(\lambda_{j})&amp;lt;/math&amp;gt; (2)&lt;br /&gt;
&lt;br /&gt;
Наконец, полагаем&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h(\lambda) = 1 + h_{1}(\lambda) + h_{2}(\lambda) = (1 + \hat{c_{1}} + \hat{c_{2}} + \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;\equiv c_{3} + \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром последовательной схемы решения является вычисление матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; собственных векторов путём умножения матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; Данная операция имеет сложность &amp;lt;math&amp;gt;cn^{3}&amp;lt;/math&amp;gt; о чём и говорится в разделе [[#Последовательная сложность алгоритма]] .&lt;br /&gt;
Ей предшествует вычисление собственных значений и векторов матрицы &amp;lt;math&amp;gt; D + \rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Ниже описана структура алгоритма, в которой есть блок умножения матриц для вычисления собственных векторов, являющийся вычислительным ядром алгоритма. В соответствующем разделе ([[#Вычислительное ядро алгоритма]]) мы упоминали о том, что данному блоку предшествует вычисление собственных значений, которое производится [https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%9D%D1%8C%D1%8E%D1%82%D0%BE%D0%BD%D0%B0 методом Ньютона].&lt;br /&gt;
&lt;br /&gt;
[[File:DivideAndConquerTree.png|thumb|center|left|800px|Рис. 3. Дерево алгоритма &amp;quot;Разделяй и властвуй&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
[[File:InfoGraph.jpg|thumb|center|1200px|Рис. 4. Детальное описание одного блока алгоритма]]&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&#039;&#039;Вычисление собственных значений и собственных векторов симметричной трехдиагональной матрицы посредством стратегии &amp;quot;разделяй и властвуй&amp;quot;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;proc dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T,Q,\Lambda)...&amp;lt;/math&amp;gt; по входной матрице &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются выходные матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;T = Q\Lambda Q^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Если &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - матрица размера &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; x &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  1. Присвоить выходным параметрам значения &amp;lt;math&amp;gt; Q = 1, \Lambda = T&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Иначе&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  1. Представить &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; в виде &amp;lt;math&amp;gt; T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  2. &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{1},Q_{1},\Lambda_{1})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  3. &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{2},Q_{2},\Lambda_{2})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  4. Построить &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt; по &amp;lt;math&amp;gt; \Lambda_{1},\Lambda_{2}, Q_{1}, Q_{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  5. Найти матрицу собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  6. Найти матрицу собственных векторов &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  7. Построить матрицу собственных векторов &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; : &amp;lt;math&amp;gt; Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}* Q^{&#039;} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  8. Присвоить выходным параметрам значения &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;endif&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Проанализируем сложность алгоритма. Пусть &amp;lt;math&amp;gt;t(n)&amp;lt;/math&amp;gt; - число флопов при обработке матрицы размера &amp;lt;math&amp;gt; n x n&amp;lt;/math&amp;gt; процедурой &#039;&#039;dc_eig&#039;&#039;. Тогда &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; t(n) = 2t(n/2) &amp;lt;/math&amp;gt; два рекурсивных обращения к &#039;&#039;dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{i},Q_{i},\Lambda_{i})&amp;lt;/math&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;D+\rho uu^{T}&amp;lt;/math&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;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; +c*n^{3}&amp;lt;/math&amp;gt; вычисление матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}*Q^{&#039;}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; Q_{1}, Q_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; рассматриваются как плотные матрицы и используется стандартный алгоритм матричного умножения, то константа &amp;lt;math&amp;gt; c &amp;lt;/math&amp;gt; в последней строке равна 1. Таким образом, именно это умножение составляет наиболее трудоёмкую часть алгоритма в целом. Игнорируя члены порядка &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;, получаем &amp;lt;math&amp;gt;t(n) = 2t(n/2) + cn^{3}&amp;lt;/math&amp;gt;. Решая это разностное уравнение, находим &amp;lt;math&amp;gt; t \approx c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На практике константа &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; обычно гораздо меньше 1, потому что матрица &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; весьма разрежена вследствие явления, называемого дефляцией.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
В данном разделе на рисунке 5 представлен информационный граф алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[File:InfoGraphSC.jpg|thumb|center|left|1200px|Рис. 5. Информационный граф алгоритма &amp;quot;Разделяй и властвуй&amp;quot; - шаг &amp;lt;b&amp;gt;Divide&amp;lt;/b&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Операции: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; - операция Divide разделения матрицы &amp;lt;math&amp;gt; T &amp;lt;/math&amp;gt; на матрицы &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Индексы - размерность &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{k}&amp;lt;/math&amp;gt; - операция Conquer сбора матрицы &amp;lt;math&amp;gt; D &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_{k} &amp;lt;/math&amp;gt; - операция поиска собственных значений &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; S^{&#039;} &amp;lt;/math&amp;gt; - операция поиска собственных векторов матрицы &amp;lt;math&amp;gt; Q^{&#039;} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; S &amp;lt;/math&amp;gt; - операция поиска собственных векторов матрицы &amp;lt;math&amp;gt; Q &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Рассмотрев информационный граф алгоритма, можно заметить, что в структуре имеется два параллельных блока - вызов рекурсивных функций &#039;&#039;dc_eig&#039;&#039; для вычисления собственных значений и векторов матриц &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&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;dc_eig&#039;&#039; отрабатывают последовательно - сначала со входными параметрами &amp;lt;math&amp;gt;T_{1}, Q_{1}, \Lambda_{1}&amp;lt;/math&amp;gt;, затем - &amp;lt;math&amp;gt;T_{2}, Q_{2}, \Lambda_{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, благодаря параллелизму высота алгоритма параллельного составляет &amp;lt;math&amp;gt;log_{2}(n)&amp;lt;/math&amp;gt;, когда как при последовательной реализации высота алгоритма равна сумме геометрической прогрессии &amp;lt;math&amp;gt;1+2+4+8+...+2^{n-1} = 2^{n} - 1&amp;lt;/math&amp;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;
&amp;lt;math&amp;gt;&lt;br /&gt;
L = \begin{bmatrix}&lt;br /&gt;
 a_{1} &amp;amp; b_{1}&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp; b_{m} &amp;amp; a_{m+1} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&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;2n + 1&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; n &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;
&lt;br /&gt;
&amp;lt;math&amp;gt; n + n^{2} = n(n + 1) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Описанный в данной статье алгоритм является самым быстрым алгоритмом, среди существующих: QR / Бисекция и обратная итерация / Разделяй и властвуй.&lt;br /&gt;
&lt;br /&gt;
Последовательная сложность алгоритма (не принимая во внимание дефляцию) удовлетворяет рекурсивному соотношению: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;t(n) = n^3 +2t(\frac{n}{2})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решение которого имеет вид:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt; t = c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На практике же, параллельная сложность алгоритма в силу использования дефляции, позволяющей получить выигрыш в количестве операций, который заключается в ускорении матричного умножения на последнем шаге алгоритма (см. [[#Дефляция]]), имеет следующий вид: &amp;lt;math&amp;gt; O(n^{2.3})&amp;lt;/math&amp;gt;  или в самых редких случаях &amp;lt;math&amp;gt; O(n^{2}) &amp;lt;/math&amp;gt; (см. [3] стр. 8).&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;
= Программная реализация алгоритма =&lt;br /&gt;
Вторая часть описания алгоритмов в рамках AlgoWiki рассматривает все составные части процесса их реализации. Рассматривается как последовательная реализация алгоритма, так и параллельная. Описывается взаимосвязь свойств программ, реализующих алгоритм, и особенностей архитектуры компьютера, на которой они выполняются. Исследуется работа с памятью, локальность данных и вычислений, описывается масштабируемость и эффективность параллельных программ, производительность компьютеров, достигаемая на данной программе. Обсуждаются особенности реализации для разных классов архитектур компьютеров, приводятся ссылки на реализации в существующих библиотеках.&lt;br /&gt;
&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;
*	число процессоров [1 : 8] (1,2,3,4,8);&lt;br /&gt;
*	размер матрицы [4 : 8192].&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости алгоритм был реализован на библиотеке OpenMP 1.5.5 для языка C++(компилятор g++) на cуперкомпьютере Ломоносов на узле compiler. Для данного узла максимально возможное число потоков - 8. В ходе оценки масштабируемости, программа была запущена в 1, 2, 4, 8 потока. &lt;br /&gt;
Параметры компиляции и запуска: &lt;br /&gt;
&lt;br /&gt;
 ssh compiler &lt;br /&gt;
 module add slurm&lt;br /&gt;
 module add openmpi/1.5.5-icc&lt;br /&gt;
 g++ _scratch/test.c++ -fopenmp -std=c++0x -o test &lt;br /&gt;
 sbatch -p test -n1 run ./test&lt;br /&gt;
&lt;br /&gt;
Для управления количеством потоков использовалась операция OpenMP omp_set_num_threads();&lt;br /&gt;
&lt;br /&gt;
[[File:ResultsDiagram.jpg|thumb|center|left|800px|Рис. 6. График времени работы программы в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Масштабируемость рассматриваемой реализации алгоритма &#039;&#039;&#039;&amp;quot;Разделяй и властвуй&amp;quot;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* При увеличении числа процессов общая эффективность программы увеличивается, т.к. время чтения и подготовки исходной матрицы остаётся неизменным, а время работы алгоритма уменьшается, однако рост незначительный.&lt;br /&gt;
* При увеличении размерности матрицы общая эффективность программы постепенно уменьшается, т.к. время чтения и подготовки исходных данных растёт быстрее, чем время работы исследуемого алгоритма.&lt;br /&gt;
* При одновременном увеличении как числа процессов, так и размерности матрицы общая эффективность программы уменьшается.&lt;br /&gt;
&lt;br /&gt;
Код исследуемой реализации представлен здесь [http://pastebin.com/QpfYZGkK pastebin.com]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Описываемый метод реализован в пакете LAPACK, описание которого можно найти в [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf этой статье] на страницах 7, 19 и 20, которая указана в списке литературы.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Дж. Деммель, «Вычислительная линейная алгебра» //С. 230-235&lt;br /&gt;
&lt;br /&gt;
[2] [http://www.netlib.org/utk/people/JackDongarra/PAPERS/104_1999_a-parallel-divide-and-conquer-algorithm.pdf Francoise Tisseury, Jack Dongarra, A Parallel Divide and Conquer Algorithm for the Symmetric Eigenvalue Problem on Distributed Memory Architectures]&lt;br /&gt;
&lt;br /&gt;
[3] [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf Francoise Tisseury, Jack Dongarra, Parallelizing the Divide and Conquer Algorithm for the Symmetric Tridiagonal Eigenvalue Problem on Distributed Memory Architectures]&lt;br /&gt;
&lt;br /&gt;
[4] [https://en.wikipedia.org/wiki/Divide-and-conquer_eigenvalue_algorithm Алгоритм &amp;quot;Разделяй и властвуй&amp;quot; - Wikipedia]&lt;br /&gt;
&lt;br /&gt;
[5] [http://www.cscamm.umd.edu/tadmor/pub/linear-stability/Gill_Tadmor_SISC90.pdf Doron Grill and Eitan Tadmor AN &amp;lt;math&amp;gt;O(N2)&amp;lt;/math&amp;gt; METHOD FOR COMPUTING THE EIGENSYSTEM OF &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;x&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; SYMMETRIC TRIDIAGONAL MATRICES BY THE DIVIDE AND CONQUER APPROACH]&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22578</id>
		<title>Метод «разделяй и властвуй» вычисления собственных значений и векторов симметричной трехдиагональной матрицы</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22578"/>
		<updated>2017-04-29T20:27:38Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Решение векового уравнения */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Роман_Землянский|Р.Землянский]] (Разделы &lt;br /&gt;
[[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]]), В.Завольсков (Разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Существующие реализации алгоритма|2.7]]), [[Участник:IgorS]] (предварительная проверка), [[Участник:Chernyavskiy|А.Ю. Чернявский]] (проверка, редактирование).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод &amp;quot;Разделяй и властвуй&amp;quot; вычисления собственных значений и векторов трёхдиагональной матрицы&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt; c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt; O(n^{2.3}) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
крайне редко: &amp;lt;math&amp;gt;  O(n^{2}) &amp;lt;/math&amp;gt; &lt;br /&gt;
| pf_width          = &lt;br /&gt;
| input_data        =  &amp;lt;math&amp;gt; 2n + 1 &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       =  &amp;lt;math&amp;gt; n(n + 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; - это наиболее быстрый из существующих методов, если нужны все собственные значения и собственные векторы трехдиагональной матрицы, начиная с порядка n, примерно равного 26. (Точное значение этого порогового порядка зависит от компьютера.) Его численно устойчивая реализация весьма не тривиальна. В самом деле, хотя впервые метод был предложен еще в 1981 г., &amp;quot;правильный&amp;quot; способ его реализации был найден лишь в 1992 г. Этот способ воплощен LAPACK-программами ssyevd (для плотных матриц) и sstevd (для трехдиагональных матриц). В них стратегия &amp;quot;разделяй-и-влавствуй&amp;quot; используется для матриц порядка, большего чем 25. Для матриц меньшего порядка (или если нужны только собственные значения) происходит автоматический переход к QR-итерации.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Пусть &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
T = \begin{bmatrix}&lt;br /&gt;
 a_{1} &amp;amp; b_{1}&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp; b_{m} &amp;amp; a_{m+1} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
= \begin{bmatrix}&lt;br /&gt;
  a_{1} &amp;amp; b_{1} &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} - b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; a_{m+1} - b_{m} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix} +&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
+ \begin{bmatrix}&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 &amp;amp;&amp;amp;b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&lt;br /&gt;
= \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m} * \begin{bmatrix} 0 \\ \vdots \\ 0 \\ 1 \\ 1 \\ 0 \\ \vdots \\ 0 \end{bmatrix} \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix} &lt;br /&gt;
&lt;br /&gt;
\equiv \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Предположим, что нам известны спектральные разложения матриц &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; T_{2} &amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; T_{i} = Q_{i} \Lambda_{i} Q_{i}^{T} &amp;lt;/math&amp;gt;. В действительности, они будут рекурсивно вычисляться тем же самым алгоритмом. Установим связь между собственными значениями матрицы Т и собственными значениями матриц&lt;br /&gt;
&amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;. Имеем:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt; &lt;br /&gt;
T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} \Lambda_{1} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2} \Lambda_{2} Q_{2}^{T}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}(\begin{bmatrix} \Lambda_{1} &amp;amp; \\  &amp;amp; \Lambda_{2}\end{bmatrix} + b_{m}uu^{T})\begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}&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;&lt;br /&gt;
u = \begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}v&lt;br /&gt;
  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
так как &amp;lt;math&amp;gt;v = \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix}^T&amp;lt;/math&amp;gt;, получим матрицу, состоящую из последнего столбца матрицы &amp;lt;math&amp;gt; Q_{1}^{T}&amp;lt;/math&amp;gt; и первого столбца матрицы &amp;lt;math&amp;gt; Q_{2}^{T}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Следовательно, &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; имеет те же собственные значения, что и подобная ей матрица &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;D = \begin{bmatrix} \Lambda_{1} &amp;amp; 0 \\ 0 &amp;amp; \Lambda_{2}\end{bmatrix}&amp;lt;/math&amp;gt; - диагональная матрица, &lt;br /&gt;
&amp;lt;math&amp;gt;\rho = b_{m}&amp;lt;/math&amp;gt; - число, а &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - вектор. &lt;br /&gt;
&lt;br /&gt;
Будем предполагать, не ограничивая общности, что диагональные элементы &amp;lt;math&amp;gt;d_{1}, \ldots, d_{n}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; упорядочены по убыванию: &amp;lt;math&amp;gt;d_{n} &amp;lt;= \ldots &amp;lt;=d_{1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Чтобы найти собственные значения матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, вычислим её характеристический многочлен, считая пока матрицу &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденной.&lt;br /&gt;
Тогда&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;det(D + \rho uu^{T} - \lambda I) = det((D - \lambda I)(I + \rho (D- \lambda I)^{-1} uu^{T}))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Поскольку &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденна, &amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 0&amp;lt;/math&amp;gt; тогда и только тогда, когда &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; - собственное значение. Заметим, что матрица &amp;lt;math&amp;gt;I + \rho (D - \lambda I)^{-1}uu^{T}&amp;lt;/math&amp;gt; получается из единичной добавлением матрицы ранга 1. Определитель такой матрицы легко вычислить.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;&#039;Лемма 1.&#039;&#039;&#039; Справедливо равенство &amp;lt;math&amp;gt;det(I + xy^{T}) = 1 + y^{T}x&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; - векторы.&lt;br /&gt;
&lt;br /&gt;
Таким образом,&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 1 + \rho u^{T}(D - \lambda I)^{-1}u&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; = 1 + \rho \sum_{i=1, n} \frac{u_{i}^{2}} {d_{i}-\lambda} \equiv f(\lambda)&amp;lt;/math&amp;gt; , &lt;br /&gt;
&lt;br /&gt;
т.е. собственные значения матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; есть корни так называемого векового уравнения &amp;lt;math&amp;gt;f(\lambda) = 0&amp;lt;/math&amp;gt;. Если все числа &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; различны и все &amp;lt;math&amp;gt;u_{i} &amp;lt;&amp;gt; 0&amp;lt;/math&amp;gt; (случай общего положения), то &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; имеет график типа показанного на рис.1(где &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\rho &amp;gt; 0&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
[[File:Graphics.PNG|thumb|center|800px|Рис. 1. График функции &amp;lt;math&amp;gt; f(\lambda) = 1 + \frac{0.5}{1 - \lambda} + \frac{0.5}{2 - \lambda} + \frac{0.5}{3 - \lambda} + \frac{0.5}{4 - \lambda}&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Можно видеть, что прямая &amp;lt;math&amp;gt;y = 1&amp;lt;/math&amp;gt; является горизонтальной асимптотой для этого графика, а прямые &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt; есть вертикальные асимптоты. Поскольку &amp;lt;math&amp;gt;f^{&#039;}(\lambda) =  \rho \sum_{i=1, n} \frac{u_{i}^{2}} {(d_{i}-\lambda)^{2}}&amp;gt; 0 &amp;lt;/math&amp;gt;, функция возрастает всюду, кроме точек &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt;. Поэтому корни функции разделяются числами &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; и ещё один корень находится справа от точки &amp;lt;math&amp;gt;d_{1}&amp;lt;/math&amp;gt; (на рис. 1 &amp;lt;math&amp;gt;d_{1} = 4&amp;lt;/math&amp;gt;). (При &amp;lt;math&amp;gt;\rho&amp;lt;0&amp;lt;/math&amp;gt; функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; всюду убывает и соответствующий корень находится слева от точки &amp;lt;math&amp;gt;d_{n}&amp;lt;/math&amp;gt;). Для функции &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt;, монотонной и гладкой на каждом из интервалов &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;, можно найти вариант метода Ньютона, который быстро и монотонно сходится к каждому из корней, если начальная точка взята в &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;. Нам достаточно знать, что на практике метод сходится к каждому собственному значению за ограниченное число шагов. Поскольку вычисление &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;f^{&#039;}(\lambda)&amp;lt;/math&amp;gt; стоит &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов, для вычисления одного собственного значения достаточно &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, а для вычисления всех &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; собственных значений матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt;O(n^{2})&amp;lt;/math&amp;gt; флопов.&lt;br /&gt;
Для собственных векторов матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; мы легко можем получить явные выражения.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;&#039;Лемма 2.&#039;&#039;&#039; Если &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - собственное значение матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, то соответствующий вектор равен &amp;lt;math&amp;gt;(D - \alpha I)^{-1}u&amp;lt;/math&amp;gt;. Поскольку матрица &amp;lt;math&amp;gt;D - \alpha I&amp;lt;/math&amp;gt; диагональная, для вычисления такого вектора достаточно &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов.&lt;br /&gt;
&lt;br /&gt;
Доказательство.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;(D + \rho uu^{T})[(D - \alpha I)^{-1}u] = (D - \alpha I + \alpha I + \rho uu^{T})(D - \alpha I)^{-1}u&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=u + \alpha (D - \alpha I)^{-1}u + u[\rho u^{T}(D - \alpha I)^{-1}u] &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=u + \alpha(D - \alpha I)^{-1}u - u&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
                                                       поскольку &amp;lt;math&amp;gt; \rho u^{T}(D - \alpha I)^{-1}u + 1 = f(\alpha) = 0 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=\alpha [(D - \alpha I)^{-1}u]&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; собственных векторов требуется &amp;lt;math&amp;gt;O(n^{2})&amp;lt;/math&amp;gt; флопов. К сожалению, формула не обеспечивает численной устойчивости, так как для двух очень близких значений &amp;lt;math&amp;gt;\alpha_{i}&amp;lt;/math&amp;gt; может давать неортогональные приближенные собственные векторы &amp;lt;math&amp;gt;u_{i}&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;d_{i}&amp;lt;/math&amp;gt; различны и все &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt; отличны от нуля. Если это не так, вековое уравнение &amp;lt;math&amp;gt;f(\lambda)=0&amp;lt;/math&amp;gt; имеет &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вертикальных асимптот, где &amp;lt;math&amp;gt;k&amp;lt;n&amp;lt;/math&amp;gt;, а потому &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; корней. Однако оказывается, что остальные &amp;lt;math&amp;gt;n - k&amp;lt;/math&amp;gt; собственных значений могут быть определены без каких-либо усилий: если &amp;lt;math&amp;gt;d_{i}=d_{i+1}&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;u_{i}=0&amp;lt;/math&amp;gt;, то легко показать, что &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; является собственным значением и для матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;. В такой ситуации мы говорим о &#039;&#039;дефляции&#039;&#039;. На практике выбирается некоторое пороговое значение и дефляция для числа &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; регистрируется, если в смысле этого порога &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; достаточно близко к &amp;lt;math&amp;gt;d_{i+1}&amp;lt;/math&amp;gt; либо &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&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;u_{i}=0&amp;lt;/math&amp;gt;, то соответствующий собственный вектор есть i-й столбец &amp;lt;math&amp;gt;e_{i}&amp;lt;/math&amp;gt; единичной матрицы. Это означает, что &amp;lt;math&amp;gt;e_{i}&amp;lt;/math&amp;gt; является i-м столбцом в матрице &amp;lt;math&amp;gt;Q_{&#039;}&amp;lt;/math&amp;gt;, поэтому при формировании матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; посредством левого умножения &amp;lt;math&amp;gt;Q_{1}&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;Q_{2}&amp;lt;/math&amp;gt; вычисление i-го столбца не требует никаких затрат. Аналогичное упрощение имеет место в случае &amp;lt;math&amp;gt;d_{i} = d_{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;
Предположим, что некоторое &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt;, хотя и мало, все же недостаточно мало для того, чтобы была зарегистрирована дефляция. В этом случае применение метода Ньютона к решению векового уравнения встречается с затруднениями. Вспомним, что пересчет приближённого решения &amp;lt;math&amp;gt;u_{j}&amp;lt;/math&amp;gt; уравнения &amp;lt;math&amp;gt;f(\lambda) = 0&amp;lt;/math&amp;gt; в методе Ньютона основан на следующих положениях:&lt;br /&gt;
&lt;br /&gt;
 1. Вблизи точки &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt; функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; аппроксимируется линейной функцией &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt;; график есть прямая линия, касающаяся графика функции &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 2. В качестве &amp;lt;math&amp;gt;\lambda_{j+1}&amp;lt;/math&amp;gt; берётся нуль этого линейного приближения, т.е. &amp;lt;math&amp;gt;l(\lambda_{j+1})=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Функция, показанная на рис.1, не доставляет видимых трудностей методу Ньютона, поскольку вблизи каждого своего нуля &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; достаточно хорошо аппроксимируется линейными функциями. Однако рассмотрим график функции на рис.2. Она получена из функции на рис. 1 заменой значения .5 для &amp;lt;math&amp;gt;u_{i}^{2}&amp;lt;/math&amp;gt; на .001. Это новое значение недостаточно мало для того, чтобы вызвать дефляцию. График функции в левой части рис.2 визуально не отличим от её вертикальных и горизонтальных асимптот, поэтому в правой части укрупненно воспроизведён фрагмент графика, прилегающий к вертикальной асимптоте &amp;lt;math&amp;gt;\lambda = 2&amp;lt;/math&amp;gt;. Видно, что график слишком быстро &amp;quot;выполняет поворот&amp;quot; и для большей части значений &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; почти горизонтален. Поэтому, применяя метод Ньютона почти к любому начальному приближению &amp;lt;math&amp;gt;\lambda_{0}&amp;lt;/math&amp;gt;, мы получаем линейное приближение &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt; с почти горизонтальным графиком и малым положительным угловым коэффициентом. В результате &amp;lt;math&amp;gt;\lambda_{1}&amp;lt;/math&amp;gt; является отрицательным числом, огромным по абсолютной величине, которое совершенно бесполезно в качестве приближения к истинному корню.&lt;br /&gt;
&lt;br /&gt;
[[File:GraphNewton.png|thumb|center|800px|Рис. 2. График функции &amp;lt;math&amp;gt; f(\lambda) = 1 + \frac{10^{-3}}{1 - \lambda} + \frac{10^{-3}}{2 - \lambda} + \frac{10^{-3}}{3 - \lambda} + \frac{10^{-3}}{4 - \lambda}&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Чтобы найти выход из этого положения, можно модифицировать метод Ньютона следующим образом: раз &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; нельзя хорошо приблизить линейной функцией &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt;, попробуем взять в качестве приближения какую-нибудь другую простую функцию &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;. Нет ничего особого именно в прямых линиях: для метода Ньютона вместо &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt; можно взять любое приближение &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;, значения и нули которого легко вычисляются. Функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; имеет полюсы в точках &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;d_{i+1}&amp;lt;/math&amp;gt;, которые определяют её поведение в соответствующих окрестностях. Поэтому при поиске корня в интервале &amp;lt;math&amp;gt;(d_{i+1}, d_{i})&amp;lt;/math&amp;gt; естественно выбрать функцию &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;, также имеющую эти полюсы, т.е. функцию вида&lt;br /&gt;
 &amp;lt;math&amp;gt;h(\lambda)= \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} + c_{3}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Константы &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; обеспечивающие, что &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt; есть приближение к &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt;, можно выбрать несколькими способами. Отметим, что если &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; уже известны, то уравнение &amp;lt;math&amp;gt;h(\lambda)=0&amp;lt;/math&amp;gt; легко решается относительно &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt;, поскольку сводится к эквивалентному квадратному уравнению&lt;br /&gt;
 &amp;lt;math&amp;gt;c_{1}(d_{i+1}-\lambda)+c_{2}(d_{i}-\lambda)+c_{3}(d_{i}-\lambda)(d_{i+1}-\lambda)=0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;\lambda_{j}&amp;lt;/math&amp;gt; - приближённое значение корня. определим &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; так, чтобы&lt;br /&gt;
 &amp;lt;math&amp;gt;\frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} + c_{3} = h(\lambda) \approx f(\lambda) = 1 + \rho \sum_{k=1, n} \frac{u_{k}^{2}} {d_{k}-\lambda} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
для &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; в окрестности &amp;lt;math&amp;gt;\lambda_{j}&amp;lt;/math&amp;gt;. Заметим, что&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;f(\lambda) = 1 + \rho \sum_{k=1, i} \frac{u_{k}^{2}} {d_{k}-\lambda} + \rho \sum_{k=i+1, n} \frac{u_{k}^{2}} {d_{k}-\lambda} \equiv 1 + \psi_{1}(\lambda) + \psi_{2}(\lambda)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\lambda \in (d_{i+1},d_{i})&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\psi_{1}(\lambda)&amp;lt;/math&amp;gt; есть сумма положительных слагаемых, а &amp;lt;math&amp;gt;\psi_{2}(\lambda)&amp;lt;/math&amp;gt; - сумма отрицательных. Поэтому и &amp;lt;math&amp;gt;\psi_{1}(\lambda)&amp;lt;/math&amp;gt;, и &amp;lt;math&amp;gt;\psi_{2}(\lambda)&amp;lt;/math&amp;gt; могут быть вычислены с высокой точностью; однако при их сложении вполне вероятно взаимное уничтожение верных разрядов и потеря относительной точности в сумме. Возьмем числа &amp;lt;math&amp;gt;c_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{1}}&amp;lt;/math&amp;gt;, такие, что функция &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h_{1}(\lambda) \equiv \hat{c_{1}} + \frac{c_{1}}{d_{i}-\lambda}&amp;lt;/math&amp;gt;   удовлетворяет условиям  &amp;lt;math&amp;gt;h_{1}(\lambda_{j}) = \psi_{1}(\lambda_{j})&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;h_{1}^{&#039;}(\lambda_{j})=\psi_{1}^{&#039;}(\lambda_{j})&amp;lt;/math&amp;gt; (1)&lt;br /&gt;
&lt;br /&gt;
Это означает, что гипербола, являющаяся графиком функции &amp;lt;math&amp;gt;h_{1}(\lambda)&amp;lt;/math&amp;gt;, касается графика функции &amp;lt;math&amp;gt;\psi_{i}(\lambda)&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt;. Два условия в (1) - это обычные условия метода Ньютона, за исключением того, что вместо прямой в качестве приближения используется гипербола. Легко проверить, что &amp;lt;math&amp;gt;c_{1}=\psi_{1}^{&#039;}(\lambda_{j})(d_{i} - \lambda_{j})^{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{1}}=\psi_{1}(\lambda_{j}) - \psi_{1}^{&#039;}(\lambda_{j})(d_{i} - \lambda_{j})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подобным же образом выбираем &amp;lt;math&amp;gt;c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{2}}&amp;lt;/math&amp;gt; так, чтобы функция &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h_{2}(\lambda) \equiv \hat{c_{2}} + \frac{c_{2}}{d_{i+1}-\lambda}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Удовлетворяла условиям&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;h_{2}(\lambda_{j}) = \psi_{2}(\lambda_{j})&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;h_{2}^{&#039;}(\lambda_{j})=\psi_{2}^{&#039;}(\lambda_{j})&amp;lt;/math&amp;gt; (2)&lt;br /&gt;
&lt;br /&gt;
Наконец, полагаем&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h(\lambda) = 1 + h_{1}(\lambda) + h_{2}(\lambda) = (1 + \hat{c_{1}} + \hat{c_{2}} + \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;\equiv c_{3} + \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром последовательной схемы решения является вычисление матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; собственных векторов путём умножения матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; Данная операция имеет сложность &amp;lt;math&amp;gt;cn^{3}&amp;lt;/math&amp;gt; о чём и говорится в разделе [[#Последовательная сложность алгоритма]] .&lt;br /&gt;
Ей предшествует вычисление собственных значений и векторов матрицы &amp;lt;math&amp;gt; D + \rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Ниже описана структура алгоритма, в которой есть блок умножения матриц для вычисления собственных векторов, являющийся вычислительным ядром алгоритма. В соответствующем разделе ([[#Вычислительное ядро алгоритма]]) мы упоминали о том, что данному блоку предшествует вычисление собственных значений, которое производится [https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%9D%D1%8C%D1%8E%D1%82%D0%BE%D0%BD%D0%B0 методом Ньютона].&lt;br /&gt;
&lt;br /&gt;
[[File:DivideAndConquerTree.png|thumb|center|left|800px|Рис. 2. Дерево алгоритма &amp;quot;Разделяй и властвуй&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
[[File:InfoGraph.jpg|thumb|center|1200px|Рис. 3. Детальное описание одного блока алгоритма]]&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&#039;&#039;Вычисление собственных значений и собственных векторов симметричной трехдиагональной матрицы посредством стратегии &amp;quot;разделяй и властвуй&amp;quot;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;proc dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T,Q,\Lambda)...&amp;lt;/math&amp;gt; по входной матрице &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются выходные матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;T = Q\Lambda Q^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Если &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - матрица размера &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; x &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  1. Присвоить выходным параметрам значения &amp;lt;math&amp;gt; Q = 1, \Lambda = T&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Иначе&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  1. Представить &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; в виде &amp;lt;math&amp;gt; T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  2. &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{1},Q_{1},\Lambda_{1})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  3. &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{2},Q_{2},\Lambda_{2})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  4. Построить &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt; по &amp;lt;math&amp;gt; \Lambda_{1},\Lambda_{2}, Q_{1}, Q_{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  5. Найти матрицу собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  6. Найти матрицу собственных векторов &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  7. Построить матрицу собственных векторов &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; : &amp;lt;math&amp;gt; Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}* Q^{&#039;} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  8. Присвоить выходным параметрам значения &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;endif&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Проанализируем сложность алгоритма. Пусть &amp;lt;math&amp;gt;t(n)&amp;lt;/math&amp;gt; - число флопов при обработке матрицы размера &amp;lt;math&amp;gt; n x n&amp;lt;/math&amp;gt; процедурой &#039;&#039;dc_eig&#039;&#039;. Тогда &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; t(n) = 2t(n/2) &amp;lt;/math&amp;gt; два рекурсивных обращения к &#039;&#039;dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{i},Q_{i},\Lambda_{i})&amp;lt;/math&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;D+\rho uu^{T}&amp;lt;/math&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;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; +c*n^{3}&amp;lt;/math&amp;gt; вычисление матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}*Q^{&#039;}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; Q_{1}, Q_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; рассматриваются как плотные матрицы и используется стандартный алгоритм матричного умножения, то константа &amp;lt;math&amp;gt; c &amp;lt;/math&amp;gt; в последней строке равна 1. Таким образом, именно это умножение составляет наиболее трудоёмкую часть алгоритма в целом. Игнорируя члены порядка &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;, получаем &amp;lt;math&amp;gt;t(n) = 2t(n/2) + cn^{3}&amp;lt;/math&amp;gt;. Решая это разностное уравнение, находим &amp;lt;math&amp;gt; t \approx c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На практике константа &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; обычно гораздо меньше 1, потому что матрица &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; весьма разрежена вследствие явления, называемого дефляцией.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
В данном разделе на рисунке 5 представлен информационный граф алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[File:InfoGraphSC.jpg|thumb|center|left|1200px|Рис. 5. Информационный граф алгоритма &amp;quot;Разделяй и властвуй&amp;quot; - шаг &amp;lt;b&amp;gt;Divide&amp;lt;/b&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Операции: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; - операция Divide разделения матрицы &amp;lt;math&amp;gt; T &amp;lt;/math&amp;gt; на матрицы &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Индексы - размерность &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{k}&amp;lt;/math&amp;gt; - операция Conquer сбора матрицы &amp;lt;math&amp;gt; D &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_{k} &amp;lt;/math&amp;gt; - операция поиска собственных значений &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; S^{&#039;} &amp;lt;/math&amp;gt; - операция поиска собственных векторов матрицы &amp;lt;math&amp;gt; Q^{&#039;} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; S &amp;lt;/math&amp;gt; - операция поиска собственных векторов матрицы &amp;lt;math&amp;gt; Q &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Рассмотрев информационный граф алгоритма, можно заметить, что в структуре имеется два параллельных блока - вызов рекурсивных функций &#039;&#039;dc_eig&#039;&#039; для вычисления собственных значений и векторов матриц &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&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;dc_eig&#039;&#039; отрабатывают последовательно - сначала со входными параметрами &amp;lt;math&amp;gt;T_{1}, Q_{1}, \Lambda_{1}&amp;lt;/math&amp;gt;, затем - &amp;lt;math&amp;gt;T_{2}, Q_{2}, \Lambda_{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, благодаря параллелизму высота алгоритма параллельного составляет &amp;lt;math&amp;gt;log_{2}(n)&amp;lt;/math&amp;gt;, когда как при последовательной реализации высота алгоритма равна сумме геометрической прогрессии &amp;lt;math&amp;gt;1+2+4+8+...+2^{n-1} = 2^{n} - 1&amp;lt;/math&amp;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;
&amp;lt;math&amp;gt;&lt;br /&gt;
L = \begin{bmatrix}&lt;br /&gt;
 a_{1} &amp;amp; b_{1}&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp; b_{m} &amp;amp; a_{m+1} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&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;2n + 1&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; n &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;
&lt;br /&gt;
&amp;lt;math&amp;gt; n + n^{2} = n(n + 1) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Описанный в данной статье алгоритм является самым быстрым алгоритмом, среди существующих: QR / Бисекция и обратная итерация / Разделяй и властвуй.&lt;br /&gt;
&lt;br /&gt;
Последовательная сложность алгоритма (не принимая во внимание дефляцию) удовлетворяет рекурсивному соотношению: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;t(n) = n^3 +2t(\frac{n}{2})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решение которого имеет вид:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt; t = c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На практике же, параллельная сложность алгоритма в силу использования дефляции, позволяющей получить выигрыш в количестве операций, который заключается в ускорении матричного умножения на последнем шаге алгоритма (см. [[#Дефляция]]), имеет следующий вид: &amp;lt;math&amp;gt; O(n^{2.3})&amp;lt;/math&amp;gt;  или в самых редких случаях &amp;lt;math&amp;gt; O(n^{2}) &amp;lt;/math&amp;gt; (см. [3] стр. 8).&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;
= Программная реализация алгоритма =&lt;br /&gt;
Вторая часть описания алгоритмов в рамках AlgoWiki рассматривает все составные части процесса их реализации. Рассматривается как последовательная реализация алгоритма, так и параллельная. Описывается взаимосвязь свойств программ, реализующих алгоритм, и особенностей архитектуры компьютера, на которой они выполняются. Исследуется работа с памятью, локальность данных и вычислений, описывается масштабируемость и эффективность параллельных программ, производительность компьютеров, достигаемая на данной программе. Обсуждаются особенности реализации для разных классов архитектур компьютеров, приводятся ссылки на реализации в существующих библиотеках.&lt;br /&gt;
&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;
*	число процессоров [1 : 8] (1,2,3,4,8);&lt;br /&gt;
*	размер матрицы [4 : 8192].&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости алгоритм был реализован на библиотеке OpenMP 1.5.5 для языка C++(компилятор g++) на cуперкомпьютере Ломоносов на узле compiler. Для данного узла максимально возможное число потоков - 8. В ходе оценки масштабируемости, программа была запущена в 1, 2, 4, 8 потока. &lt;br /&gt;
Параметры компиляции и запуска: &lt;br /&gt;
&lt;br /&gt;
 ssh compiler &lt;br /&gt;
 module add slurm&lt;br /&gt;
 module add openmpi/1.5.5-icc&lt;br /&gt;
 g++ _scratch/test.c++ -fopenmp -std=c++0x -o test &lt;br /&gt;
 sbatch -p test -n1 run ./test&lt;br /&gt;
&lt;br /&gt;
Для управления количеством потоков использовалась операция OpenMP omp_set_num_threads();&lt;br /&gt;
&lt;br /&gt;
[[File:ResultsDiagram.jpg|thumb|center|left|800px|Рис. 6. График времени работы программы в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Масштабируемость рассматриваемой реализации алгоритма &#039;&#039;&#039;&amp;quot;Разделяй и властвуй&amp;quot;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* При увеличении числа процессов общая эффективность программы увеличивается, т.к. время чтения и подготовки исходной матрицы остаётся неизменным, а время работы алгоритма уменьшается, однако рост незначительный.&lt;br /&gt;
* При увеличении размерности матрицы общая эффективность программы постепенно уменьшается, т.к. время чтения и подготовки исходных данных растёт быстрее, чем время работы исследуемого алгоритма.&lt;br /&gt;
* При одновременном увеличении как числа процессов, так и размерности матрицы общая эффективность программы уменьшается.&lt;br /&gt;
&lt;br /&gt;
Код исследуемой реализации представлен здесь [http://pastebin.com/QpfYZGkK pastebin.com]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Описываемый метод реализован в пакете LAPACK, описание которого можно найти в [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf этой статье] на страницах 7, 19 и 20, которая указана в списке литературы.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Дж. Деммель, «Вычислительная линейная алгебра» //С. 230-235&lt;br /&gt;
&lt;br /&gt;
[2] [http://www.netlib.org/utk/people/JackDongarra/PAPERS/104_1999_a-parallel-divide-and-conquer-algorithm.pdf Francoise Tisseury, Jack Dongarra, A Parallel Divide and Conquer Algorithm for the Symmetric Eigenvalue Problem on Distributed Memory Architectures]&lt;br /&gt;
&lt;br /&gt;
[3] [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf Francoise Tisseury, Jack Dongarra, Parallelizing the Divide and Conquer Algorithm for the Symmetric Tridiagonal Eigenvalue Problem on Distributed Memory Architectures]&lt;br /&gt;
&lt;br /&gt;
[4] [https://en.wikipedia.org/wiki/Divide-and-conquer_eigenvalue_algorithm Алгоритм &amp;quot;Разделяй и властвуй&amp;quot; - Wikipedia]&lt;br /&gt;
&lt;br /&gt;
[5] [http://www.cscamm.umd.edu/tadmor/pub/linear-stability/Gill_Tadmor_SISC90.pdf Doron Grill and Eitan Tadmor AN &amp;lt;math&amp;gt;O(N2)&amp;lt;/math&amp;gt; METHOD FOR COMPUTING THE EIGENSYSTEM OF &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;x&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; SYMMETRIC TRIDIAGONAL MATRICES BY THE DIVIDE AND CONQUER APPROACH]&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22577</id>
		<title>Метод «разделяй и властвуй» вычисления собственных значений и векторов симметричной трехдиагональной матрицы</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22577"/>
		<updated>2017-04-29T20:26:54Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* ЧАСТЬ. Программная реализация алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Роман_Землянский|Р.Землянский]] (Разделы &lt;br /&gt;
[[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]]), В.Завольсков (Разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Существующие реализации алгоритма|2.7]]), [[Участник:IgorS]] (предварительная проверка), [[Участник:Chernyavskiy|А.Ю. Чернявский]] (проверка, редактирование).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод &amp;quot;Разделяй и властвуй&amp;quot; вычисления собственных значений и векторов трёхдиагональной матрицы&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt; c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt; O(n^{2.3}) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
крайне редко: &amp;lt;math&amp;gt;  O(n^{2}) &amp;lt;/math&amp;gt; &lt;br /&gt;
| pf_width          = &lt;br /&gt;
| input_data        =  &amp;lt;math&amp;gt; 2n + 1 &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       =  &amp;lt;math&amp;gt; n(n + 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; - это наиболее быстрый из существующих методов, если нужны все собственные значения и собственные векторы трехдиагональной матрицы, начиная с порядка n, примерно равного 26. (Точное значение этого порогового порядка зависит от компьютера.) Его численно устойчивая реализация весьма не тривиальна. В самом деле, хотя впервые метод был предложен еще в 1981 г., &amp;quot;правильный&amp;quot; способ его реализации был найден лишь в 1992 г. Этот способ воплощен LAPACK-программами ssyevd (для плотных матриц) и sstevd (для трехдиагональных матриц). В них стратегия &amp;quot;разделяй-и-влавствуй&amp;quot; используется для матриц порядка, большего чем 25. Для матриц меньшего порядка (или если нужны только собственные значения) происходит автоматический переход к QR-итерации.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Пусть &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
T = \begin{bmatrix}&lt;br /&gt;
 a_{1} &amp;amp; b_{1}&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp; b_{m} &amp;amp; a_{m+1} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
= \begin{bmatrix}&lt;br /&gt;
  a_{1} &amp;amp; b_{1} &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} - b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; a_{m+1} - b_{m} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix} +&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
+ \begin{bmatrix}&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 &amp;amp;&amp;amp;b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&lt;br /&gt;
= \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m} * \begin{bmatrix} 0 \\ \vdots \\ 0 \\ 1 \\ 1 \\ 0 \\ \vdots \\ 0 \end{bmatrix} \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix} &lt;br /&gt;
&lt;br /&gt;
\equiv \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Предположим, что нам известны спектральные разложения матриц &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; T_{2} &amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; T_{i} = Q_{i} \Lambda_{i} Q_{i}^{T} &amp;lt;/math&amp;gt;. В действительности, они будут рекурсивно вычисляться тем же самым алгоритмом. Установим связь между собственными значениями матрицы Т и собственными значениями матриц&lt;br /&gt;
&amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;. Имеем:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt; &lt;br /&gt;
T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} \Lambda_{1} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2} \Lambda_{2} Q_{2}^{T}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}(\begin{bmatrix} \Lambda_{1} &amp;amp; \\  &amp;amp; \Lambda_{2}\end{bmatrix} + b_{m}uu^{T})\begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}&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;&lt;br /&gt;
u = \begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}v&lt;br /&gt;
  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
так как &amp;lt;math&amp;gt;v = \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix}^T&amp;lt;/math&amp;gt;, получим матрицу, состоящую из последнего столбца матрицы &amp;lt;math&amp;gt; Q_{1}^{T}&amp;lt;/math&amp;gt; и первого столбца матрицы &amp;lt;math&amp;gt; Q_{2}^{T}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Следовательно, &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; имеет те же собственные значения, что и подобная ей матрица &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;D = \begin{bmatrix} \Lambda_{1} &amp;amp; 0 \\ 0 &amp;amp; \Lambda_{2}\end{bmatrix}&amp;lt;/math&amp;gt; - диагональная матрица, &lt;br /&gt;
&amp;lt;math&amp;gt;\rho = b_{m}&amp;lt;/math&amp;gt; - число, а &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - вектор. &lt;br /&gt;
&lt;br /&gt;
Будем предполагать, не ограничивая общности, что диагональные элементы &amp;lt;math&amp;gt;d_{1}, \ldots, d_{n}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; упорядочены по убыванию: &amp;lt;math&amp;gt;d_{n} &amp;lt;= \ldots &amp;lt;=d_{1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Чтобы найти собственные значения матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, вычислим её характеристический многочлен, считая пока матрицу &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденной.&lt;br /&gt;
Тогда&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;det(D + \rho uu^{T} - \lambda I) = det((D - \lambda I)(I + \rho (D- \lambda I)^{-1} uu^{T}))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Поскольку &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденна, &amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 0&amp;lt;/math&amp;gt; тогда и только тогда, когда &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; - собственное значение. Заметим, что матрица &amp;lt;math&amp;gt;I + \rho (D - \lambda I)^{-1}uu^{T}&amp;lt;/math&amp;gt; получается из единичной добавлением матрицы ранга 1. Определитель такой матрицы легко вычислить.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;&#039;Лемма 1.&#039;&#039;&#039; Справедливо равенство &amp;lt;math&amp;gt;det(I + xy^{T}) = 1 + y^{T}x&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; - векторы.&lt;br /&gt;
&lt;br /&gt;
Таким образом,&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 1 + \rho u^{T}(D - \lambda I)^{-1}u&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; = 1 + \rho \sum_{i=1, n} \frac{u_{i}^{2}} {d_{i}-\lambda} \equiv f(\lambda)&amp;lt;/math&amp;gt; , &lt;br /&gt;
&lt;br /&gt;
т.е. собственные значения матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; есть корни так называемого векового уравнения &amp;lt;math&amp;gt;f(\lambda) = 0&amp;lt;/math&amp;gt;. Если все числа &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; различны и все &amp;lt;math&amp;gt;u_{i} &amp;lt;&amp;gt; 0&amp;lt;/math&amp;gt; (случай общего положения), то &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; имеет график типа показанного на рис.1(где &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\rho &amp;gt; 0&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
[[File:Graphics.PNG|thumb|center|800px|Рис. 1. График функции &amp;lt;math&amp;gt; f(\lambda) = 1 + \frac{0.5}{1 - \lambda} + \frac{0.5}{2 - \lambda} + \frac{0.5}{3 - \lambda} + \frac{0.5}{4 - \lambda}&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Можно видеть, что прямая &amp;lt;math&amp;gt;y = 1&amp;lt;/math&amp;gt; является горизонтальной асимптотой для этого графика, а прямые &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt; есть вертикальные асимптоты. Поскольку &amp;lt;math&amp;gt;f^{&#039;}(\lambda) =  \rho \sum_{i=1, n} \frac{u_{i}^{2}} {(d_{i}-\lambda)^{2}}&amp;gt; 0 &amp;lt;/math&amp;gt;, функция возрастает всюду, кроме точек &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt;. Поэтому корни функции разделяются числами &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; и ещё один корень находится справа от точки &amp;lt;math&amp;gt;d_{1}&amp;lt;/math&amp;gt; (на рис. 1 &amp;lt;math&amp;gt;d_{1} = 4&amp;lt;/math&amp;gt;). (При &amp;lt;math&amp;gt;\rho&amp;lt;0&amp;lt;/math&amp;gt; функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; всюду убывает и соответствующий корень находится слева от точки &amp;lt;math&amp;gt;d_{n}&amp;lt;/math&amp;gt;). Для функции &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt;, монотонной и гладкой на каждом из интервалов &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;, можно найти вариант метода Ньютона, который быстро и монотонно сходится к каждому из корней, если начальная точка взята в &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;. Нам достаточно знать, что на практике метод сходится к каждому собственному значению за ограниченное число шагов. Поскольку вычисление &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;f^{&#039;}(\lambda)&amp;lt;/math&amp;gt; стоит &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов, для вычисления одного собственного значения достаточно &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, а для вычисления всех &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; собственных значений матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt;O(n^{2})&amp;lt;/math&amp;gt; флопов.&lt;br /&gt;
Для собственных векторов матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; мы легко можем получить явные выражения.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;&#039;Лемма 2.&#039;&#039;&#039; Если &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - собственное значение матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, то соответствующий вектор равен &amp;lt;math&amp;gt;(D - \alpha I)^{-1}u&amp;lt;/math&amp;gt;. Поскольку матрица &amp;lt;math&amp;gt;D - \alpha I&amp;lt;/math&amp;gt; диагональная, для вычисления такого вектора достаточно &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов.&lt;br /&gt;
&lt;br /&gt;
Доказательство.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;(D + \rho uu^{T})[(D - \alpha I)^{-1}u] = (D - \alpha I + \alpha I + \rho uu^{T})(D - \alpha I)^{-1}u&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=u + \alpha (D - \alpha I)^{-1}u + u[\rho u^{T}(D - \alpha I)^{-1}u] &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=u + \alpha(D - \alpha I)^{-1}u - u&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
                                                       поскольку &amp;lt;math&amp;gt; \rho u^{T}(D - \alpha I)^{-1}u + 1 = f(\alpha) = 0 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=\alpha [(D - \alpha I)^{-1}u]&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; собственных векторов требуется &amp;lt;math&amp;gt;O(n^{2})&amp;lt;/math&amp;gt; флопов. К сожалению, формула не обеспечивает численной устойчивости, так как для двух очень близких значений &amp;lt;math&amp;gt;\alpha_{i}&amp;lt;/math&amp;gt; может давать неортогональные приближенные собственные векторы &amp;lt;math&amp;gt;u_{i}&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;d_{i}&amp;lt;/math&amp;gt; различны и все &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt; отличны от нуля. Если это не так, вековое уравнение &amp;lt;math&amp;gt;f(\lambda)=0&amp;lt;/math&amp;gt; имеет &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вертикальных асимптот, где &amp;lt;math&amp;gt;k&amp;lt;n&amp;lt;/math&amp;gt;, а потому &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; корней. Однако оказывается, что остальные &amp;lt;math&amp;gt;n - k&amp;lt;/math&amp;gt; собственных значений могут быть определены без каких-либо усилий: если &amp;lt;math&amp;gt;d_{i}=d_{i+1}&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;u_{i}=0&amp;lt;/math&amp;gt;, то легко показать, что &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; является собственным значением и для матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;. В такой ситуации мы говорим о &#039;&#039;дефляции&#039;&#039;. На практике выбирается некоторое пороговое значение и дефляция для числа &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; регистрируется, если в смысле этого порога &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; достаточно близко к &amp;lt;math&amp;gt;d_{i+1}&amp;lt;/math&amp;gt; либо &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&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;u_{i}=0&amp;lt;/math&amp;gt;, то соответствующий собственный вектор есть i-й столбец &amp;lt;math&amp;gt;e_{i}&amp;lt;/math&amp;gt; единичной матрицы. Это означает, что &amp;lt;math&amp;gt;e_{i}&amp;lt;/math&amp;gt; является i-м столбцом в матрице &amp;lt;math&amp;gt;Q_{&#039;}&amp;lt;/math&amp;gt;, поэтому при формировании матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; посредством левого умножения &amp;lt;math&amp;gt;Q_{1}&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;Q_{2}&amp;lt;/math&amp;gt; вычисление i-го столбца не требует никаких затрат. Аналогичное упрощение имеет место в случае &amp;lt;math&amp;gt;d_{i} = d_{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;
Предположим, что некоторое &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt;, хотя и мало, все же недостаточно мало для того, чтобы была зарегистрирована дефляция. В этом случае применение метода Ньютона к решению векового уравнения встречается с затруднениями. Вспомним, что пересчет приближённого решения &amp;lt;math&amp;gt;u_{j}&amp;lt;/math&amp;gt; уравнения &amp;lt;math&amp;gt;f(\lambda) = 0&amp;lt;/math&amp;gt; в методе Ньютона основан на следующих положениях:&lt;br /&gt;
&lt;br /&gt;
 1. Вблизи точки &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt; функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; аппроксимируется линейной функцией &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt;; график есть прямая линия, касающаяся графика функции &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 2. В качестве &amp;lt;math&amp;gt;\lambda_{j+1}&amp;lt;/math&amp;gt; берётся нуль этого линейного приближения, т.е. &amp;lt;math&amp;gt;l(\lambda_{j+1})=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Функция, показанная на рис.1, не доставляет видимых трудностей методу Ньютона, поскольку вблизи каждого своего нуля &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; достаточно хорошо аппроксимируется линейными функциями. Однако рассмотрим график функции на рис. 4. Она получена из функции на рис. 1 заменой значения .5 для &amp;lt;math&amp;gt;u_{i}^{2}&amp;lt;/math&amp;gt; на .001. Это новое значение недостаточно мало для того, чтобы вызвать дефляцию. График функции в левой части рис.4 визуально не отличим от её вертикальных и горизонтальных асимптот, поэтому в правой части укрупненно воспроизведён фрагмент графика, прилегающий к вертикальной асимптоте &amp;lt;math&amp;gt;\lambda = 2&amp;lt;/math&amp;gt;. Видно, что график слишком быстро &amp;quot;выполняет поворот&amp;quot; и для большей части значений &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; почти горизонтален. Поэтому, применяя метод Ньютона почти к любому начальному приближению &amp;lt;math&amp;gt;\lambda_{0}&amp;lt;/math&amp;gt;, мы получаем линейное приближение &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt; с почти горизонтальным графиком и малым положительным угловым коэффициентом. В результате &amp;lt;math&amp;gt;\lambda_{1}&amp;lt;/math&amp;gt; является отрицательным числом, огромным по абсолютной величине, которое совершенно бесполезно в качестве приближения к истинному корню.&lt;br /&gt;
&lt;br /&gt;
[[File:GraphNewton.png|thumb|center|800px|Рис. 4. График функции &amp;lt;math&amp;gt; f(\lambda) = 1 + \frac{10^{-3}}{1 - \lambda} + \frac{10^{-3}}{2 - \lambda} + \frac{10^{-3}}{3 - \lambda} + \frac{10^{-3}}{4 - \lambda}&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Чтобы найти выход из этого положения, можно модифицировать метод Ньютона следующим образом: раз &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; нельзя хорошо приблизить линейной функцией &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt;, попробуем взять в качестве приближения какую-нибудь другую простую функцию &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;. Нет ничего особого именно в прямых линиях: для метода Ньютона вместо &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt; можно взять любое приближение &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;, значения и нули которого легко вычисляются. Функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; имеет полюсы в точках &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;d_{i+1}&amp;lt;/math&amp;gt;, которые определяют её поведение в соответствующих окрестностях. Поэтому при поиске корня в интервале &amp;lt;math&amp;gt;(d_{i+1}, d_{i})&amp;lt;/math&amp;gt; естественно выбрать функцию &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;, также имеющую эти полюсы, т.е. функцию вида&lt;br /&gt;
 &amp;lt;math&amp;gt;h(\lambda)= \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} + c_{3}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Константы &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; обеспечивающие, что &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt; есть приближение к &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt;, можно выбрать несколькими способами. Отметим, что если &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; уже известны, то уравнение &amp;lt;math&amp;gt;h(\lambda)=0&amp;lt;/math&amp;gt; легко решается относительно &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt;, поскольку сводится к эквивалентному квадратному уравнению&lt;br /&gt;
 &amp;lt;math&amp;gt;c_{1}(d_{i+1}-\lambda)+c_{2}(d_{i}-\lambda)+c_{3}(d_{i}-\lambda)(d_{i+1}-\lambda)=0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;\lambda_{j}&amp;lt;/math&amp;gt; - приближённое значение корня. определим &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; так, чтобы&lt;br /&gt;
 &amp;lt;math&amp;gt;\frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} + c_{3} = h(\lambda) \approx f(\lambda) = 1 + \rho \sum_{k=1, n} \frac{u_{k}^{2}} {d_{k}-\lambda} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
для &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; в окрестности &amp;lt;math&amp;gt;\lambda_{j}&amp;lt;/math&amp;gt;. Заметим, что&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;f(\lambda) = 1 + \rho \sum_{k=1, i} \frac{u_{k}^{2}} {d_{k}-\lambda} + \rho \sum_{k=i+1, n} \frac{u_{k}^{2}} {d_{k}-\lambda} \equiv 1 + \psi_{1}(\lambda) + \psi_{2}(\lambda)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\lambda \in (d_{i+1},d_{i})&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\psi_{1}(\lambda)&amp;lt;/math&amp;gt; есть сумма положительных слагаемых, а &amp;lt;math&amp;gt;\psi_{2}(\lambda)&amp;lt;/math&amp;gt; - сумма отрицательных. Поэтому и &amp;lt;math&amp;gt;\psi_{1}(\lambda)&amp;lt;/math&amp;gt;, и &amp;lt;math&amp;gt;\psi_{2}(\lambda)&amp;lt;/math&amp;gt; могут быть вычислены с высокой точностью; однако при их сложении вполне вероятно взаимное уничтожение верных разрядов и потеря относительной точности в сумме. Возьмем числа &amp;lt;math&amp;gt;c_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{1}}&amp;lt;/math&amp;gt;, такие, что функция &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h_{1}(\lambda) \equiv \hat{c_{1}} + \frac{c_{1}}{d_{i}-\lambda}&amp;lt;/math&amp;gt;   удовлетворяет условиям  &amp;lt;math&amp;gt;h_{1}(\lambda_{j}) = \psi_{1}(\lambda_{j})&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;h_{1}^{&#039;}(\lambda_{j})=\psi_{1}^{&#039;}(\lambda_{j})&amp;lt;/math&amp;gt; (1)&lt;br /&gt;
&lt;br /&gt;
Это означает, что гипербола, являющаяся графиком функции &amp;lt;math&amp;gt;h_{1}(\lambda)&amp;lt;/math&amp;gt;, касается графика функции &amp;lt;math&amp;gt;\psi_{i}(\lambda)&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt;. Два условия в (1) - это обычные условия метода Ньютона, за исключением того, что вместо прямой в качестве приближения используется гипербола. Легко проверить, что &amp;lt;math&amp;gt;c_{1}=\psi_{1}^{&#039;}(\lambda_{j})(d_{i} - \lambda_{j})^{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{1}}=\psi_{1}(\lambda_{j}) - \psi_{1}^{&#039;}(\lambda_{j})(d_{i} - \lambda_{j})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подобным же образом выбираем &amp;lt;math&amp;gt;c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{2}}&amp;lt;/math&amp;gt; так, чтобы функция &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h_{2}(\lambda) \equiv \hat{c_{2}} + \frac{c_{2}}{d_{i+1}-\lambda}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Удовлетворяла условиям&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;h_{2}(\lambda_{j}) = \psi_{2}(\lambda_{j})&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;h_{2}^{&#039;}(\lambda_{j})=\psi_{2}^{&#039;}(\lambda_{j})&amp;lt;/math&amp;gt; (2)&lt;br /&gt;
&lt;br /&gt;
Наконец, полагаем&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h(\lambda) = 1 + h_{1}(\lambda) + h_{2}(\lambda) = (1 + \hat{c_{1}} + \hat{c_{2}} + \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;\equiv c_{3} + \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром последовательной схемы решения является вычисление матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; собственных векторов путём умножения матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; Данная операция имеет сложность &amp;lt;math&amp;gt;cn^{3}&amp;lt;/math&amp;gt; о чём и говорится в разделе [[#Последовательная сложность алгоритма]] .&lt;br /&gt;
Ей предшествует вычисление собственных значений и векторов матрицы &amp;lt;math&amp;gt; D + \rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Ниже описана структура алгоритма, в которой есть блок умножения матриц для вычисления собственных векторов, являющийся вычислительным ядром алгоритма. В соответствующем разделе ([[#Вычислительное ядро алгоритма]]) мы упоминали о том, что данному блоку предшествует вычисление собственных значений, которое производится [https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%9D%D1%8C%D1%8E%D1%82%D0%BE%D0%BD%D0%B0 методом Ньютона].&lt;br /&gt;
&lt;br /&gt;
[[File:DivideAndConquerTree.png|thumb|center|left|800px|Рис. 2. Дерево алгоритма &amp;quot;Разделяй и властвуй&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
[[File:InfoGraph.jpg|thumb|center|1200px|Рис. 3. Детальное описание одного блока алгоритма]]&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&#039;&#039;Вычисление собственных значений и собственных векторов симметричной трехдиагональной матрицы посредством стратегии &amp;quot;разделяй и властвуй&amp;quot;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;proc dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T,Q,\Lambda)...&amp;lt;/math&amp;gt; по входной матрице &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются выходные матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;T = Q\Lambda Q^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Если &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - матрица размера &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; x &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  1. Присвоить выходным параметрам значения &amp;lt;math&amp;gt; Q = 1, \Lambda = T&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Иначе&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  1. Представить &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; в виде &amp;lt;math&amp;gt; T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  2. &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{1},Q_{1},\Lambda_{1})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  3. &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{2},Q_{2},\Lambda_{2})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  4. Построить &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt; по &amp;lt;math&amp;gt; \Lambda_{1},\Lambda_{2}, Q_{1}, Q_{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  5. Найти матрицу собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  6. Найти матрицу собственных векторов &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  7. Построить матрицу собственных векторов &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; : &amp;lt;math&amp;gt; Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}* Q^{&#039;} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  8. Присвоить выходным параметрам значения &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;endif&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Проанализируем сложность алгоритма. Пусть &amp;lt;math&amp;gt;t(n)&amp;lt;/math&amp;gt; - число флопов при обработке матрицы размера &amp;lt;math&amp;gt; n x n&amp;lt;/math&amp;gt; процедурой &#039;&#039;dc_eig&#039;&#039;. Тогда &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; t(n) = 2t(n/2) &amp;lt;/math&amp;gt; два рекурсивных обращения к &#039;&#039;dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{i},Q_{i},\Lambda_{i})&amp;lt;/math&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;D+\rho uu^{T}&amp;lt;/math&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;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; +c*n^{3}&amp;lt;/math&amp;gt; вычисление матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}*Q^{&#039;}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; Q_{1}, Q_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; рассматриваются как плотные матрицы и используется стандартный алгоритм матричного умножения, то константа &amp;lt;math&amp;gt; c &amp;lt;/math&amp;gt; в последней строке равна 1. Таким образом, именно это умножение составляет наиболее трудоёмкую часть алгоритма в целом. Игнорируя члены порядка &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;, получаем &amp;lt;math&amp;gt;t(n) = 2t(n/2) + cn^{3}&amp;lt;/math&amp;gt;. Решая это разностное уравнение, находим &amp;lt;math&amp;gt; t \approx c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На практике константа &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; обычно гораздо меньше 1, потому что матрица &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; весьма разрежена вследствие явления, называемого дефляцией.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
В данном разделе на рисунке 5 представлен информационный граф алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[File:InfoGraphSC.jpg|thumb|center|left|1200px|Рис. 5. Информационный граф алгоритма &amp;quot;Разделяй и властвуй&amp;quot; - шаг &amp;lt;b&amp;gt;Divide&amp;lt;/b&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Операции: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; - операция Divide разделения матрицы &amp;lt;math&amp;gt; T &amp;lt;/math&amp;gt; на матрицы &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Индексы - размерность &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{k}&amp;lt;/math&amp;gt; - операция Conquer сбора матрицы &amp;lt;math&amp;gt; D &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_{k} &amp;lt;/math&amp;gt; - операция поиска собственных значений &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; S^{&#039;} &amp;lt;/math&amp;gt; - операция поиска собственных векторов матрицы &amp;lt;math&amp;gt; Q^{&#039;} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; S &amp;lt;/math&amp;gt; - операция поиска собственных векторов матрицы &amp;lt;math&amp;gt; Q &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Рассмотрев информационный граф алгоритма, можно заметить, что в структуре имеется два параллельных блока - вызов рекурсивных функций &#039;&#039;dc_eig&#039;&#039; для вычисления собственных значений и векторов матриц &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&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;dc_eig&#039;&#039; отрабатывают последовательно - сначала со входными параметрами &amp;lt;math&amp;gt;T_{1}, Q_{1}, \Lambda_{1}&amp;lt;/math&amp;gt;, затем - &amp;lt;math&amp;gt;T_{2}, Q_{2}, \Lambda_{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, благодаря параллелизму высота алгоритма параллельного составляет &amp;lt;math&amp;gt;log_{2}(n)&amp;lt;/math&amp;gt;, когда как при последовательной реализации высота алгоритма равна сумме геометрической прогрессии &amp;lt;math&amp;gt;1+2+4+8+...+2^{n-1} = 2^{n} - 1&amp;lt;/math&amp;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;
&amp;lt;math&amp;gt;&lt;br /&gt;
L = \begin{bmatrix}&lt;br /&gt;
 a_{1} &amp;amp; b_{1}&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp; b_{m} &amp;amp; a_{m+1} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&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;2n + 1&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; n &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;
&lt;br /&gt;
&amp;lt;math&amp;gt; n + n^{2} = n(n + 1) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Описанный в данной статье алгоритм является самым быстрым алгоритмом, среди существующих: QR / Бисекция и обратная итерация / Разделяй и властвуй.&lt;br /&gt;
&lt;br /&gt;
Последовательная сложность алгоритма (не принимая во внимание дефляцию) удовлетворяет рекурсивному соотношению: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;t(n) = n^3 +2t(\frac{n}{2})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решение которого имеет вид:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt; t = c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На практике же, параллельная сложность алгоритма в силу использования дефляции, позволяющей получить выигрыш в количестве операций, который заключается в ускорении матричного умножения на последнем шаге алгоритма (см. [[#Дефляция]]), имеет следующий вид: &amp;lt;math&amp;gt; O(n^{2.3})&amp;lt;/math&amp;gt;  или в самых редких случаях &amp;lt;math&amp;gt; O(n^{2}) &amp;lt;/math&amp;gt; (см. [3] стр. 8).&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;
= Программная реализация алгоритма =&lt;br /&gt;
Вторая часть описания алгоритмов в рамках AlgoWiki рассматривает все составные части процесса их реализации. Рассматривается как последовательная реализация алгоритма, так и параллельная. Описывается взаимосвязь свойств программ, реализующих алгоритм, и особенностей архитектуры компьютера, на которой они выполняются. Исследуется работа с памятью, локальность данных и вычислений, описывается масштабируемость и эффективность параллельных программ, производительность компьютеров, достигаемая на данной программе. Обсуждаются особенности реализации для разных классов архитектур компьютеров, приводятся ссылки на реализации в существующих библиотеках.&lt;br /&gt;
&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;
*	число процессоров [1 : 8] (1,2,3,4,8);&lt;br /&gt;
*	размер матрицы [4 : 8192].&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости алгоритм был реализован на библиотеке OpenMP 1.5.5 для языка C++(компилятор g++) на cуперкомпьютере Ломоносов на узле compiler. Для данного узла максимально возможное число потоков - 8. В ходе оценки масштабируемости, программа была запущена в 1, 2, 4, 8 потока. &lt;br /&gt;
Параметры компиляции и запуска: &lt;br /&gt;
&lt;br /&gt;
 ssh compiler &lt;br /&gt;
 module add slurm&lt;br /&gt;
 module add openmpi/1.5.5-icc&lt;br /&gt;
 g++ _scratch/test.c++ -fopenmp -std=c++0x -o test &lt;br /&gt;
 sbatch -p test -n1 run ./test&lt;br /&gt;
&lt;br /&gt;
Для управления количеством потоков использовалась операция OpenMP omp_set_num_threads();&lt;br /&gt;
&lt;br /&gt;
[[File:ResultsDiagram.jpg|thumb|center|left|800px|Рис. 6. График времени работы программы в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Масштабируемость рассматриваемой реализации алгоритма &#039;&#039;&#039;&amp;quot;Разделяй и властвуй&amp;quot;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* При увеличении числа процессов общая эффективность программы увеличивается, т.к. время чтения и подготовки исходной матрицы остаётся неизменным, а время работы алгоритма уменьшается, однако рост незначительный.&lt;br /&gt;
* При увеличении размерности матрицы общая эффективность программы постепенно уменьшается, т.к. время чтения и подготовки исходных данных растёт быстрее, чем время работы исследуемого алгоритма.&lt;br /&gt;
* При одновременном увеличении как числа процессов, так и размерности матрицы общая эффективность программы уменьшается.&lt;br /&gt;
&lt;br /&gt;
Код исследуемой реализации представлен здесь [http://pastebin.com/QpfYZGkK pastebin.com]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Описываемый метод реализован в пакете LAPACK, описание которого можно найти в [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf этой статье] на страницах 7, 19 и 20, которая указана в списке литературы.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Дж. Деммель, «Вычислительная линейная алгебра» //С. 230-235&lt;br /&gt;
&lt;br /&gt;
[2] [http://www.netlib.org/utk/people/JackDongarra/PAPERS/104_1999_a-parallel-divide-and-conquer-algorithm.pdf Francoise Tisseury, Jack Dongarra, A Parallel Divide and Conquer Algorithm for the Symmetric Eigenvalue Problem on Distributed Memory Architectures]&lt;br /&gt;
&lt;br /&gt;
[3] [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf Francoise Tisseury, Jack Dongarra, Parallelizing the Divide and Conquer Algorithm for the Symmetric Tridiagonal Eigenvalue Problem on Distributed Memory Architectures]&lt;br /&gt;
&lt;br /&gt;
[4] [https://en.wikipedia.org/wiki/Divide-and-conquer_eigenvalue_algorithm Алгоритм &amp;quot;Разделяй и властвуй&amp;quot; - Wikipedia]&lt;br /&gt;
&lt;br /&gt;
[5] [http://www.cscamm.umd.edu/tadmor/pub/linear-stability/Gill_Tadmor_SISC90.pdf Doron Grill and Eitan Tadmor AN &amp;lt;math&amp;gt;O(N2)&amp;lt;/math&amp;gt; METHOD FOR COMPUTING THE EIGENSYSTEM OF &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;x&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; SYMMETRIC TRIDIAGONAL MATRICES BY THE DIVIDE AND CONQUER APPROACH]&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22576</id>
		<title>Метод «разделяй и властвуй» вычисления собственных значений и векторов симметричной трехдиагональной матрицы</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22576"/>
		<updated>2017-04-29T20:14:10Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Роман_Землянский|Р.Землянский]] (Разделы &lt;br /&gt;
[[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]]), В.Завольсков (Разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Существующие реализации алгоритма|2.7]]), [[Участник:IgorS]] (предварительная проверка), [[Участник:Chernyavskiy|А.Ю. Чернявский]] (проверка, редактирование).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод &amp;quot;Разделяй и властвуй&amp;quot; вычисления собственных значений и векторов трёхдиагональной матрицы&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt; c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt; O(n^{2.3}) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
крайне редко: &amp;lt;math&amp;gt;  O(n^{2}) &amp;lt;/math&amp;gt; &lt;br /&gt;
| pf_width          = &lt;br /&gt;
| input_data        =  &amp;lt;math&amp;gt; 2n + 1 &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       =  &amp;lt;math&amp;gt; n(n + 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; - это наиболее быстрый из существующих методов, если нужны все собственные значения и собственные векторы трехдиагональной матрицы, начиная с порядка n, примерно равного 26. (Точное значение этого порогового порядка зависит от компьютера.) Его численно устойчивая реализация весьма не тривиальна. В самом деле, хотя впервые метод был предложен еще в 1981 г., &amp;quot;правильный&amp;quot; способ его реализации был найден лишь в 1992 г. Этот способ воплощен LAPACK-программами ssyevd (для плотных матриц) и sstevd (для трехдиагональных матриц). В них стратегия &amp;quot;разделяй-и-влавствуй&amp;quot; используется для матриц порядка, большего чем 25. Для матриц меньшего порядка (или если нужны только собственные значения) происходит автоматический переход к QR-итерации.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Пусть &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
T = \begin{bmatrix}&lt;br /&gt;
 a_{1} &amp;amp; b_{1}&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp; b_{m} &amp;amp; a_{m+1} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
= \begin{bmatrix}&lt;br /&gt;
  a_{1} &amp;amp; b_{1} &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} - b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; a_{m+1} - b_{m} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix} +&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
+ \begin{bmatrix}&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 &amp;amp;&amp;amp;b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&lt;br /&gt;
= \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m} * \begin{bmatrix} 0 \\ \vdots \\ 0 \\ 1 \\ 1 \\ 0 \\ \vdots \\ 0 \end{bmatrix} \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix} &lt;br /&gt;
&lt;br /&gt;
\equiv \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Предположим, что нам известны спектральные разложения матриц &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; T_{2} &amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; T_{i} = Q_{i} \Lambda_{i} Q_{i}^{T} &amp;lt;/math&amp;gt;. В действительности, они будут рекурсивно вычисляться тем же самым алгоритмом. Установим связь между собственными значениями матрицы Т и собственными значениями матриц&lt;br /&gt;
&amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;. Имеем:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt; &lt;br /&gt;
T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} \Lambda_{1} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2} \Lambda_{2} Q_{2}^{T}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}(\begin{bmatrix} \Lambda_{1} &amp;amp; \\  &amp;amp; \Lambda_{2}\end{bmatrix} + b_{m}uu^{T})\begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}&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;&lt;br /&gt;
u = \begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}v&lt;br /&gt;
  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
так как &amp;lt;math&amp;gt;v = \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix}^T&amp;lt;/math&amp;gt;, получим матрицу, состоящую из последнего столбца матрицы &amp;lt;math&amp;gt; Q_{1}^{T}&amp;lt;/math&amp;gt; и первого столбца матрицы &amp;lt;math&amp;gt; Q_{2}^{T}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Следовательно, &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; имеет те же собственные значения, что и подобная ей матрица &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;D = \begin{bmatrix} \Lambda_{1} &amp;amp; 0 \\ 0 &amp;amp; \Lambda_{2}\end{bmatrix}&amp;lt;/math&amp;gt; - диагональная матрица, &lt;br /&gt;
&amp;lt;math&amp;gt;\rho = b_{m}&amp;lt;/math&amp;gt; - число, а &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - вектор. &lt;br /&gt;
&lt;br /&gt;
Будем предполагать, не ограничивая общности, что диагональные элементы &amp;lt;math&amp;gt;d_{1}, \ldots, d_{n}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; упорядочены по убыванию: &amp;lt;math&amp;gt;d_{n} &amp;lt;= \ldots &amp;lt;=d_{1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Чтобы найти собственные значения матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, вычислим её характеристический многочлен, считая пока матрицу &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденной.&lt;br /&gt;
Тогда&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;det(D + \rho uu^{T} - \lambda I) = det((D - \lambda I)(I + \rho (D- \lambda I)^{-1} uu^{T}))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Поскольку &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденна, &amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 0&amp;lt;/math&amp;gt; тогда и только тогда, когда &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; - собственное значение. Заметим, что матрица &amp;lt;math&amp;gt;I + \rho (D - \lambda I)^{-1}uu^{T}&amp;lt;/math&amp;gt; получается из единичной добавлением матрицы ранга 1. Определитель такой матрицы легко вычислить.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;&#039;Лемма 1.&#039;&#039;&#039; Справедливо равенство &amp;lt;math&amp;gt;det(I + xy^{T}) = 1 + y^{T}x&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; - векторы.&lt;br /&gt;
&lt;br /&gt;
Таким образом,&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 1 + \rho u^{T}(D - \lambda I)^{-1}u&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; = 1 + \rho \sum_{i=1, n} \frac{u_{i}^{2}} {d_{i}-\lambda} \equiv f(\lambda)&amp;lt;/math&amp;gt; , &lt;br /&gt;
&lt;br /&gt;
т.е. собственные значения матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; есть корни так называемого векового уравнения &amp;lt;math&amp;gt;f(\lambda) = 0&amp;lt;/math&amp;gt;. Если все числа &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; различны и все &amp;lt;math&amp;gt;u_{i} &amp;lt;&amp;gt; 0&amp;lt;/math&amp;gt; (случай общего положения), то &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; имеет график типа показанного на рис.1(где &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\rho &amp;gt; 0&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
[[File:Graphics.PNG|thumb|center|800px|Рис. 1. График функции &amp;lt;math&amp;gt; f(\lambda) = 1 + \frac{0.5}{1 - \lambda} + \frac{0.5}{2 - \lambda} + \frac{0.5}{3 - \lambda} + \frac{0.5}{4 - \lambda}&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Можно видеть, что прямая &amp;lt;math&amp;gt;y = 1&amp;lt;/math&amp;gt; является горизонтальной асимптотой для этого графика, а прямые &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt; есть вертикальные асимптоты. Поскольку &amp;lt;math&amp;gt;f^{&#039;}(\lambda) =  \rho \sum_{i=1, n} \frac{u_{i}^{2}} {(d_{i}-\lambda)^{2}}&amp;gt; 0 &amp;lt;/math&amp;gt;, функция возрастает всюду, кроме точек &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt;. Поэтому корни функции разделяются числами &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; и ещё один корень находится справа от точки &amp;lt;math&amp;gt;d_{1}&amp;lt;/math&amp;gt; (на рис. 1 &amp;lt;math&amp;gt;d_{1} = 4&amp;lt;/math&amp;gt;). (При &amp;lt;math&amp;gt;\rho&amp;lt;0&amp;lt;/math&amp;gt; функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; всюду убывает и соответствующий корень находится слева от точки &amp;lt;math&amp;gt;d_{n}&amp;lt;/math&amp;gt;). Для функции &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt;, монотонной и гладкой на каждом из интервалов &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;, можно найти вариант метода Ньютона, который быстро и монотонно сходится к каждому из корней, если начальная точка взята в &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;. Нам достаточно знать, что на практике метод сходится к каждому собственному значению за ограниченное число шагов. Поскольку вычисление &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;f^{&#039;}(\lambda)&amp;lt;/math&amp;gt; стоит &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов, для вычисления одного собственного значения достаточно &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, а для вычисления всех &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; собственных значений матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt;O(n^{2})&amp;lt;/math&amp;gt; флопов.&lt;br /&gt;
Для собственных векторов матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; мы легко можем получить явные выражения.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;&#039;Лемма 2.&#039;&#039;&#039; Если &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - собственное значение матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, то соответствующий вектор равен &amp;lt;math&amp;gt;(D - \alpha I)^{-1}u&amp;lt;/math&amp;gt;. Поскольку матрица &amp;lt;math&amp;gt;D - \alpha I&amp;lt;/math&amp;gt; диагональная, для вычисления такого вектора достаточно &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов.&lt;br /&gt;
&lt;br /&gt;
Доказательство.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;(D + \rho uu^{T})[(D - \alpha I)^{-1}u] = (D - \alpha I + \alpha I + \rho uu^{T})(D - \alpha I)^{-1}u&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=u + \alpha (D - \alpha I)^{-1}u + u[\rho u^{T}(D - \alpha I)^{-1}u] &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=u + \alpha(D - \alpha I)^{-1}u - u&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
                                                       поскольку &amp;lt;math&amp;gt; \rho u^{T}(D - \alpha I)^{-1}u + 1 = f(\alpha) = 0 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=\alpha [(D - \alpha I)^{-1}u]&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; собственных векторов требуется &amp;lt;math&amp;gt;O(n^{2})&amp;lt;/math&amp;gt; флопов. К сожалению, формула не обеспечивает численной устойчивости, так как для двух очень близких значений &amp;lt;math&amp;gt;\alpha_{i}&amp;lt;/math&amp;gt; может давать неортогональные приближенные собственные векторы &amp;lt;math&amp;gt;u_{i}&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;d_{i}&amp;lt;/math&amp;gt; различны и все &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt; отличны от нуля. Если это не так, вековое уравнение &amp;lt;math&amp;gt;f(\lambda)=0&amp;lt;/math&amp;gt; имеет &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вертикальных асимптот, где &amp;lt;math&amp;gt;k&amp;lt;n&amp;lt;/math&amp;gt;, а потому &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; корней. Однако оказывается, что остальные &amp;lt;math&amp;gt;n - k&amp;lt;/math&amp;gt; собственных значений могут быть определены без каких-либо усилий: если &amp;lt;math&amp;gt;d_{i}=d_{i+1}&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;u_{i}=0&amp;lt;/math&amp;gt;, то легко показать, что &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; является собственным значением и для матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;. В такой ситуации мы говорим о &#039;&#039;дефляции&#039;&#039;. На практике выбирается некоторое пороговое значение и дефляция для числа &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; регистрируется, если в смысле этого порога &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; достаточно близко к &amp;lt;math&amp;gt;d_{i+1}&amp;lt;/math&amp;gt; либо &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&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;u_{i}=0&amp;lt;/math&amp;gt;, то соответствующий собственный вектор есть i-й столбец &amp;lt;math&amp;gt;e_{i}&amp;lt;/math&amp;gt; единичной матрицы. Это означает, что &amp;lt;math&amp;gt;e_{i}&amp;lt;/math&amp;gt; является i-м столбцом в матрице &amp;lt;math&amp;gt;Q_{&#039;}&amp;lt;/math&amp;gt;, поэтому при формировании матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; посредством левого умножения &amp;lt;math&amp;gt;Q_{1}&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;Q_{2}&amp;lt;/math&amp;gt; вычисление i-го столбца не требует никаких затрат. Аналогичное упрощение имеет место в случае &amp;lt;math&amp;gt;d_{i} = d_{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;
Предположим, что некоторое &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt;, хотя и мало, все же недостаточно мало для того, чтобы была зарегистрирована дефляция. В этом случае применение метода Ньютона к решению векового уравнения встречается с затруднениями. Вспомним, что пересчет приближённого решения &amp;lt;math&amp;gt;u_{j}&amp;lt;/math&amp;gt; уравнения &amp;lt;math&amp;gt;f(\lambda) = 0&amp;lt;/math&amp;gt; в методе Ньютона основан на следующих положениях:&lt;br /&gt;
&lt;br /&gt;
 1. Вблизи точки &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt; функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; аппроксимируется линейной функцией &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt;; график есть прямая линия, касающаяся графика функции &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 2. В качестве &amp;lt;math&amp;gt;\lambda_{j+1}&amp;lt;/math&amp;gt; берётся нуль этого линейного приближения, т.е. &amp;lt;math&amp;gt;l(\lambda_{j+1})=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Функция, показанная на рис.1, не доставляет видимых трудностей методу Ньютона, поскольку вблизи каждого своего нуля &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; достаточно хорошо аппроксимируется линейными функциями. Однако рассмотрим график функции на рис. 4. Она получена из функции на рис. 1 заменой значения .5 для &amp;lt;math&amp;gt;u_{i}^{2}&amp;lt;/math&amp;gt; на .001. Это новое значение недостаточно мало для того, чтобы вызвать дефляцию. График функции в левой части рис.4 визуально не отличим от её вертикальных и горизонтальных асимптот, поэтому в правой части укрупненно воспроизведён фрагмент графика, прилегающий к вертикальной асимптоте &amp;lt;math&amp;gt;\lambda = 2&amp;lt;/math&amp;gt;. Видно, что график слишком быстро &amp;quot;выполняет поворот&amp;quot; и для большей части значений &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; почти горизонтален. Поэтому, применяя метод Ньютона почти к любому начальному приближению &amp;lt;math&amp;gt;\lambda_{0}&amp;lt;/math&amp;gt;, мы получаем линейное приближение &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt; с почти горизонтальным графиком и малым положительным угловым коэффициентом. В результате &amp;lt;math&amp;gt;\lambda_{1}&amp;lt;/math&amp;gt; является отрицательным числом, огромным по абсолютной величине, которое совершенно бесполезно в качестве приближения к истинному корню.&lt;br /&gt;
&lt;br /&gt;
[[File:GraphNewton.png|thumb|center|800px|Рис. 4. График функции &amp;lt;math&amp;gt; f(\lambda) = 1 + \frac{10^{-3}}{1 - \lambda} + \frac{10^{-3}}{2 - \lambda} + \frac{10^{-3}}{3 - \lambda} + \frac{10^{-3}}{4 - \lambda}&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Чтобы найти выход из этого положения, можно модифицировать метод Ньютона следующим образом: раз &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; нельзя хорошо приблизить линейной функцией &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt;, попробуем взять в качестве приближения какую-нибудь другую простую функцию &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;. Нет ничего особого именно в прямых линиях: для метода Ньютона вместо &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt; можно взять любое приближение &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;, значения и нули которого легко вычисляются. Функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; имеет полюсы в точках &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;d_{i+1}&amp;lt;/math&amp;gt;, которые определяют её поведение в соответствующих окрестностях. Поэтому при поиске корня в интервале &amp;lt;math&amp;gt;(d_{i+1}, d_{i})&amp;lt;/math&amp;gt; естественно выбрать функцию &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;, также имеющую эти полюсы, т.е. функцию вида&lt;br /&gt;
 &amp;lt;math&amp;gt;h(\lambda)= \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} + c_{3}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Константы &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; обеспечивающие, что &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt; есть приближение к &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt;, можно выбрать несколькими способами. Отметим, что если &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; уже известны, то уравнение &amp;lt;math&amp;gt;h(\lambda)=0&amp;lt;/math&amp;gt; легко решается относительно &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt;, поскольку сводится к эквивалентному квадратному уравнению&lt;br /&gt;
 &amp;lt;math&amp;gt;c_{1}(d_{i+1}-\lambda)+c_{2}(d_{i}-\lambda)+c_{3}(d_{i}-\lambda)(d_{i+1}-\lambda)=0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;\lambda_{j}&amp;lt;/math&amp;gt; - приближённое значение корня. определим &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; так, чтобы&lt;br /&gt;
 &amp;lt;math&amp;gt;\frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} + c_{3} = h(\lambda) \approx f(\lambda) = 1 + \rho \sum_{k=1, n} \frac{u_{k}^{2}} {d_{k}-\lambda} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
для &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; в окрестности &amp;lt;math&amp;gt;\lambda_{j}&amp;lt;/math&amp;gt;. Заметим, что&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;f(\lambda) = 1 + \rho \sum_{k=1, i} \frac{u_{k}^{2}} {d_{k}-\lambda} + \rho \sum_{k=i+1, n} \frac{u_{k}^{2}} {d_{k}-\lambda} \equiv 1 + \psi_{1}(\lambda) + \psi_{2}(\lambda)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\lambda \in (d_{i+1},d_{i})&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\psi_{1}(\lambda)&amp;lt;/math&amp;gt; есть сумма положительных слагаемых, а &amp;lt;math&amp;gt;\psi_{2}(\lambda)&amp;lt;/math&amp;gt; - сумма отрицательных. Поэтому и &amp;lt;math&amp;gt;\psi_{1}(\lambda)&amp;lt;/math&amp;gt;, и &amp;lt;math&amp;gt;\psi_{2}(\lambda)&amp;lt;/math&amp;gt; могут быть вычислены с высокой точностью; однако при их сложении вполне вероятно взаимное уничтожение верных разрядов и потеря относительной точности в сумме. Возьмем числа &amp;lt;math&amp;gt;c_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{1}}&amp;lt;/math&amp;gt;, такие, что функция &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h_{1}(\lambda) \equiv \hat{c_{1}} + \frac{c_{1}}{d_{i}-\lambda}&amp;lt;/math&amp;gt;   удовлетворяет условиям  &amp;lt;math&amp;gt;h_{1}(\lambda_{j}) = \psi_{1}(\lambda_{j})&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;h_{1}^{&#039;}(\lambda_{j})=\psi_{1}^{&#039;}(\lambda_{j})&amp;lt;/math&amp;gt; (1)&lt;br /&gt;
&lt;br /&gt;
Это означает, что гипербола, являющаяся графиком функции &amp;lt;math&amp;gt;h_{1}(\lambda)&amp;lt;/math&amp;gt;, касается графика функции &amp;lt;math&amp;gt;\psi_{i}(\lambda)&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt;. Два условия в (1) - это обычные условия метода Ньютона, за исключением того, что вместо прямой в качестве приближения используется гипербола. Легко проверить, что &amp;lt;math&amp;gt;c_{1}=\psi_{1}^{&#039;}(\lambda_{j})(d_{i} - \lambda_{j})^{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{1}}=\psi_{1}(\lambda_{j}) - \psi_{1}^{&#039;}(\lambda_{j})(d_{i} - \lambda_{j})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подобным же образом выбираем &amp;lt;math&amp;gt;c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{2}}&amp;lt;/math&amp;gt; так, чтобы функция &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h_{2}(\lambda) \equiv \hat{c_{2}} + \frac{c_{2}}{d_{i+1}-\lambda}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Удовлетворяла условиям&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;h_{2}(\lambda_{j}) = \psi_{2}(\lambda_{j})&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;h_{2}^{&#039;}(\lambda_{j})=\psi_{2}^{&#039;}(\lambda_{j})&amp;lt;/math&amp;gt; (2)&lt;br /&gt;
&lt;br /&gt;
Наконец, полагаем&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h(\lambda) = 1 + h_{1}(\lambda) + h_{2}(\lambda) = (1 + \hat{c_{1}} + \hat{c_{2}} + \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;\equiv c_{3} + \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром последовательной схемы решения является вычисление матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; собственных векторов путём умножения матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; Данная операция имеет сложность &amp;lt;math&amp;gt;cn^{3}&amp;lt;/math&amp;gt; о чём и говорится в разделе [[#Последовательная сложность алгоритма]] .&lt;br /&gt;
Ей предшествует вычисление собственных значений и векторов матрицы &amp;lt;math&amp;gt; D + \rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Ниже описана структура алгоритма, в которой есть блок умножения матриц для вычисления собственных векторов, являющийся вычислительным ядром алгоритма. В соответствующем разделе ([[#Вычислительное ядро алгоритма]]) мы упоминали о том, что данному блоку предшествует вычисление собственных значений, которое производится [https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%9D%D1%8C%D1%8E%D1%82%D0%BE%D0%BD%D0%B0 методом Ньютона].&lt;br /&gt;
&lt;br /&gt;
[[File:DivideAndConquerTree.png|thumb|center|left|800px|Рис. 2. Дерево алгоритма &amp;quot;Разделяй и властвуй&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
[[File:InfoGraph.jpg|thumb|center|1200px|Рис. 3. Детальное описание одного блока алгоритма]]&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&#039;&#039;Вычисление собственных значений и собственных векторов симметричной трехдиагональной матрицы посредством стратегии &amp;quot;разделяй и властвуй&amp;quot;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;proc dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T,Q,\Lambda)...&amp;lt;/math&amp;gt; по входной матрице &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются выходные матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;T = Q\Lambda Q^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Если &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - матрица размера &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; x &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  1. Присвоить выходным параметрам значения &amp;lt;math&amp;gt; Q = 1, \Lambda = T&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Иначе&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  1. Представить &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; в виде &amp;lt;math&amp;gt; T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  2. &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{1},Q_{1},\Lambda_{1})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  3. &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{2},Q_{2},\Lambda_{2})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  4. Построить &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt; по &amp;lt;math&amp;gt; \Lambda_{1},\Lambda_{2}, Q_{1}, Q_{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  5. Найти матрицу собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  6. Найти матрицу собственных векторов &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  7. Построить матрицу собственных векторов &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; : &amp;lt;math&amp;gt; Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}* Q^{&#039;} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  8. Присвоить выходным параметрам значения &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;endif&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Проанализируем сложность алгоритма. Пусть &amp;lt;math&amp;gt;t(n)&amp;lt;/math&amp;gt; - число флопов при обработке матрицы размера &amp;lt;math&amp;gt; n x n&amp;lt;/math&amp;gt; процедурой &#039;&#039;dc_eig&#039;&#039;. Тогда &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; t(n) = 2t(n/2) &amp;lt;/math&amp;gt; два рекурсивных обращения к &#039;&#039;dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{i},Q_{i},\Lambda_{i})&amp;lt;/math&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;D+\rho uu^{T}&amp;lt;/math&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;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; +c*n^{3}&amp;lt;/math&amp;gt; вычисление матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}*Q^{&#039;}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; Q_{1}, Q_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; рассматриваются как плотные матрицы и используется стандартный алгоритм матричного умножения, то константа &amp;lt;math&amp;gt; c &amp;lt;/math&amp;gt; в последней строке равна 1. Таким образом, именно это умножение составляет наиболее трудоёмкую часть алгоритма в целом. Игнорируя члены порядка &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;, получаем &amp;lt;math&amp;gt;t(n) = 2t(n/2) + cn^{3}&amp;lt;/math&amp;gt;. Решая это разностное уравнение, находим &amp;lt;math&amp;gt; t \approx c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На практике константа &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; обычно гораздо меньше 1, потому что матрица &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; весьма разрежена вследствие явления, называемого дефляцией.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
В данном разделе на рисунке 5 представлен информационный граф алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[File:InfoGraphSC.jpg|thumb|center|left|1200px|Рис. 5. Информационный граф алгоритма &amp;quot;Разделяй и властвуй&amp;quot; - шаг &amp;lt;b&amp;gt;Divide&amp;lt;/b&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Операции: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; - операция Divide разделения матрицы &amp;lt;math&amp;gt; T &amp;lt;/math&amp;gt; на матрицы &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Индексы - размерность &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{k}&amp;lt;/math&amp;gt; - операция Conquer сбора матрицы &amp;lt;math&amp;gt; D &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_{k} &amp;lt;/math&amp;gt; - операция поиска собственных значений &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; S^{&#039;} &amp;lt;/math&amp;gt; - операция поиска собственных векторов матрицы &amp;lt;math&amp;gt; Q^{&#039;} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; S &amp;lt;/math&amp;gt; - операция поиска собственных векторов матрицы &amp;lt;math&amp;gt; Q &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Рассмотрев информационный граф алгоритма, можно заметить, что в структуре имеется два параллельных блока - вызов рекурсивных функций &#039;&#039;dc_eig&#039;&#039; для вычисления собственных значений и векторов матриц &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&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;dc_eig&#039;&#039; отрабатывают последовательно - сначала со входными параметрами &amp;lt;math&amp;gt;T_{1}, Q_{1}, \Lambda_{1}&amp;lt;/math&amp;gt;, затем - &amp;lt;math&amp;gt;T_{2}, Q_{2}, \Lambda_{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, благодаря параллелизму высота алгоритма параллельного составляет &amp;lt;math&amp;gt;log_{2}(n)&amp;lt;/math&amp;gt;, когда как при последовательной реализации высота алгоритма равна сумме геометрической прогрессии &amp;lt;math&amp;gt;1+2+4+8+...+2^{n-1} = 2^{n} - 1&amp;lt;/math&amp;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;
&amp;lt;math&amp;gt;&lt;br /&gt;
L = \begin{bmatrix}&lt;br /&gt;
 a_{1} &amp;amp; b_{1}&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp; b_{m} &amp;amp; a_{m+1} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&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;2n + 1&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; n &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;
&lt;br /&gt;
&amp;lt;math&amp;gt; n + n^{2} = n(n + 1) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Описанный в данной статье алгоритм является самым быстрым алгоритмом, среди существующих: QR / Бисекция и обратная итерация / Разделяй и властвуй.&lt;br /&gt;
&lt;br /&gt;
Последовательная сложность алгоритма (не принимая во внимание дефляцию) удовлетворяет рекурсивному соотношению: &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;t(n) = n^3 +2t(\frac{n}{2})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Решение которого имеет вид:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt; t = c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На практике же, параллельная сложность алгоритма в силу использования дефляции, позволяющей получить выигрыш в количестве операций, который заключается в ускорении матричного умножения на последнем шаге алгоритма (см. [[#Дефляция]]), имеет следующий вид: &amp;lt;math&amp;gt; O(n^{2.3})&amp;lt;/math&amp;gt;  или в самых редких случаях &amp;lt;math&amp;gt; O(n^{2}) &amp;lt;/math&amp;gt; (см. [3] стр. 8).&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;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
Вторая часть описания алгоритмов в рамках AlgoWiki рассматривает все составные части процесса их реализации. Рассматривается как последовательная реализация алгоритма, так и параллельная. Описывается взаимосвязь свойств программ, реализующих алгоритм, и особенностей архитектуры компьютера, на которой они выполняются. Исследуется работа с памятью, локальность данных и вычислений, описывается масштабируемость и эффективность параллельных программ, производительность компьютеров, достигаемая на данной программе. Обсуждаются особенности реализации для разных классов архитектур компьютеров, приводятся ссылки на реализации в существующих библиотеках.&lt;br /&gt;
&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;
*	число процессоров [1 : 8] (1,2,3,4,8);&lt;br /&gt;
*	размер матрицы [4 : 8192].&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости алгоритм был реализован на библиотеке OpenMP 1.5.5 для языка C++(компилятор g++) на cуперкомпьютере Ломоносов на узле compiler. Для данного узла максимально возможное число потоков - 8. В ходе оценки масштабируемости, программа была запущена в 1, 2, 4, 8 потока. &lt;br /&gt;
Параметры компиляции и запуска: &lt;br /&gt;
&lt;br /&gt;
 ssh compiler &lt;br /&gt;
 module add slurm&lt;br /&gt;
 module add openmpi/1.5.5-icc&lt;br /&gt;
 g++ _scratch/test.c++ -fopenmp -std=c++0x -o test &lt;br /&gt;
 sbatch -p test -n1 run ./test&lt;br /&gt;
&lt;br /&gt;
Для управления количеством потоков использовалась операция OpenMP omp_set_num_threads();&lt;br /&gt;
&lt;br /&gt;
[[File:ResultsDiagram.jpg|thumb|center|left|800px|Рис. 6. График времени работы программы в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Масштабируемость рассматриваемой реализации алгоритма &#039;&#039;&#039;&amp;quot;Разделяй и властвуй&amp;quot;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* При увеличении числа процессов общая эффективность программы увеличивается, т.к. время чтения и подготовки исходной матрицы остаётся неизменным, а время работы алгоритма уменьшается, однако рост незначительный.&lt;br /&gt;
* При увеличении размерности матрицы общая эффективность программы постепенно уменьшается, т.к. время чтения и подготовки исходных данных растёт быстрее, чем время работы исследуемого алгоритма.&lt;br /&gt;
* При одновременном увеличении как числа процессов, так и размерности матрицы общая эффективность программы уменьшается.&lt;br /&gt;
&lt;br /&gt;
Код исследуемой реализации представлен здесь [http://pastebin.com/QpfYZGkK pastebin.com]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Описываемый метод реализован в пакете LAPACK, описание которого можно найти в [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf этой статье] на страницах 7, 19 и 20, которая указана в списке литературы.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Дж. Деммель, «Вычислительная линейная алгебра» //С. 230-235&lt;br /&gt;
&lt;br /&gt;
[2] [http://www.netlib.org/utk/people/JackDongarra/PAPERS/104_1999_a-parallel-divide-and-conquer-algorithm.pdf Francoise Tisseury, Jack Dongarra, A Parallel Divide and Conquer Algorithm for the Symmetric Eigenvalue Problem on Distributed Memory Architectures]&lt;br /&gt;
&lt;br /&gt;
[3] [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf Francoise Tisseury, Jack Dongarra, Parallelizing the Divide and Conquer Algorithm for the Symmetric Tridiagonal Eigenvalue Problem on Distributed Memory Architectures]&lt;br /&gt;
&lt;br /&gt;
[4] [https://en.wikipedia.org/wiki/Divide-and-conquer_eigenvalue_algorithm Алгоритм &amp;quot;Разделяй и властвуй&amp;quot; - Wikipedia]&lt;br /&gt;
&lt;br /&gt;
[5] [http://www.cscamm.umd.edu/tadmor/pub/linear-stability/Gill_Tadmor_SISC90.pdf Doron Grill and Eitan Tadmor AN &amp;lt;math&amp;gt;O(N2)&amp;lt;/math&amp;gt; METHOD FOR COMPUTING THE EIGENSYSTEM OF &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;x&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; SYMMETRIC TRIDIAGONAL MATRICES BY THE DIVIDE AND CONQUER APPROACH]&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22575</id>
		<title>Метод «разделяй и властвуй» вычисления собственных значений и векторов симметричной трехдиагональной матрицы</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22575"/>
		<updated>2017-04-29T20:09:45Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Роман_Землянский|Р.Землянский]] (Разделы &lt;br /&gt;
[[#Общее описание алгоритма|1.1]], [[#Математическое описание алгоритма|1.2]], [[#Последовательная сложность алгоритма|1.6]], [[#Ресурс параллелизма алгоритма|1.8]], [[#Входные и выходные данные алгоритма|1.9]], [[#Свойства алгоритма|1.10]]), В.Завольсков (Разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Существующие реализации алгоритма|2.7]]), [[Участник:IgorS]] (предварительная проверка), [[Участник:Chernyavskiy|А.Ю. Чернявский]] (проверка, редактирование).&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22574</id>
		<title>Метод «разделяй и властвуй» вычисления собственных значений и векторов симметричной трехдиагональной матрицы</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22574"/>
		<updated>2017-04-29T20:06:35Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Роман_Землянский|Р.Землянский]] (Разделы ), [[Участник:Владислав_Завольсков|В.Завольсков]] (Разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Существующие реализации алгоритма|2.7]]), [[Участник:IgorS]] (предварительная проверка), [[Участник:Chernyavskiy|А.Ю. Чернявский]] (проверка, редактирование).&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22573</id>
		<title>Метод «разделяй и властвуй» вычисления собственных значений и векторов симметричной трехдиагональной матрицы</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22573"/>
		<updated>2017-04-29T20:01:09Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Zemlyanskiy|Р.Землянский]] (Разделы ), [[Участник:Zavolskov|В.Завольсков]] (Разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Существующие реализации алгоритма|2.7]]), [[Участник:IgorS]] (предварительная проверка), [[Участник:Chernyavskiy|А.Ю. Чернявский]] (проверка, редактирование).&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22572</id>
		<title>Метод «разделяй и властвуй» вычисления собственных значений и векторов симметричной трехдиагональной матрицы</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=22572"/>
		<updated>2017-04-29T20:00:39Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Основные авторы описания: [[Участник:Zemlyansky|Р.Землянский]] (Разделы ), [[Участник:Zavolskov|В.Завольсков]] (Разделы [[#Вычислительное ядро алгоритма|1.3]], [[#Макроструктура алгоритма|1.4]], [[#Схема реализации последовательного алгоритма|1.5]], [[#Информационный граф|1.7]], [[#Существующие реализации алгоритма|2.7]]), [[Участник:IgorS]] (предварительная проверка), [[Участник:Chernyavskiy|А.Ю. Чернявский]] (проверка, редактирование).&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</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:Error0x0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22492</id>
		<title>Участник:Error0x0/Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией</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:Error0x0/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9B%D0%B0%D0%BD%D1%86%D0%BE%D1%88%D0%B0_%D0%B4%D0%BB%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B8_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D1%82%D0%BE%D1%87%D0%BA%D0%BE%D0%B9_%D1%81_%D0%BF%D0%BE%D0%BB%D0%BD%D0%BE%D0%B9_%D0%BF%D0%B5%D1%80%D0%B5%D0%BE%D1%80%D1%82%D0%BE%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B5%D0%B9&amp;diff=22492"/>
		<updated>2017-02-11T17:34:24Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(k^2 n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(k \log k \log n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(kn)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;n^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;
Автор описания: [[Участник:Error0x0|В. А. Янушковский]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Алгоритм Ланцоша представляет собой итерационный алгоритм для вычисления собственных значений симметрической матрицы. &lt;br /&gt;
Идея алгоритма заключается в построении матрицы &amp;lt;math&amp;gt;Q_k = [q_1, ..., q_k]&amp;lt;/math&amp;gt; из ортонормированных векторов Ланцоша и использовании собственных значений трёхдиагональной матрицы &amp;lt;math&amp;gt;T_k = Q_k^T A Q_k&amp;lt;/math&amp;gt; (чисел Ритца) как приближения к искомым собственным числам матрицы&amp;lt;ref name=&amp;quot;Деммель&amp;quot;&amp;gt;Деммель&amp;amp;nbsp;Дж. Вычислительная линейная алгебра&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;
Пусть &amp;lt;math&amp;gt;q_1 = b/||b||_2, \beta_0=0, q_0=0&amp;lt;/math&amp;gt;&lt;br /&gt;
Алгоритм производит &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; итераций на каждой из которых:&lt;br /&gt;
# вычисляется &amp;lt;math&amp;gt;z = Aq_j&amp;lt;/math&amp;gt;,&lt;br /&gt;
# производится переортогонализация &amp;lt;math&amp;gt;z = z - \sum^{j-1}_{i=1} {(z^T q_i)q_i}&amp;lt;/math&amp;gt;,&lt;br /&gt;
# &amp;lt;math&amp;gt;\beta_j = ||z||_2&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;\beta_j = 0&amp;lt;/math&amp;gt;, алгоритм останавливается,&lt;br /&gt;
# &amp;lt;math&amp;gt;q_{j+1} = z/\beta_j&amp;lt;/math&amp;gt;,&lt;br /&gt;
# вычисляются собственные значения и векторы матрицы &amp;lt;math&amp;gt;T_j = Q_j^T A Q_j&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;z = z - \sum^{j-1}_{i=1} {(z^T q_i)q_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Алгоритм имеет следующую макроструктуру:&lt;br /&gt;
* Начальная инициализация (деление вектора на норму &amp;lt;math&amp;gt;q_1 = b/||b||_2&amp;lt;/math&amp;gt;)&lt;br /&gt;
* Далее &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; итераций, каждая из которых может быть разложена:&lt;br /&gt;
** Умножение матрицы на вектор (&amp;lt;math&amp;gt;z = Aq_j&amp;lt;/math&amp;gt;)&lt;br /&gt;
** Переортогонализация &amp;lt;math&amp;gt;z = z - \sum^{j-1}_{i=1} {(z^T q_i)q_i}&amp;lt;/math&amp;gt;&lt;br /&gt;
** Нахождение следующего вектора &amp;lt;math&amp;gt;q_{j+1} = z/\beta_j&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;\beta_j = ||z||_2&amp;lt;/math&amp;gt;&lt;br /&gt;
** Нахождение следующего собственного значения и вектора матрицы &amp;lt;math&amp;gt;T_j = Q_j^T A Q_j&amp;lt;/math&amp;gt; (числа Ритца, используется метод &amp;quot;разделяй и властвуй&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
beta[0] = 0 # инициализация&lt;br /&gt;
q[0] = 0&lt;br /&gt;
q[1] = b / norm(b) # вычисление первого столбца&lt;br /&gt;
for j in [1 .. k]: # k итераций&lt;br /&gt;
    z = mul(A, q[j]) # вектор Ланцоша как произведение матрицы A на столбец q[j]&lt;br /&gt;
    alpha[j] = scalar_mul(q[j], z) # вычисление alpha[j]&lt;br /&gt;
    for i in [1 .. j - 1]: # полная переортогонализация&lt;br /&gt;
        z -= scalar_mul(z, q[i]) * q[i]&lt;br /&gt;
    beta[j] = norm(z) # вычисление нормы z&lt;br /&gt;
    if beta[j] == 0: # останов, если норма z равна нулю&lt;br /&gt;
        break&lt;br /&gt;
    result.append(next_ritz_number(alpha, beta, j)) # вычисление следующего собственного значения и вектора матрицы Tj&lt;br /&gt;
return result&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;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;i \in [0...j-1]&amp;lt;/math&amp;gt; выполняется &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений, итого &amp;lt;math&amp;gt;\frac{k(k-1)}{2} 4n \approx 2k^2 n&amp;lt;/math&amp;gt;. &lt;br /&gt;
Таким образом, для метода с полной переортогонализацией сложность составляет &amp;lt;math&amp;gt;O(k^2 n)&amp;lt;/math&amp;gt;, сложность по памяти -- &amp;lt;math&amp;gt;O(kn)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
На рисунке приведён информационный граф одной итерации алгоритма&lt;br /&gt;
[[File:Lanczos graph.png|thumb|center|800px|Рисунок 1. Информационный граф итерации алгоритма]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Для процесса переортогонализации возможна параллельная оптимизация в двух местах:&lt;br /&gt;
* Итерации внутреннего цикла могут вычисляться параллельно, однако, требуется суммирование вычитаемых векторов, соответственно, сложность переортогонализации можно снизить с &amp;lt;math&amp;gt;O(kn)&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;O(n \log k)&amp;lt;/math&amp;gt;&lt;br /&gt;
* В каждой итерации внутреннего цикла возможно распараллеливание вычисления выражения справа (скалярное произведение и умножение вектора на число), что теоретически позволяет снизить сложность итерации с &amp;lt;math&amp;gt;O(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;
&#039;&#039;&#039;Входные данны&#039;&#039;&#039;е: квадратная симметрическая матрица &amp;lt;math&amp;gt;A&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^2&amp;lt;/math&amp;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;: &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;z&amp;lt;/math&amp;gt; векторам &amp;lt;math&amp;gt;q_1, ..., q_k&amp;lt;/math&amp;gt;. В случае идеально точной арифметики данная переортогонализация не требовалась бы, однако в реальных вычислениях ошибки округления приводят к потере ортогональности, в связи с чем требуется переортогонализация.&lt;br /&gt;
Однако, единственной проблемой, возникающей при отсутствии переортогонализации, является появление повторных копий чисел Ритца (собственных значений), что в случае, если не требуется установление кратностей собственных значений, допустимо.&lt;br /&gt;
&lt;br /&gt;
Вычислительная мощность алгоритма примерно равна &amp;lt;math&amp;gt;2k^2 / 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;
Исследование масштабируемости алгоритма проводилось на суперкомпьютере IBM Blue Gene/P ВМК МГУ.&lt;br /&gt;
&lt;br /&gt;
Алгоритм тестировался на следующих параметрах:&lt;br /&gt;
* размер входной матрицы: 2048-8192 с шагом 512&lt;br /&gt;
* число узлов: 1-256     &lt;br /&gt;
&lt;br /&gt;
Зависимость времени выполнения от параметров изображена на графике:&lt;br /&gt;
&lt;br /&gt;
[[Файл:Lanczos full chart.png|center|border |800px]]&lt;br /&gt;
Из рисунка видно, что алгоритм хорошо масштабируется, время выполнения на одном ядре растёт существенно быстрее чем на множестве ядер. При этом, для маленькой матрице на большом числе ядер прирост эффективности практически отсутствует.&lt;br /&gt;
&lt;br /&gt;
[http://pastebin.com/u7KThy6D  Используемая реализация алгоритма на языке C++]&lt;br /&gt;
&lt;br /&gt;
Пример компиляции и запуска:&lt;br /&gt;
  $ mpixlcxx_r -o lanczos lanczos.cpp&lt;br /&gt;
  $ mpisubmit.bg -n 256 -w 00:5:00 lanczos&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://www.nag.co.uk/numeric/fl/nagdoc_fl23/html/INDEXES/KWIC/lanczos.html NAG Library] содержит ряд процедур для решения СЛАУ и поиска собственных значений на основе алгоритма Ланцоша.&lt;br /&gt;
&lt;br /&gt;
[http://www.mathworks.com/help/techdoc/ref/eigs.html MATLAB] и [https://www.gnu.org/software/octave/doc/interpreter/Sparse-Linear-Algebra.html#doc_002deigs GNU Octave] позволяют с помощью функции &#039;&#039;eigs()&#039;&#039; находить собственные значения на основе данного алгоритма.&lt;br /&gt;
&lt;br /&gt;
Matlab-реализация доступна как часть [http://www.cs.cmu.edu/~bickson/gabp/#download Gaussian Belief Propagation Matlab Package]. [http://www.graphlab.ml.cmu.edu/pmf.html GraphLab] содержит несколько параллельных реализаций алгоритма на C++.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</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:Error0x0&amp;diff=22491</id>
		<title>Обсуждение участника:Error0x0</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:Error0x0&amp;diff=22491"/>
		<updated>2017-02-11T17:34:02Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Статья Участник:Error0x0/Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Статья [[Участник:Error0x0/Алгоритм Ланцоша для арифметики с плавающей точкой с полной переортогонализацией]] ==&lt;br /&gt;
&lt;br /&gt;
* В разделе 1.3 не приведено описание вычислительного ядра&lt;br /&gt;
* Не указано ФИО автора&lt;br /&gt;
* Не приведена краткая сводка свойств алгоритма в начале статьи&lt;br /&gt;
&lt;br /&gt;
Добавил.&lt;br /&gt;
&lt;br /&gt;
* В разделе 1.4 требуется привести описание алгоритма на верхнем уровне (на основе макроопераций). [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 17:35, 1 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 1.5 кроме кода нужны также текстовые пояснения. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 17:35, 1 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 1.10 должна быть оценка вычислительной мощности алгоритма. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 17:35, 1 ноября 2016 (MSK)&lt;br /&gt;
* Не заполнен раздел 2.4 описания. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:44, 16 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
Пункты 1.4, 1.5, 1.10 исправлены, пункт 2.4 добавлен&lt;br /&gt;
* В разделе 1.4 должно быть не перечисление макроопераций, а нужно показать структуру алгоритма на макроуровне. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 17:10, 3 февраля 2017 (MSK)&lt;br /&gt;
* Граф, приведённый в разделе 1.7, не является информационным графом (направленный ациклический граф, вершины - операции, дуги - информационные зависимости). [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 17:10, 3 февраля 2017 (MSK)&lt;br /&gt;
* В разделе 2.4 не приведены все параметры запуска теста - например, с какими опциями проводилась компиляция. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 17:10, 3 февраля 2017 (MSK) &lt;br /&gt;
* Из графиков в разделе 2.4 следует сделать выводы о масштабируемости реализации. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 17:10, 3 февраля 2017 (MSK)&lt;br /&gt;
&lt;br /&gt;
Исправлено.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Замечания:&lt;br /&gt;
&lt;br /&gt;
*Информационный граф должен содержать не просто макроструктуру, но и взаимодействие на уровне данных между различными операциями.&lt;br /&gt;
*Из общего и, главное, математического описания алгоритма должно быть понятно, почему он работает (необходимы хотя бы краткие объяснения, а не просто шаги).&lt;br /&gt;
*Сколько раз делается ортогонализация? Один или два?&lt;br /&gt;
*Объясните, почему основной вклад дает только переортогонализация. Она сильно затратнее умножения матрицы на вектор?&lt;br /&gt;
*Не совсем понятна последовательная сложность. В цикле ведь происходит умножение матрицы на вектор, а это квадратичная по размерности матрицы операция.&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</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:Amirida/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=21800</id>
		<title>Участник:Amirida/Метод «разделяй и властвуй» вычисления собственных значений и векторов симметричной трехдиагональной матрицы</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:Amirida/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%C2%AB%D1%80%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9%C2%BB_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D1%85_%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D0%B9_%D0%B8_%D0%B2%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D1%82%D1%80%D0%B5%D1%85%D0%B4%D0%B8%D0%B0%D0%B3%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B&amp;diff=21800"/>
		<updated>2017-01-30T08:52:04Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Метод «разделяй и властвуй» вычисления собственных значений и векторов симметричной трехдиагональной матрицы.&lt;br /&gt;
&lt;br /&gt;
Авторы:&lt;br /&gt;
 &lt;br /&gt;
Изотова И.А. (619 группа) пункты 1.1, 1.2, 1.5, 1.7, 1.9&lt;br /&gt;
&lt;br /&gt;
Ульянов Г.В. (619 группа) пункты 1.3, 1.4, 1.6, 1.8, 1.10&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;n &amp;gt; 25&amp;lt;/math&amp;gt; (точное значение этого порогового порядка зависит от компьютера.) Однако алгоритм не гарантирует высокой относительной точности для малых собственных значений.Его численно устойчивая реализация весьма не тривиальна. Хотя впервые метод был предложен еще в 1981 г., &amp;quot;правильный&amp;quot; способ его реализации был найден лишь в 1992 г. Этот способ воплощен LAPACK-программами ssyevd (для плотных матриц) и sstevd (для трехдиагональных матриц). В них стратегия &amp;quot;разделяй-и-влавствуй&amp;quot; используется для матриц порядка, большего чем 25. Для матриц меньшего порядка (или если нужны только собственные значения) происходит автоматический переход к QR-итерации. Однако, из-за высокой сложности, алгоритм пока не вошел в состав ALGLIB.&lt;br /&gt;
&lt;br /&gt;
В наихудшем случае алгоритм «разделяй-и-властвуй» требует &amp;lt;math&amp;gt; O(n^{3})&amp;lt;/math&amp;gt; операций, но константа, на практике оказывается весьма малой. На большой выборке случайных тестовых матриц в среднем затрачивается лишь &amp;lt;math&amp;gt; O(n^{2.3})&amp;lt;/math&amp;gt; операций с плавающей точкой, а для некоторых специальных распределений собственных значений — &amp;lt;math&amp;gt; O(n^{2})&amp;lt;/math&amp;gt; (подробнее в разделе [[1.6 Последовательная сложность алгоритма]]).&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;T, T_{1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt; имеют размерность &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;m \times m&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;(n - m) \times (n - m)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Запишем матрицу &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; в следующем виде:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
T = \begin{bmatrix}&lt;br /&gt;
 a_{1} &amp;amp; b_{1}&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp; b_{m} &amp;amp; a_{m+1} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
= \begin{bmatrix}&lt;br /&gt;
  a_{1} &amp;amp; b_{1} &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} - b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; a_{m+1} - b_{m} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix} +&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
+ \begin{bmatrix}&lt;br /&gt;
 b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&lt;br /&gt;
= \begin{bmatrix}&lt;br /&gt;
 T_{1} &amp;amp; 0 \\ &lt;br /&gt;
0 &amp;amp; T_{2}&lt;br /&gt;
\end{bmatrix} + b_{m} * \begin{bmatrix} 0 \\ \vdots \\ 0 \\ 1 \\ 1 \\ 0 \\ \vdots \\ 0 \end{bmatrix} \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix} &lt;br /&gt;
&lt;br /&gt;
\equiv \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Предположим, что нам известны спектральные разложения матриц &amp;lt;math&amp;gt;\hat{T}_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{T}_{2}&amp;lt;/math&amp;gt;, т.е.:&lt;br /&gt;
&amp;lt;math&amp;gt;\hat{T}_{1} = Q_{1} D_{1} Q_{1}^{T}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{T}_{2} = Q_{2} D_{2} Q_{2}^{T}&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;T&amp;lt;/math&amp;gt; и собственными значениями матриц &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; &lt;br /&gt;
T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} \Lambda_{1} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2} L_{2} Q_{2}^{T}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}(\begin{bmatrix} \Lambda_{1} &amp;amp; \\  &amp;amp; \Lambda_{2}\end{bmatrix} + b_{m}vv^{T})\begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt; u = \begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}v &amp;lt;/math&amp;gt; - матрица, в первой строке которой находятся элементы последнего столбца матрицы &amp;lt;math&amp;gt; Q_{1}^{T}&amp;lt;/math&amp;gt;, а во второй - элементы первого столбца матрицы &amp;lt;math&amp;gt; Q_{2}^{T}&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;v = \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix}^T&amp;lt;/math&amp;gt;.&lt;br /&gt;
Следовательно, &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; имеет такие же собственные значения, что и подобная ей матрица &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;D = \begin{bmatrix} L_{1} &amp;amp; 0 \\ 0 &amp;amp; L_{2}\end{bmatrix}&amp;lt;/math&amp;gt; - диагональная матрица, &lt;br /&gt;
&amp;lt;math&amp;gt;\rho = b_{m}&amp;lt;/math&amp;gt; - число, а &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - вектор. &lt;br /&gt;
В дальнейшем предполагаем, не ограничивая общности, что диагональные элементы &amp;lt;math&amp;gt;d_{1}, \ldots, d_{n}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; упорядочены по не возрастанию: &amp;lt;math&amp;gt;d_{n} &amp;lt;= \ldots &amp;lt;=d_{1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для того, чтобы найти собственные значения матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, потребуется вычислить её характеристический многочлен, считая пока матрицу &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденной.&lt;br /&gt;
Тогда получаем&lt;br /&gt;
&amp;lt;math&amp;gt;det(D + \rho uu^{T} - \lambda I) = det((D - \lambda I)(I + \rho (D- \lambda I)^{-1} uu^{T}))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденная, &amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 0&amp;lt;/math&amp;gt; тогда и только тогда, когда &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; - является собственным значением. Можем заметить, что матрица &amp;lt;math&amp;gt;I + \rho (D - \lambda I)^{-1}uu^{T}&amp;lt;/math&amp;gt; получается из единичной путём добавления матрицы ранга 1. Определитель такой матрицы не сложно вычислить.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;Лемма 1.&#039;&#039; Справедливо равенство &amp;lt;math&amp;gt;det(I + xy^{T}) = 1 + y^{T}x&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; - векторы.&lt;br /&gt;
&lt;br /&gt;
Следовательно, получаем&lt;br /&gt;
&amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 1 + \rho u^{T}(D - \lambda I)^{-1}u&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; = 1 + \rho \sum_{i=1, n} \frac{u_{i}^{2}} {d_{i}-\lambda} \equiv f(\lambda)&amp;lt;/math&amp;gt; , &lt;br /&gt;
&lt;br /&gt;
т.е. собственные значения матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; являются корнями так называемого векового уравнения &amp;lt;math&amp;gt;f(\lambda) = 0&amp;lt;/math&amp;gt;. Если все числа &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; различны между собой и все &amp;lt;math&amp;gt;u_{i} &amp;lt;&amp;gt; 0&amp;lt;/math&amp;gt; (случай общего положения), то &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; имеет график типа, который показан на рис.1(где &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\rho &amp;gt; 0&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
[[File:График_функции.PNG|thumb|center|600px|Рис. 1. График функции &amp;lt;math&amp;gt; f(\lambda) = 1 + \frac{0.5}{1 - \lambda} + \frac{0.5}{2 - \lambda} + \frac{0.5}{3 - \lambda} + \frac{0.5}{4 - \lambda}&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
По Рис.1 можно заметить, что прямая &amp;lt;math&amp;gt;y = 1&amp;lt;/math&amp;gt; является горизонтальной асимптотой для данного графика, а прямые &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt; есть вертикальные асимптоты. Так как &amp;lt;math&amp;gt;f^{&#039;}(\lambda) =  \rho \sum_{i=1, n} \frac{u_{i}^{2}} {(d_{i}-\lambda)^{2}}&amp;gt; 0 &amp;lt;/math&amp;gt;, функция возрастает всюду, кроме точек &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt;. Из этого следует, что корни функции разделяются числами &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; и ещё один корень находится справа от точки &amp;lt;math&amp;gt;d_{1}&amp;lt;/math&amp;gt; (на рис. 1 &amp;lt;math&amp;gt;d_{1} = 4&amp;lt;/math&amp;gt;). (При &amp;lt;math&amp;gt;\rho&amp;lt;0&amp;lt;/math&amp;gt; функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; всюду убывает и соответствующий корень будет находиться слева от точки &amp;lt;math&amp;gt;d_{n}&amp;lt;/math&amp;gt;). Для функции &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt;, которая является монотонной и гладкой на каждом из интервалов &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;, можно найти вариант метода Ньютона, который будет быстро и монотонно сходиться к каждому из корней, при условии, что начальная точка взята в &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;. Нам достаточно знать тот факт, что на практике метод сходится к каждому собственному значению за строго ограниченное число шагов. Поскольку вычисление &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;f^{&#039;}(\lambda)&amp;lt;/math&amp;gt; стоит &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов, для вычисления одного собственного значения достаточно &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов, следовательно для вычисления всех &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; собственных значений матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; потребуется &amp;lt;math&amp;gt;O(n^{2})&amp;lt;/math&amp;gt; флопов.&lt;br /&gt;
Для собственных векторов матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; мы легко можем получить явные выражения.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;Лемма 2.&#039;&#039; Если &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - собственное значение матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, то соответствующий вектор равен &amp;lt;math&amp;gt;(D - \alpha I)^{-1}u&amp;lt;/math&amp;gt;. Поскольку матрица &amp;lt;math&amp;gt;D - \alpha I&amp;lt;/math&amp;gt; диагональная, для вычисления такого вектора достаточно &amp;lt;math&amp;gt;O(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;(D + \rho uu^{T})[(D - \alpha I)^{-1}u] = &lt;br /&gt;
&lt;br /&gt;
(D - \alpha I + \alpha I + \rho uu^{T})(D - \alpha I)^{-1}u = &lt;br /&gt;
&lt;br /&gt;
u + \alpha (D - \alpha I)^{-1}u + u[\rho u^{T}(D - \alpha I)^{-1}u]= &amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; = u + \alpha(D - \alpha I)^{-1}u - u = \alpha [(D - \alpha I)^{-1}u]&amp;lt;/math&amp;gt;, &lt;br /&gt;
&lt;br /&gt;
поскольку &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \rho u^{T}(D - \alpha I)^{-1}u + 1 = f(\alpha) = 0 &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;O(n^{2})&amp;lt;/math&amp;gt; флопов. К сожалению, данная формула не обеспечивает нам численной устойчивости, так как для двух очень близких значений &amp;lt;math&amp;gt;\alpha_{i}&amp;lt;/math&amp;gt; может давать неортогональные приближенные собственные векторы &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt;. Учёным потребовалось целое десятилетие для того, чтобы найти устойчивую альтернативу исходному описанию алгоритма. Подробнее детали будут обсуждаться ниже в данном разделе. &lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром последовательной схемы решения будет являться вычисление матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; собственных векторов при помощи умножения матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt;. Эта операция имеет сложность &amp;lt;math&amp;gt;cn^{3}&amp;lt;/math&amp;gt; о чём будет говориться ниже, в разделе [[#Последовательная сложность алгоритма|1.6 Последовательная сложность алгоритма]].&lt;br /&gt;
&lt;br /&gt;
Данной операции предшествует вычисление собственных значений и векторов матрицы &amp;lt;math&amp;gt; D + \rho uu^{T}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Алгоритм &amp;quot;разделяй и властвуй&amp;quot; для вычисления собственных значений и векторов симметричной трехдиагональной матрицы состоит из вызова рекурсивной функции &#039;&#039;proc dc_eig&#039;&#039; &amp;lt;math&amp;gt;(T, Q, \Lambda)&amp;lt;/math&amp;gt;, выполнение которой описывается следующими этапами: &lt;br /&gt;
&lt;br /&gt;
*Подаваемая на вход матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; представляется в виде &amp;lt;math&amp;gt; T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &amp;lt;/math&amp;gt;, представление в таком виде возможно  до тех пор, пока размерность матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; не достгнет 1. &lt;br /&gt;
&lt;br /&gt;
*От матриц &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt; также вызываются соотвтетствующие функции &#039;&#039;proc dc_eig&#039;&#039; &amp;lt;math&amp;gt;(T_{1}, Q_{1}, \Lambda_{1})&amp;lt;/math&amp;gt; и &#039;&#039;proc dc_eig&#039;&#039; &amp;lt;math&amp;gt;(T_{2}, Q_{2}, \Lambda_{2})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
*Вычисляются матрицы &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt; по &amp;lt;math&amp;gt; \Lambda_{1},\Lambda_{2}, Q_{1}, Q_{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
*Вычисление собственных значений&amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; и векторов &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
*Построение матрицы собственных векторов &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;для матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Рассмотри реализацию метода &amp;quot;разделяй и властвуй&amp;quot; в виде алгоритма, состоящего из частного случая, когда матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; имеет размерность &amp;lt;math&amp;gt;1 \times 1&amp;lt;/math&amp;gt; и общего случая, когда матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - симметричная трехдиагональная матрица произвольной размерности, кроме &amp;lt;math&amp;gt;1 \times 1&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;proc dc_eig&#039;&#039; &amp;lt;math&amp;gt;(T, Q, \Lambda) ... &amp;lt;/math&amp;gt; по входной матрице &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются выходные матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;T = Q\Lambda Q^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
     &#039;&#039;if&#039;&#039; матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; имеет размерность &amp;lt;math&amp;gt;1 \times 1&amp;lt;/math&amp;gt;                       (&#039;&#039;проверяем матрицу &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; на принадлежность частному случаю алгоритма&#039;&#039;)&lt;br /&gt;
     &#039;&#039;then&#039;&#039;&lt;br /&gt;
         присвоить выходным параметрам значения &amp;lt;math&amp;gt;Q = 1, \Lambda = T&amp;lt;/math&amp;gt;              (&#039;&#039;если матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;1 \times 1&amp;lt;/math&amp;gt;, то СЗ и СВ матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; найдены&#039;&#039;)&lt;br /&gt;
     &#039;&#039;else&#039;&#039;                                                                                    (&#039;&#039;если матрица &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; имеет общей вид, то:&#039;&#039;)&lt;br /&gt;
         &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; в виде &amp;lt;math&amp;gt; T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &amp;lt;/math&amp;gt;                                                                  (&#039;&#039;разложим матрицу &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;&#039;&#039;)&lt;br /&gt;
         &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{1},Q_{1},\Lambda_{1})&amp;lt;/math&amp;gt;                              (&#039;&#039;вызываем рекурсивно функцию &#039;&#039;dc_eig&#039;&#039;, вычисляющую СЗ и СВ матрицы &amp;lt;math&amp;gt;T_1&amp;lt;/math&amp;gt;&#039;&#039;)&lt;br /&gt;
         &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{2},Q_{2},\Lambda_{2})&amp;lt;/math&amp;gt;                              (&#039;&#039;вызываем рекурсивно функцию &#039;&#039;dc_eig&#039;&#039;, вычисляющую СЗ и СВ матрицы &amp;lt;math&amp;gt;T_2&amp;lt;/math&amp;gt;&#039;&#039;)&lt;br /&gt;
         Построить &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt; по &amp;lt;math&amp;gt; \Lambda_{1},\Lambda_{2}, Q_{1}, Q_{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
         Найти матрицу собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
         Найти матрицу собственных векторов &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
         Построить матрицу собственных векторов &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; : &amp;lt;math&amp;gt; Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; &lt;br /&gt;
Q_{2}\end{bmatrix}* Q^{&#039;} &amp;lt;/math&amp;gt;&lt;br /&gt;
         Присвоить выходным параметрам значения &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
  &#039;&#039;&#039;endif&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;t(n)&amp;lt;/math&amp;gt; - число флопов при обработке матрицы размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt; процедурой &#039;&#039;dc_eig&#039;&#039;. Тогда &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;t(n) = 2t(n/2)&amp;lt;/math&amp;gt; два рекурсивных обращения к &#039;&#039;dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{i},Q_{i},\Lambda_{i})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;math&amp;gt;+O(n^{2})&amp;lt;/math&amp;gt; вычисление собственных значений матрицы &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&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;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;+c*n^{3}&amp;lt;/math&amp;gt; вычисление матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}*Q^{&#039;}&amp;lt;/math&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; Q_{1}, Q_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; рассматриваются как плотные матрицы и используется стандартный алгоритм матричного умножения, то константа &amp;lt;math&amp;gt; c &amp;lt;/math&amp;gt; в последней строке равна 1. Таким образом, именно это умножение составляет наиболее трудоёмкую часть алгоритма в целом. Игнорируя члены порядка &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;, получаем &amp;lt;math&amp;gt;t(n) = 2t(n/2) + cn^{3}&amp;lt;/math&amp;gt;. Решая это разностное уравнение, находим &amp;lt;math&amp;gt; t \approx c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На практике обычно &amp;lt;math&amp;gt;c&amp;lt;&amp;lt;1&amp;lt;/math&amp;gt; ( так как матрица &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; весьма разрежена вследствие дефляциии).&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
В данном разделе представлен информационный граф алгоритма: на рисунке 2 изображена часть алгоритма, в которой происходит деление - &amp;quot;разделяй&amp;quot;, а на рисунке 3 описана часть &amp;quot;властвуй&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Divide.png|thumb|center|left|8000px|Рис. 2 Информационный граф шага &amp;quot;разделяй&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
[[File:Conq.png|thumb|center|left|8000px|Рис. 3 Информационный граф шага &amp;quot;властвуй&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
Операции: &lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; - операция &amp;quot;разделяй&amp;quot; разделения матрицы &amp;lt;math&amp;gt; T &amp;lt;/math&amp;gt; на матрицы &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;C_{n}&amp;lt;/math&amp;gt; - операция &amp;quot;властвуй&amp;quot; сбора матрицы &amp;lt;math&amp;gt; D_{n*n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt; R_{n} &amp;lt;/math&amp;gt; - операция поиска собственных значений матрицы &amp;lt;math&amp;gt; T_{n*n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt; S^{&#039;}_{n} &amp;lt;/math&amp;gt; - операция поиска собственных векторов матрицы &amp;lt;math&amp;gt; D_{n*n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt; S_{n} &amp;lt;/math&amp;gt; - операция поиска собственных векторов матрицы &amp;lt;math&amp;gt; T_{n*n} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Данные:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;Q_{n}&amp;lt;/math&amp;gt; - вектор собственных значений размерности &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;V_{n*n}&amp;lt;/math&amp;gt; - матрица собственных векторов размерности &amp;lt;b&amp;gt;n&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Параллелизм достигается за счёт вызова рекурсивных функций &#039;&#039;dc_eig&#039;&#039;, вычисляющих собственные значения и собственные вектора матриц &amp;lt;math&amp;gt;T_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2&amp;lt;/math&amp;gt;. Рекурсивное разделение матрицы приводит к возможности построения структуры в виде двоичного дерева, в каждой вершине которого происходит вычисение функции &#039;&#039;dc_eig&#039;&#039;. Таким образом высота ярусно-параллельной формы, где вычисления для каждого листа дерева в такой структуре происходят независимо, составляет &amp;lt;math&amp;gt;log_2(n)&amp;lt;/math&amp;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;T&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;&lt;br /&gt;
T = \begin{bmatrix}&lt;br /&gt;
 a_{1} &amp;amp; b_{1}&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp; b_{m} &amp;amp; a_{m+1} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&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;2n-1&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;\alpha_{i}&amp;lt;/math&amp;gt; (всего &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;) и собственные векторы &amp;lt;math&amp;gt;\lambda_{i}&amp;lt;/math&amp;gt; (всего &amp;lt;math&amp;gt;n^2&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;n+n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
1. Один из самых быстрых алгоритмов вычисления вектора собственных значений и собственных векторов, соответствующих собственным значениям, матриц порядка большего, чем 25.&lt;br /&gt;
&lt;br /&gt;
2. Вычислительная мощность алгоритма, как отношение числа операций к суммарному объему входных и выходных данных – линейна.&lt;br /&gt;
 &lt;br /&gt;
3. Алгоритм не гарантирует высокой относительной точности для малых собственных значений.&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&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; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости алгоритм был реализован с использованием библиотеки OpenMP 1.5.5 для языка C++(компилятор g++) на cуперкомпьютере Ломоносов на узле compiler. Максимальное число потоков для данного узла равно 8. Для оценки масштабируемости, программа была запущена в 1, 2, 4, 8 потока. Код исследуемой реализации представлен по [https://github.com/Zero-ger/Tasks следующей ссылке]&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров [1 : 8] (1,2,3,4,8);&lt;br /&gt;
*	размер матрицы [4 : 8192].&lt;br /&gt;
&lt;br /&gt;
Параметры компиляции и запуска: &lt;br /&gt;
&lt;br /&gt;
 ssh compiler &lt;br /&gt;
 module add slurm&lt;br /&gt;
 module add openmpi/1.5.5-icc&lt;br /&gt;
 g++ GetValues.cxx  -fopenmp -std=c++0x -o _scratch/mytask&lt;br /&gt;
 cd _scratch/&lt;br /&gt;
 sbatch -p test -n1 run ./mytask&lt;br /&gt;
&lt;br /&gt;
Для управления количеством потоков использовалась операция OpenMP omp_set_num_threads();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Graph.png|thumb|center|left|800px|Рис. 6. График времени работы программы в зависимости от размера задачи и числа процессов]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Проведем оценки масштабируемости:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;По размеру задачи&#039;&#039;&#039; — при увеличении размерности матрицы общая эффективность программы постепенно уменьшается. Это связано с тем, что время чтения и подготовки исходных данных растёт быстрее, чем время работы исследуемого алгоритма.&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;
&lt;br /&gt;
Метод &amp;quot;Разделяй и властвуй&amp;quot; реализован в пакете LAPACK, описание которого можно найти в данной [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf статье].&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Джеймс Деммель. Вычислительная линейная алгебра. Теория и приложения. изд. 	Мир, 	1/1/2001. — С. 228 - 236.&lt;br /&gt;
&lt;br /&gt;
[2]  [https://en.wikipedia.org/wiki/Divide-and-conquer_eigenvalue_algorithm Divide-and-conquer eigenvalue algorithm]&lt;br /&gt;
&lt;br /&gt;
[3] Gr´egoire Pichon, Azzam Haidar, Mathieu Faverge, Jakub Kurzak. Divide and Conquer Symmetric Tridiagonal Eigensolver&lt;br /&gt;
for Multicore Architectures. 2015. — С. 1 - 11.&lt;br /&gt;
&lt;br /&gt;
[4] C.F. Borges, W.B. Gragg, A parallel divide-and-conquer method for the generalized real symmetric definite tridiagonal&lt;br /&gt;
eigenproblem, in: L. Reichel, A. Ruttan, R.S. Varga (Eds.), Numerical Linear Algebra, Proc. Conf. in Numerical&lt;br /&gt;
Linear Algebra and Scientific Computation, Kent, OH, de Gruyter, Berlin, 1993. — С. 11–29&lt;br /&gt;
&lt;br /&gt;
[5] L. Elsner, A. Fasse, E. Langmann. A divide-and-conquer method for the tridiagonal generalized eigenvalue problem. Journal of Computational and Applied Mathematics. 1997. — С. 141 - 148.&lt;br /&gt;
&lt;br /&gt;
[6] [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf Francoise Tisseury, Jack Dongarra, Parallelizing the Divide and Conquer Algorithm for the Symmetric Tridiagonal Eigenvalue Problem on Distributed Memory Architectures]&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</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:Amirida&amp;diff=21799</id>
		<title>Обсуждение участника:Amirida</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:Amirida&amp;diff=21799"/>
		<updated>2017-01-30T08:51:47Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Статья [[Участник:Amirida/Метод «разделяй и властвуй» вычисления собственных значений и векторов симметричной трехдиагональной матрицы ]] ==&lt;br /&gt;
&lt;br /&gt;
=== Отсутствующие части ===&lt;br /&gt;
* Пропущен раздел описания 2.4. Масштабируемость алгоритма и его реализации. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:25, 9 ноября 2016 (MSK)&lt;br /&gt;
* Не заполнен раздел 2.4 описания. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:28, 16 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Замечания по тексту ===&lt;br /&gt;
* В разделе 1.4 требуется привести описание алгоритма на верхнем уровне (на основе макроопераций). [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:25, 9 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 1.5 кроме кода нужны также текстовые пояснения. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:25, 9 ноября 2016 (MSK)&lt;br /&gt;
* Граф, приведённый в разделе 1.7 не является информационным графом (ациклический граф, вершины - операции, дуги - информационные зависимости). [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:25, 9 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 1.8 используется непонятный термин &amp;quot;высота алгоритма&amp;quot;. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:25, 9 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 1.10 не нужно дублировать последовательную сложность алгоритма, но требуется привести оценку вычислительной мощности. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:25, 9 ноября 2016 (MSK)&lt;br /&gt;
* Отсутствует информация в разделе 2.7 (по текущей нумерации 2.6). [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:25, 9 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Дополнительно (03.12) === &lt;br /&gt;
[[Участник:chernyavskiy]]&lt;br /&gt;
&lt;br /&gt;
*Для ускорение дальнейшей проверки укажите на этой странице (в данном разделе) подробно источники, из которых брались разделы и их части. Если раздел писался самостоятельно - укажите это.&lt;br /&gt;
&lt;br /&gt;
Разделы:&lt;br /&gt;
&lt;br /&gt;
1.1 - Джеймс Деммель. Вычислительная линейная алгебра. стр. 228&lt;br /&gt;
&lt;br /&gt;
1.2 - Джеймс Деммель. Вычислительная линейная алгебра. стр. 228-233&lt;br /&gt;
&lt;br /&gt;
1.3 - Джеймс Деммель. Вычислительная линейная алгебра. стр. 232&lt;br /&gt;
&lt;br /&gt;
1.4 - Джеймс Деммель. Вычислительная линейная алгебра. стр. 232&lt;br /&gt;
&lt;br /&gt;
1.5 - Джеймс Деммель. Вычислительная линейная алгебра. стр. 232&lt;br /&gt;
&lt;br /&gt;
1.6 - Джеймс Деммель. Вычислительная линейная алгебра. стр. 232, https://en.wikipedia.org/wiki/Divide-and-conquer_eigenvalue_algorithm&lt;br /&gt;
&lt;br /&gt;
1.7 - Писали сами&lt;br /&gt;
&lt;br /&gt;
1.8 - Писали сами&lt;br /&gt;
&lt;br /&gt;
1.9 - Писали сами&lt;br /&gt;
&lt;br /&gt;
1.10 - Джеймс Деммель. Вычислительная линейная алгебра&lt;br /&gt;
&lt;br /&gt;
2.4 - Писали сами&lt;br /&gt;
&lt;br /&gt;
2.7 - Писали сами&lt;br /&gt;
&lt;br /&gt;
=== Новые замечания и вопросы ===&lt;br /&gt;
&lt;br /&gt;
Замечания:&lt;br /&gt;
1) Необходимо исправить ошибки в разделе 1.2.&lt;br /&gt;
2) Необходимо изменить информационный граф: не видна связь между шагами &amp;quot;разделяй&amp;quot; и &amp;quot;властвуй&amp;quot;. &lt;br /&gt;
3) В разделе 1.1 написано:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;В наихудшем случае алгоритм «разделяй-и-властвуй» требует &amp;lt;math&amp;gt; O(n^{3})&amp;lt;/math&amp;gt; операций, но константа, на практике оказывается весьма малой. На большой выборке случайных тестовых матриц в среднем затрачивается лишь &amp;lt;math&amp;gt; O(n^{2.3})&amp;lt;/math&amp;gt; операций с плавающей точкой, а для некоторых специальных распределений собственных значений — &amp;lt;math&amp;gt; O(n^{2})&amp;lt;/math&amp;gt; (подробнее в разделе [[1.6 Последовательная сложность алгоритма]]).&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Во-первых, не работает ссылка, а во-вторых, в разделе 1.6. я не вижу обоснования приведенным здесь оценкам.&lt;br /&gt;
&lt;br /&gt;
4) В разделе 1.6. встречается слово &amp;quot;дефляция&amp;quot;. Больше в описании про дефляцию ни слова. Необходимо добавить. И определение, и роль в алгоритме.&lt;br /&gt;
&lt;br /&gt;
Также прошу ответить на несколько вопросов:&lt;br /&gt;
1) Что такое общая &#039;&#039;эффективность программы&#039;&#039;?&lt;br /&gt;
2) Чем &#039;&#039;общая эффективность программы&#039;&#039; отличается от &#039;&#039;эффективности программы&#039;&#039;?&lt;br /&gt;
3) Как алгоритм работает с кратными собственными значениями?&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</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%A0%D0%BE%D0%BC%D0%B0%D0%BD_%D0%97%D0%B5%D0%BC%D0%BB%D1%8F%D0%BD%D1%81%D0%BA%D0%B8%D0%B9/Zavolskov/Zemlyanskiy&amp;diff=20094</id>
		<title>Участник:Роман Землянский/Zavolskov/Zemlyanskiy</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%A0%D0%BE%D0%BC%D0%B0%D0%BD_%D0%97%D0%B5%D0%BC%D0%BB%D1%8F%D0%BD%D1%81%D0%BA%D0%B8%D0%B9/Zavolskov/Zemlyanskiy&amp;diff=20094"/>
		<updated>2016-12-05T12:11:11Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--{{Assignment|IgorS}}--&amp;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;
&#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;
[[#Информационный граф]]&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;
&lt;br /&gt;
[[#Последовательная сложность алгоритма]]&lt;br /&gt;
&lt;br /&gt;
[[#Ресурс параллелизма алгоритма]]&lt;br /&gt;
&lt;br /&gt;
[[#Входные и выходные данные алгоритма]]&lt;br /&gt;
&lt;br /&gt;
[[#Свойства алгоритма]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
614 группа&lt;br /&gt;
&lt;br /&gt;
= ЧАСТЬ. Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
&#039;&#039;&#039;Метод разделяй и властвуй вычисления собственных значений и векторов трёхдиагональной матрицы&#039;&#039;&#039; - это наиболее быстрый из существующих методов, если нужны все собственные значения и собственные векторы трехдиагональной матрицы, начиная с порядка n, примерно равного 26. (Точное значение этого порогового порядка зависит от компьютера.) Его численно устойчивая реализация весьма не тривиальна. В самом деле, хотя впервые метод был предложен еще в 1981 г., &amp;quot;правильный&amp;quot; способ его реализации был найден лишь в 1992 г. Этот способ воплощен LAPACK-программами ssyevd (для плотных матриц) и sstevd (для трехдиагональных матриц). В них стратегия &amp;quot;разделяй-и-влавствуй&amp;quot; используется для матриц порядка, большего чем 25. Для матриц меньшего порядка (или если нужны только собственные значения) происходит автоматический переход к QR-итерации.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Пусть &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
L = \begin{bmatrix}&lt;br /&gt;
 a_{1} &amp;amp; b_{1}&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp; b_{m} &amp;amp; a_{m+1} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
= \begin{bmatrix}&lt;br /&gt;
  a_{1} &amp;amp; b_{1} &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} - b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; a_{m+1} - b_{m} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix} +&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
+ \begin{bmatrix}&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 &amp;amp;&amp;amp;b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&lt;br /&gt;
= \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m} * \begin{bmatrix} 0 \\ \vdots \\ 0 \\ 1 \\ 1 \\ 0 \\ \vdots \\ 0 \end{bmatrix} \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix} &lt;br /&gt;
&lt;br /&gt;
\equiv \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Предположим, что нам известны спектральные разложения матриц &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt; T_{2} &amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt; T_{i} = Q_{i} \Lambda_{i} Q_{i}^{T} &amp;lt;/math&amp;gt;. В действительности, они будут рекурсивно вычисляться тем же самым алгоритмом. Установим связь между собственными значениями матрицы Т и собственными значениями матриц&lt;br /&gt;
&amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;. Имеем:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt; &lt;br /&gt;
T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} \Lambda_{1} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2} \Lambda_{2} Q_{2}^{T}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}(\begin{bmatrix} \Lambda_{1} &amp;amp; \\  &amp;amp; \Lambda_{2}\end{bmatrix} + b_{m}vv^{T})\begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}&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;&lt;br /&gt;
u = \begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}v&lt;br /&gt;
  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
так как &amp;lt;math&amp;gt;v = \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix}^T&amp;lt;/math&amp;gt;, получим матрицу, состоящую из последнего столбца матрицы &amp;lt;math&amp;gt; Q_{1}^{T}&amp;lt;/math&amp;gt; и первого столбца матрицы &amp;lt;math&amp;gt; Q_{2}^{T}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Следовательно, &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; имеет те же собственные значения, что и подобная ей матрица &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;D = \begin{bmatrix} \Lambda_{1} &amp;amp; 0 \\ 0 &amp;amp; \Lambda_{2}\end{bmatrix}&amp;lt;/math&amp;gt; - диагональная матрица, &lt;br /&gt;
&amp;lt;math&amp;gt;\rho = b_{m}&amp;lt;/math&amp;gt; - число, а &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - вектор. &lt;br /&gt;
&lt;br /&gt;
Будем предполагать, не ограничивая общности, что диагональные элементы &amp;lt;math&amp;gt;d_{1}, \ldots, d_{n}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; упорядочены по убыванию: &amp;lt;math&amp;gt;d_{n} &amp;lt;= \ldots &amp;lt;=d_{1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Чтобы найти собственные значения матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, вычислим её характеристический многочлен, считая пока матрицу &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденной.&lt;br /&gt;
Тогда&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;det(D + \rho uu^{T} - \lambda I) = det((D - \lambda I)(I + \rho (D- \lambda I)^{-1} uu^{T}))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Поскольку &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденна, &amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 0&amp;lt;/math&amp;gt; тогда и только тогда, когда &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; - собственное значение. Заметим, что матрица &amp;lt;math&amp;gt;I + \rho (D - \lambda I)^{-1}uu^{T}&amp;lt;/math&amp;gt; получается из единичной добавлением матрицы ранга 1. Определитель такой матрицы легко вычислить.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;&#039;Лемма 1.&#039;&#039;&#039; Справедливо равенство &amp;lt;math&amp;gt;det(I + xy^{T}) = 1 + y^{T}x&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; - векторы.&lt;br /&gt;
&lt;br /&gt;
Таким образом,&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 1 + \rho u^{T}(D - \lambda I)^{-1}u&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; = 1 + \rho \sum_{i=1, n} \frac{u_{i}^{2}} {d_{i}-\lambda} \equiv f(\lambda)&amp;lt;/math&amp;gt; , &lt;br /&gt;
&lt;br /&gt;
т.е. собственные значения матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; есть корни так называемого векового уравнения &amp;lt;math&amp;gt;f(\lambda) = 0&amp;lt;/math&amp;gt;. Если все числа &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; различны и все &amp;lt;math&amp;gt;u_{i} &amp;lt;&amp;gt; 0&amp;lt;/math&amp;gt; (случай общего положения), то &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; имеет график типа показанного на рис.1(где &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\rho &amp;gt; 0&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
[[File:Graphics.PNG|thumb|center|800px|Рис. 1. График функции &amp;lt;math&amp;gt; f(\lambda) = 1 + \frac{0.5}{1 - \lambda} + \frac{0.5}{2 - \lambda} + \frac{0.5}{3 - \lambda} + \frac{0.5}{4 - \lambda}&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Можно видеть, что прямая &amp;lt;math&amp;gt;y = 1&amp;lt;/math&amp;gt; является горизонтальной асимптотой для этого графика, а прямые &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt; есть вертикальные асимптоты. Поскольку &amp;lt;math&amp;gt;f^{&#039;}(\lambda) =  \rho \sum_{i=1, n} \frac{u_{i}^{2}} {(d_{i}-\lambda)^{2}}&amp;gt; 0 &amp;lt;/math&amp;gt;, функция возрастает всюду, кроме точек &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt;. Поэтому корни функции разделяются числами &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; и ещё один корень находится справа от точки &amp;lt;math&amp;gt;d_{1}&amp;lt;/math&amp;gt; (на рис. 1 &amp;lt;math&amp;gt;d_{1} = 4&amp;lt;/math&amp;gt;). (При &amp;lt;math&amp;gt;\rho&amp;lt;0&amp;lt;/math&amp;gt; функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; всюду убывает и соответствующий корень находится слева от точки &amp;lt;math&amp;gt;d_{n}&amp;lt;/math&amp;gt;). Для функции &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt;, монотонной и гладкой на каждом из интервалов &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;, можно найти вариант метода Ньютона, который быстро и монотонно сходится к каждому из корней, если начальная точка взята в &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;. Нам достаточно знать, что на практике метод сходится к каждому собственному значению за ограниченное число шагов. Поскольку вычисление &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;f^{&#039;}(\lambda)&amp;lt;/math&amp;gt; стоит &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов, для вычисления одного собственного значения достаточно &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, а для вычисления всех &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; собственных значений матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; требуется &amp;lt;math&amp;gt;O(n^{2})&amp;lt;/math&amp;gt; флопов.&lt;br /&gt;
Для собственных векторов матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; мы легко можем получить явные выражения.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;&#039;Лемма 2.&#039;&#039;&#039; Если &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - собственное значение матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, то соответствующий вектор равен &amp;lt;math&amp;gt;(D - \alpha I)^{-1}u&amp;lt;/math&amp;gt;. Поскольку матрица &amp;lt;math&amp;gt;D - \alpha I&amp;lt;/math&amp;gt; диагональная, для вычисления такого вектора достаточно &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов.&lt;br /&gt;
&lt;br /&gt;
Доказательство.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;(D + \rho uu^{T})[(D - \alpha I)^{-1}u] = (D - \alpha I + \alpha I + \rho uu^{T})(D - \alpha I)^{-1}u&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=u + \alpha (D - \alpha I)^{-1}u + u[\rho u^{T}(D - \alpha I)^{-1}u] &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=u + \alpha(D - \alpha I)^{-1}u - u&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
                                                       поскольку &amp;lt;math&amp;gt; \rho u^{T}(D - \alpha I)^{-1}u + 1 = f(\alpha) = 0 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;=\alpha [(D - \alpha I)^{-1}u]&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; собственных векторов требуется &amp;lt;math&amp;gt;O(n^{2})&amp;lt;/math&amp;gt; флопов. К сожалению, формула не обеспечивает численной устойчивости, так как для двух очень близких значений &amp;lt;math&amp;gt;\alpha_{i}&amp;lt;/math&amp;gt; может давать неортогональные приближенные собственные векторы &amp;lt;math&amp;gt;u_{i}&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;d_{i}&amp;lt;/math&amp;gt; различны и все &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt; отличны от нуля. Если это не так, вековое уравнение &amp;lt;math&amp;gt;f(\lambda)=0&amp;lt;/math&amp;gt; имеет &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вертикальных асимптот, где &amp;lt;math&amp;gt;k&amp;lt;n&amp;lt;/math&amp;gt;, а потому &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; корней. Однако оказывается, что остальные &amp;lt;math&amp;gt;n - k&amp;lt;/math&amp;gt; собственных значений могут быть определены без каких-либо усилий: если &amp;lt;math&amp;gt;d_{i}=d_{i+1}&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;u_{i}=0&amp;lt;/math&amp;gt;, то легко показать, что &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; является собственным значением и для матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;. В такой ситуации мы говорим о &#039;&#039;дефляции&#039;&#039;. На практике выбирается некоторое пороговое значение и дефляция для числа &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; регистрируется, если в смысле этого порога &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; достаточно близко к &amp;lt;math&amp;gt;d_{i+1}&amp;lt;/math&amp;gt; либо &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&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;u_{i}=0&amp;lt;/math&amp;gt;, то соответствующий собственный вектор есть i-й столбец &amp;lt;math&amp;gt;e_{i}&amp;lt;/math&amp;gt; единичной матрицы. Это означает, что &amp;lt;math&amp;gt;e_{i}&amp;lt;/math&amp;gt; является i-м столбцом в матрице &amp;lt;math&amp;gt;Q_{&#039;}&amp;lt;/math&amp;gt;, поэтому при формировании матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; посредством левого умножения &amp;lt;math&amp;gt;Q_{1}&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;Q_{2}&amp;lt;/math&amp;gt; вычисление i-го столбца не требует никаких затрат. Аналогичное упрощение имеет место в случае &amp;lt;math&amp;gt;d_{i} = d_{i+1}&amp;lt;/math&amp;gt;. При дефляции многих собственных значений устраняется большая часть работы, связанной с матричным умножением.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром последовательной схемы решения является вычисление матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; собственных векторов путём умножения матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; Данная операция имеет сложность &amp;lt;math&amp;gt;cn^{3}&amp;lt;/math&amp;gt; о чём и говорится в разделе [[#Последовательная сложность алгоритма]] .&lt;br /&gt;
Ей предшествует вычисление собственных значений и векторов матрицы &amp;lt;math&amp;gt; D + \rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
Ниже описана структура алгоритма, в которой есть блок умножения матриц для вычисления собственных векторов, являющийся вычислительным ядром алгоритма. В соответствующем разделе ([[#Вычислительное ядро алгоритма]]) мы упоминали о том, что данному блоку предшествует вычисление собственных значений, которое производится [https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%9D%D1%8C%D1%8E%D1%82%D0%BE%D0%BD%D0%B0 методом Ньютона].&lt;br /&gt;
&lt;br /&gt;
[[File:DivideAndConquerTree.png|thumb|center|left|800px|Рис. 2. Дерево алгоритма &amp;quot;Разделяй и властвуй&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
[[File:InfoGraph.jpg|thumb|center|1200px|Рис. 3. Детальное описание одного блока алгоритма]]&lt;br /&gt;
&lt;br /&gt;
=== Решение векового уравнения ===&lt;br /&gt;
Подробно стоит поговорить о решении векового уравнения, которое является одной из основных частей алгоритма.&lt;br /&gt;
&lt;br /&gt;
Предположим, что некоторое &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt;, хотя и мало, все же недостаточно мало для того, чтобы была зарегистрирована дефляция. В этом случае применение метода Ньютона к решению векового уравнения встречается с затруднениями. Вспомним, что пересчет приближённого решения &amp;lt;math&amp;gt;u_{j}&amp;lt;/math&amp;gt; уравнения &amp;lt;math&amp;gt;f(\lambda) = 0&amp;lt;/math&amp;gt; в методе Ньютона основан на следующих положениях:&lt;br /&gt;
&lt;br /&gt;
 1. Вблизи точки &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt; функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; аппроксимируется линейной функцией &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt;; график есть прямая линия, касающаяся графика функции &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 2. В качестве &amp;lt;math&amp;gt;\lambda_{j+1}&amp;lt;/math&amp;gt; берётся нуль этого линейного приближения, т.е. &amp;lt;math&amp;gt;l(\lambda_{j+1})=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Функция, показанная на рис.1, не доставляет видимых трудностей методу Ньютона, поскольку вблизи каждого своего нуля &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; достаточно хорошо аппроксимируется линейными функциями. Однако рассмотрим график функции на рис. 4. Она получена из функции на рис. 1 заменой значения .5 для &amp;lt;math&amp;gt;u_{i}^{2}&amp;lt;/math&amp;gt; на .001. Это новое значение недостаточно мало для того, чтобы вызвать дефляцию. График функции в левой части рис.4 визуально не отличим от её вертикальных и горизонтальных асимптот, поэтому в правой части укрупненно воспроизведён фрагмент графика, прилегающий к вертикальной асимптоте &amp;lt;math&amp;gt;\lambda = 2&amp;lt;/math&amp;gt;. Видно, что график слишком быстро &amp;quot;выполняет поворот&amp;quot; и для большей части значений &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; почти горизонтален. Поэтому, применяя метод Ньютона почти к любому начальному приближению &amp;lt;math&amp;gt;\lambda_{0}&amp;lt;/math&amp;gt;, мы получаем линейное приближение &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt; с почти горизонтальным графиком и малым положительным угловым коэффициентом. В результате &amp;lt;math&amp;gt;\lambda_{1}&amp;lt;/math&amp;gt; является отрицательным числом, огромным по абсолютной величине, которое совершенно бесполезно в качестве приближения к истинному корню.&lt;br /&gt;
&lt;br /&gt;
[[File:GraphNewton.png|thumb|center|800px|Рис. 4. График функции &amp;lt;math&amp;gt; f(\lambda) = 1 + \frac{10^{-3}}{1 - \lambda} + \frac{10^{-3}}{2 - \lambda} + \frac{10^{-3}}{3 - \lambda} + \frac{10^{-3}}{4 - \lambda}&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Чтобы найти выход из этого положения, можно модифицировать метод Ньютона следующим образом: раз &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; нельзя хорошо приблизить линейной функцией &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt;, попробуем взять в качестве приближения какую-нибудь другую простую функцию &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;. Нет ничего особого именно в прямых линиях: для метода Ньютона вместо &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt; можно взять любое приближение &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;, значения и нули которого легко вычисляются. Функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; имеет полюсы в точках &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;d_{i+1}&amp;lt;/math&amp;gt;, которые определяют её поведение в соответствующих окрестностях. Поэтому при поиске корня в интервале &amp;lt;math&amp;gt;(d_{i+1}, d_{i})&amp;lt;/math&amp;gt; естественно выбрать функцию &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;, также имеющую эти полюсы, т.е. функцию вида&lt;br /&gt;
 &amp;lt;math&amp;gt;h(\lambda)= \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} + c_{3}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Константы &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; обеспечивающие, что &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt; есть приближение к &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt;, можно выбрать несколькими способами. Отметим, что если &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; уже известны, то уравнение &amp;lt;math&amp;gt;h(\lambda)=0&amp;lt;/math&amp;gt; легко решается относительно &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt;, поскольку сводится к эквивалентному квадратному уравнению&lt;br /&gt;
 &amp;lt;math&amp;gt;c_{1}(d_{i+1}-\lambda)+c_{2}(d_{i}-\lambda)+c_{3}(d_{i}-\lambda)(d_{i+1}-\lambda)=0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;\lambda_{j}&amp;lt;/math&amp;gt; - приближённое значение корня. определим &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; так, чтобы&lt;br /&gt;
 &amp;lt;math&amp;gt;\frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} + c_{3} = h(\lambda) \approx f(\lambda) = 1 + \rho \sum_{k=1, n} \frac{u_{k}^{2}} {d_{k}-\lambda} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
для &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; в окрестности &amp;lt;math&amp;gt;\lambda_{j}&amp;lt;/math&amp;gt;. Заметим, что&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;f(\lambda) = 1 + \rho \sum_{k=1, i} \frac{u_{k}^{2}} {d_{k}-\lambda} + \rho \sum_{k=i+1, n} \frac{u_{k}^{2}} {d_{k}-\lambda} \equiv 1 + \psi_{1}(\lambda) + \psi_{2}(\lambda)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\lambda \in (d_{i+1},d_{i})&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\psi_{1}(\lambda)&amp;lt;/math&amp;gt; есть сумма положительных слагаемых, а &amp;lt;math&amp;gt;\psi_{2}(\lambda)&amp;lt;/math&amp;gt; - сумма отрицательных. Поэтому и &amp;lt;math&amp;gt;\psi_{1}(\lambda)&amp;lt;/math&amp;gt;, и &amp;lt;math&amp;gt;\psi_{2}(\lambda)&amp;lt;/math&amp;gt; могут быть вычислены с высокой точностью; однако при их сложении вполне вероятно взаимное уничтожение верных разрядов и потеря относительной точности в сумме. Возьмем числа &amp;lt;math&amp;gt;c_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{1}}&amp;lt;/math&amp;gt;, такие, что функция &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h_{1}(\lambda) \equiv \hat{c_{1}} + \frac{c_{1}}{d_{i}-\lambda}&amp;lt;/math&amp;gt;   удовлетворяет условиям  &amp;lt;math&amp;gt;h_{1}(\lambda_{j}) = \psi_{1}(\lambda_{j})&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;h_{1}^{&#039;}(\lambda_{j})=\psi_{1}^{&#039;}(\lambda_{j})&amp;lt;/math&amp;gt; (1)&lt;br /&gt;
&lt;br /&gt;
Это означает, что гипербола, являющаяся графиком функции &amp;lt;math&amp;gt;h_{1}(\lambda)&amp;lt;/math&amp;gt;, касается графика функции &amp;lt;math&amp;gt;\psi_{i}(\lambda)&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt;. Два условия в (1) - это обычные условия метода Ньютона, за исключением того, что вместо прямой в качестве приближения используется гипербола. Легко проверить, что &amp;lt;math&amp;gt;c_{1}=\psi_{1}^{&#039;}(\lambda_{j})(d_{i} - \lambda_{j})^{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{1}}=\psi_{1}(\lambda_{j}) - \psi_{1}^{&#039;}(\lambda_{j})(d_{i} - \lambda_{j})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подобным же образом выбираем &amp;lt;math&amp;gt;c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{2}}&amp;lt;/math&amp;gt; так, чтобы функция &lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h_{2}(\lambda) \equiv \hat{c_{2}} + \frac{c_{2}}{d_{i+1}-\lambda}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Удовлетворяла условиям&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt;h_{2}(\lambda_{j}) = \psi_{2}(\lambda_{j})&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;h_{2}^{&#039;}(\lambda_{j})=\psi_{2}^{&#039;}(\lambda_{j})&amp;lt;/math&amp;gt; (2)&lt;br /&gt;
&lt;br /&gt;
Наконец, полагаем&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;h(\lambda) = 1 + h_{1}(\lambda) + h_{2}(\lambda) = (1 + \hat{c_{1}} + \hat{c_{2}} + \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;math&amp;gt;\equiv c_{3} + \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&#039;&#039;Вычисление собственных значений и собственных векторов симметричной трехдиагональной матрицы посредством стратегии &amp;quot;разделяй и властвуй&amp;quot;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;proc dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T,Q,\Lambda)...&amp;lt;/math&amp;gt; по входной матрице &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются выходные матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;T = Q\Lambda Q^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Если &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - матрица размера &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; x &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  1. Присвоить выходным параметрам значения &amp;lt;math&amp;gt; Q = 1, \Lambda = T&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Иначе&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  1. Представить &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; в виде &amp;lt;math&amp;gt; T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  2. &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{1},Q_{1},\Lambda_{1})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  3. &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{2},Q_{2},\Lambda_{2})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  4. Построить &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt; по &amp;lt;math&amp;gt; \Lambda_{1},\Lambda_{2}, Q_{1}, Q_{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  5. Найти матрицу собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  6. Найти матрицу собственных векторов &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  7. Построить матрицу собственных векторов &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; : &amp;lt;math&amp;gt; Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}* Q^{&#039;} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  8. Присвоить выходным параметрам значения &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;endif&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Проанализируем сложность алгоритма. Пусть &amp;lt;math&amp;gt;t(n)&amp;lt;/math&amp;gt; - число флопов при обработке матрицы размера &amp;lt;math&amp;gt; n x n&amp;lt;/math&amp;gt; процедурой &#039;&#039;dc_eig&#039;&#039;. Тогда &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; t(n) = 2t(n/2) &amp;lt;/math&amp;gt; два рекурсивных обращения к &#039;&#039;dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{i},Q_{i},\Lambda_{i})&amp;lt;/math&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;D+\rho uu^{T}&amp;lt;/math&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;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; +c*n^{3}&amp;lt;/math&amp;gt; вычисление матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}*Q^{&#039;}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; Q_{1}, Q_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; рассматриваются как плотные матрицы и используется стандартный алгоритм матричного умножения, то константа &amp;lt;math&amp;gt; c &amp;lt;/math&amp;gt; в последней строке равна 1. Таким образом, именно это умножение составляет наиболее трудоёмкую часть алгоритма в целом. Игнорируя члены порядка &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;, получаем &amp;lt;math&amp;gt;t(n) = 2t(n/2) + cn^{3}&amp;lt;/math&amp;gt;. Решая это разностное уравнение, находим &amp;lt;math&amp;gt; t \approx c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На практике константа &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; обычно гораздо меньше 1, потому что матрица &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; весьма разрежена вследствие явления, называемого дефляцией.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
В данном разделе представлен информационный граф алгоритма: на рисунке 5 изображена часть алгоритма, в которой происходит деление - &amp;quot;Divide&amp;quot;, а на рисунке 6 описана часть &amp;quot;Conquer&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[File:Infograph1.jpg|thumb|center|left|800px|Рис. 5. Информационный граф алгоритма &amp;quot;Разделяй и властвуй&amp;quot; - шаг &amp;lt;b&amp;gt;Divide&amp;lt;/b&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
[[File:Infograph2.jpg|thumb|center|1200px|Рис. 6. Информационный граф алгоритма &amp;quot;Разделяй и властвуй&amp;quot; - шаг &amp;lt;b&amp;gt;Conquer&amp;lt;/b&amp;gt;. Qk*k - матрица собственных значений размерности &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;. Lk*k - матрица собственных векторов размерности &amp;lt;b&amp;gt;k&amp;lt;/b&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
Операции: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; - операция Divide разделения матрицы &amp;lt;math&amp;gt; T &amp;lt;/math&amp;gt; на матрицы &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Индексы - размерность &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{k}&amp;lt;/math&amp;gt; - операция Conquer сбора матрицы &amp;lt;math&amp;gt; D &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; L_{k} &amp;lt;/math&amp;gt; - операция поиска собственных значений &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; S^{&#039;} &amp;lt;/math&amp;gt; - операция поиска собственных векторов матрицы &amp;lt;math&amp;gt; Q^{&#039;} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; S &amp;lt;/math&amp;gt; - операция поиска собственных векторов матрицы &amp;lt;math&amp;gt; Q &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Рассмотрев информационный граф алгоритма, можно заметить, что в структуре имеется два параллельных блока - вызов рекурсивных функций &#039;&#039;dc_eig&#039;&#039; для вычисления собственных значений и векторов матриц &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&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;dc_eig&#039;&#039; отрабатывают последовательно - сначала со входными параметрами &amp;lt;math&amp;gt;T_{1}, Q_{1}, \Lambda_{1}&amp;lt;/math&amp;gt;, затем - &amp;lt;math&amp;gt;T_{2}, Q_{2}, \Lambda_{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, благодаря параллелизму высота алгоритма параллельного составляет &amp;lt;math&amp;gt;log_{2}(n)&amp;lt;/math&amp;gt;, когда как при последовательной реализации высота алгоритма равна сумме геометрической прогрессии &amp;lt;math&amp;gt;1+2+4+8+...+2^{n-1} = 2^{n} - 1&amp;lt;/math&amp;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;
&amp;lt;math&amp;gt;&lt;br /&gt;
L = \begin{bmatrix}&lt;br /&gt;
 a_{1} &amp;amp; b_{1}&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp; b_{m} &amp;amp; a_{m+1} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&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;2n + 1&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; n &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;
&lt;br /&gt;
&amp;lt;math&amp;gt; n + n^{2} = n(n + 1) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Описанный в данной статье алгоритм является самым быстрым алгоритмом, среди существующих: QR / Бисекция и обратная итерация / Разделяй и властвуй.&lt;br /&gt;
&lt;br /&gt;
Последовательная сложность алгоритма: &amp;lt;math&amp;gt; t = c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Параллельная сложность алгоритма (в силу использования дефляции): &amp;lt;math&amp;gt; O(n^{2.3})&amp;lt;/math&amp;gt;  или в самых редких случаях &amp;lt;math&amp;gt; O(n^{2}) &amp;lt;/math&amp;gt; (см. [3] стр. 8).&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;
= ЧАСТЬ. Программная реализация алгоритма =&lt;br /&gt;
Вторая часть описания алгоритмов в рамках AlgoWiki рассматривает все составные части процесса их реализации. Рассматривается как последовательная реализация алгоритма, так и параллельная. Описывается взаимосвязь свойств программ, реализующих алгоритм, и особенностей архитектуры компьютера, на которой они выполняются. Исследуется работа с памятью, локальность данных и вычислений, описывается масштабируемость и эффективность параллельных программ, производительность компьютеров, достигаемая на данной программе. Обсуждаются особенности реализации для разных классов архитектур компьютеров, приводятся ссылки на реализации в существующих библиотеках.&lt;br /&gt;
&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;
*	число процессоров [1 : 8] (1,2,3,4,8);&lt;br /&gt;
*	размер матрицы [4 : 8192].&lt;br /&gt;
&lt;br /&gt;
Для исследования масштабируемости алгоритм был реализован на библиотеке OpenMP 1.5.5 для языка C++(компилятор g++) на cуперкомпьютере Ломоносов на узле compiler. Для данного узла максимально возможное число потоков - 8. В ходе оценки масштабируемости, программа была запущена в 1, 2, 4, 8 потока. &lt;br /&gt;
Параметры компиляции и запуска: &lt;br /&gt;
&lt;br /&gt;
 ssh compiler &lt;br /&gt;
 module add slurm&lt;br /&gt;
 module add openmpi/1.5.5-icc&lt;br /&gt;
 g++ _scratch/test.c++ -fopenmp -std=c++0x -o test &lt;br /&gt;
 sbatch -p test -n1 run ./test&lt;br /&gt;
&lt;br /&gt;
Для управления количеством потоков использовалась операция OpenMP omp_set_num_threads();&lt;br /&gt;
&lt;br /&gt;
[[File:ResultsDiagram.jpg|thumb|center|left|800px|Рис. 7. График времени работы программы в зависимости от числа процессов и размера задачи]]&lt;br /&gt;
&lt;br /&gt;
Масштабируемость рассматриваемой реализации алгоритма &#039;&#039;&#039;&amp;quot;Разделяй и властвуй&amp;quot;&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* При увеличении числа процессов общая эффективность программы увеличивается, т.к. время чтения и подготовки исходной матрицы остаётся неизменным, а время работы алгоритма уменьшается, однако рост незначительный.&lt;br /&gt;
* При увеличении размерности матрицы общая эффективность программы постепенно уменьшается, т.к. время чтения и подготовки исходных данных растёт быстрее, чем время работы исследуемого алгоритма.&lt;br /&gt;
* При одновременном увеличении как числа процессов, так и размерности матрицы общая эффективность программы уменьшается.&lt;br /&gt;
&lt;br /&gt;
Код исследуемой реализации представлен здесь [http://pastebin.com/QpfYZGkK pastebin.com]&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Описываемый метод реализован в пакете LAPACK, описание которого можно найти в [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf этой статье] на страницах 7, 19 и 20, которая указана в списке литературы.&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Дж. Деммель, «Вычислительная линейная алгебра» //С. 230-235&lt;br /&gt;
&lt;br /&gt;
[2] [http://www.netlib.org/utk/people/JackDongarra/PAPERS/104_1999_a-parallel-divide-and-conquer-algorithm.pdf Francoise Tisseury, Jack Dongarra, A Parallel Divide and Conquer Algorithm for the Symmetric Eigenvalue Problem on Distributed Memory Architectures]&lt;br /&gt;
&lt;br /&gt;
[3] [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf Francoise Tisseury, Jack Dongarra, Parallelizing the Divide and Conquer Algorithm for the Symmetric Tridiagonal Eigenvalue Problem on Distributed Memory Architectures]&lt;br /&gt;
&lt;br /&gt;
[4] [https://en.wikipedia.org/wiki/Divide-and-conquer_eigenvalue_algorithm Алгоритм &amp;quot;Разделяй и властвуй&amp;quot; - Wikipedia]&lt;br /&gt;
&lt;br /&gt;
[5] [http://www.cscamm.umd.edu/tadmor/pub/linear-stability/Gill_Tadmor_SISC90.pdf Doron Grill and Eitan Tadmor AN &amp;lt;math&amp;gt;O(N2)&amp;lt;/math&amp;gt; METHOD FOR COMPUTING THE EIGENSYSTEM OF &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;x&amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; SYMMETRIC TRIDIAGONAL MATRICES BY THE DIVIDE AND CONQUER APPROACH]&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</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%A0%D0%BE%D0%BC%D0%B0%D0%BD_%D0%97%D0%B5%D0%BC%D0%BB%D1%8F%D0%BD%D1%81%D0%BA%D0%B8%D0%B9&amp;diff=20038</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%A0%D0%BE%D0%BC%D0%B0%D0%BD_%D0%97%D0%B5%D0%BC%D0%BB%D1%8F%D0%BD%D1%81%D0%BA%D0%B8%D0%B9&amp;diff=20038"/>
		<updated>2016-12-05T07:58:16Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: /* Второй этап проверки */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Замечания к статье ==&lt;br /&gt;
&lt;br /&gt;
* п. 1.1 &amp;quot;...собственные векторы трехдиагональной матриц,&amp;quot; заменить на &amp;quot;...собственные векторы трехдиагональной матрицы,&amp;quot;--[[Участник:IgorS|IgorS]] ([[Обсуждение участника:IgorS|обсуждение]]) 14:48, 26 октября 2016 (MSK)&lt;br /&gt;
* п. 1.7 приведенный рисунок не является рисунком информационного графа--[[Участник:IgorS|IgorS]] ([[Обсуждение участника:IgorS|обсуждение]]) 14:48, 26 октября 2016 (MSK)&lt;br /&gt;
* п. 1.8, 1.9 оценка не произведена--[[Участник:IgorS|IgorS]] ([[Обсуждение участника:IgorS|обсуждение]]) 14:48, 26 октября 2016 (MSK)&lt;br /&gt;
* п. 2.4 не заполнен--[[Участник:IgorS|IgorS]] ([[Обсуждение участника:IgorS|обсуждение]]) 13:26, 16 ноября 2016 (MSK)&lt;br /&gt;
** в п.п. 2.4 следует добавить код исследуемой программы, а также подробное описание условий, в которых производились эксперименты: характеристики программно-аппаратной платформы (какой компилятор, с какими опциями использовался, какие версии библиотек, на каких узлах проводился запуск и т.д.)--[[Участник:IgorS|IgorS]] ([[Обсуждение участника:IgorS|обсуждение]]) 12:16, 21 ноября 2016 (MSK)  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Второй этап проверки ==&lt;br /&gt;
&lt;br /&gt;
=== Итерация 1 ===&lt;br /&gt;
&lt;br /&gt;
Начальные замечания и комментарии (возможно будут появляться новые, пишите, пожалуйста, комментарии по ходу исправлений и ответы):&lt;br /&gt;
&lt;br /&gt;
* Исправить ошибки в формулах в разделе 1.2&lt;br /&gt;
* Исправить ошибку в разделе 1.9&lt;br /&gt;
* Раздел 2.7 - как это не найдены реализации, если в пункте 1.1 они указаны?&lt;br /&gt;
* По информационному графу не видно, что дерево может быть большей высоты, нужно бы это как-то отразить. И не совсем очевидно, как Divide переходит в Conquer. Нужно постараться, чтобы граф был более информативен и без чтения остальных разделов.&lt;br /&gt;
&lt;br /&gt;
=== Итерация 2 ===&lt;br /&gt;
&lt;br /&gt;
ПИШИТЕ В КОММЕНТАРИЯХ ЗДЕСЬ ХОД ИСПРАВЛЕНИЙ И ОТВЕТЫ! Так легче своевременно отслеживать изменения.&lt;br /&gt;
&lt;br /&gt;
* В разделе 1.2 есть как минимум еще одна ошибка.&lt;br /&gt;
* Какое всё-таки отношение имеет вековое уравнени к макроструктуре алгоритма?&lt;br /&gt;
* В пункте 1.10 написано про сложность O(n^{2/3}) просто со ссылкой. Этого недостаточно. Подумайте, как написать. Можно что-то вроде &amp;quot;теоретическая сложность такая-то, на практике же получается так-то и происходит в силу того-то...&amp;quot;&lt;br /&gt;
* Информационный граф пока еще требует доработки. Прочтите ещё раз внимательно его описание на соответствующей странице. Основная его задача - показать взаимосвязь между опреациями алгоритма. Согласен, что в данном случае не нужно опускаться на уровень элементов матриц. Но пока граф не очень хорошо отражает структуру. И более конкретные вещи:&lt;br /&gt;
1) В операции divivde разве матрицы половинной размерности возникают не из предыдущего шага? И где собственно вычисления?&lt;br /&gt;
2) Связь между divide и conquer вообще не видна.&lt;br /&gt;
Древовидная структура - это правильно. Но, снова повтрою, весь граф должен полностью отражать схему вычислений.&lt;br /&gt;
Можно еще для дополнительной наглядности раскрыть полностью рекурсию для конкретного небольшого примера (например, 4Х4) и отразить полностью все происходящие вычисления.&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</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:Nikita&amp;diff=20037</id>
		<title>Обсуждение участника:Nikita</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:Nikita&amp;diff=20037"/>
		<updated>2016-12-05T07:42:11Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению:&lt;br /&gt;
&lt;br /&gt;
1. Пункт 1.7 что обозначают серые вершины на графе?&lt;br /&gt;
&lt;br /&gt;
2. в пункте 1.9 указать чему соответствуют разные входные и выходные данные. Иначе непонятно будет человеку, который первый раз на сайте.&lt;br /&gt;
&lt;br /&gt;
3. Ссылки на литературу внутри текста статьи не нашел.&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;
1. Думаю, описание метода Пейли разумнее переместить в раздел &amp;quot;Математическое описание&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2. В математическом описании желательно хотя бы минимально кратко обосновать корректность (что достаточно проверить (p-1)/2 квадратов, и что матрица будет состоять только из элементов +1 и -1). &lt;br /&gt;
&lt;br /&gt;
3. Исправить код. Есть как опечатки, так и ошибки. Вообще говоря, для любой похожей математической задачи необходимо писать тесты. Здесь он очевиден - проверить получившуюся матрицу по определению. В Algowiki тест вставлять не нужно, приведите его здесь.&lt;br /&gt;
&lt;br /&gt;
4. Информационный граф неправилен. У вас, скорее, отражена макроструктура. Алгоритм довольно прост, поэтому необходимо построить граф по всем правилам, где выход операции переходит строго на вход следующей операции. Разумно будет взять конкретный пример n=4. Лучше построить граф, как с данными, так и без них. Представленный граф тоже можно будет оставить для наглядности. Его основная проблема в том, что не видно, как функция построения итоговой матрицы обращается к элементам residual, что может быть важным для каких-либо архитектур.&lt;br /&gt;
&lt;br /&gt;
5. (22.11) с учетом ошибки и в параллельном коде, эксперимент в пункте 2.4. нужно провести заново.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исправления по второму этапу:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
На данный момент были исправлены все замечания, кроме пункта 4. Скажите, пожалуйста, будут ли применяться штрафы в период правки замечаний?&lt;br /&gt;
&#039;&#039;Ответ:&#039;&#039; нет, если, как в вашем случае, происходит просто исправление, штрафов не будет. Но лучше всё же не тянуть, т.к. могут возникнуть новые комментарии.&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</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:Amirida&amp;diff=19968</id>
		<title>Обсуждение участника:Amirida</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:Amirida&amp;diff=19968"/>
		<updated>2016-12-03T10:19:24Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Статья [[Участник:Amirida/Метод «разделяй и властвуй» вычисления собственных значений и векторов симметричной трехдиагональной матрицы ]] ==&lt;br /&gt;
&lt;br /&gt;
=== Отсутствующие части ===&lt;br /&gt;
* Пропущен раздел описания 2.4. Масштабируемость алгоритма и его реализации. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:25, 9 ноября 2016 (MSK)&lt;br /&gt;
* Не заполнен раздел 2.4 описания. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 15:28, 16 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
=== Замечания по тексту ===&lt;br /&gt;
* В разделе 1.4 требуется привести описание алгоритма на верхнем уровне (на основе макроопераций). [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:25, 9 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 1.5 кроме кода нужны также текстовые пояснения. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:25, 9 ноября 2016 (MSK)&lt;br /&gt;
* Граф, приведённый в разделе 1.7 не является информационным графом (ациклический граф, вершины - операции, дуги - информационные зависимости). [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:25, 9 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 1.8 используется непонятный термин &amp;quot;высота алгоритма&amp;quot;. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:25, 9 ноября 2016 (MSK)&lt;br /&gt;
* В разделе 1.10 не нужно дублировать последовательную сложность алгоритма, но требуется привести оценку вычислительной мощности. [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:25, 9 ноября 2016 (MSK)&lt;br /&gt;
* Отсутствует информация в разделе 2.7 (по текущей нумерации 2.6). [[Участник:ASA|Александр Сергеевич Антонов]] ([[Обсуждение участника:ASA|обсуждение]]) 11:25, 9 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Дополнительно (03.12) === &lt;br /&gt;
[[Участник:chernyavskiy]]&lt;br /&gt;
&lt;br /&gt;
*Для ускорение дальнейшей проверки укажите на этой странице (в данном разделе) подробно источники, из которых брались разделы и их части. Если раздел писался самостоятельно - укажите это.&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</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:Nikita&amp;diff=18953</id>
		<title>Обсуждение участника:Nikita</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:Nikita&amp;diff=18953"/>
		<updated>2016-11-22T13:04:36Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению:&lt;br /&gt;
&lt;br /&gt;
1. Пункт 1.7 что обозначают серые вершины на графе?&lt;br /&gt;
&lt;br /&gt;
2. в пункте 1.9 указать чему соответствуют разные входные и выходные данные. Иначе непонятно будет человеку, который первый раз на сайте.&lt;br /&gt;
&lt;br /&gt;
3. Ссылки на литературу внутри текста статьи не нашел.&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;
1. Думаю, описание метода Пейли разумнее переместить в раздел &amp;quot;Математическое описание&amp;quot;&lt;br /&gt;
&lt;br /&gt;
2. В математическом описании желательно хотя бы минимально кратко обосновать корректность (что достаточно проверить (p-1)/2 квадратов, и что матрица будет состоять только из элементов +1 и -1). &lt;br /&gt;
&lt;br /&gt;
3. Исправить код. Есть как опечатки, так и ошибки. Вообще говоря, для любой похожей математической задачи необходимо писать тесты. Здесь он очевиден - проверить получившуюся матрицу по определению. В Algowiki тест вставлять не нужно, приведите его здесь.&lt;br /&gt;
&lt;br /&gt;
4. Информационный граф неправилен. У вас, скорее, отражена макроструктура. Алгоритм довольно прост, поэтому необходимо построить граф по всем правилам, где выход операции переходит строго на вход следующей операции. Разумно будет взять конкретный пример n=4. Лучше построить граф, как с данными, так и без них. Представленный граф тоже можно будет оставить для наглядности. Его основная проблема в том, что не видно, как функция построения итоговой матрицы обращается к элементам residual, что может быть важным для каких-либо архитектур.&lt;br /&gt;
&lt;br /&gt;
5. (22.11) с учетом ошибки и в параллельном коде, эксперимент в пункте 2.4. нужно провести заново.&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</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:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=18891</id>
		<title>Участник:Nikita/Построение матрицы Адамара</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:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=18891"/>
		<updated>2016-11-21T21:09:45Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--{{Assignment|Sleo}}&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы статьи: [[Участник:Nikita|Иванов Н.В.]] (1.1,1.7,1.9,1.10,2.4,2.7), [[Участник:Tsyganov Nikita|Цыганов Н.И.]] (1.2,1.3,1.4,1.5,1.6,1.7,1.8,2.4).&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;rt&amp;quot;&amp;gt;http://cyberleninka.ru/article/n/matritsy-adamara-nechetnogo-poryadka.pdf&amp;lt;/ref&amp;gt; Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). &amp;lt;ref name=&amp;quot;rt2&amp;quot;&amp;gt;Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&amp;lt;/ref&amp;gt; Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&amp;lt;ref name=&amp;quot;rt3&amp;quot;&amp;gt;http://tc.nsu.ru/uploads/codingtheory.pdf&amp;lt;/ref&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;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-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;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&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;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
	// 1) Считаем вычеты по модулю p=n-1 и создаем вспомогательный массив вычетов residues&lt;br /&gt;
	// Достаточно посчитать значения (1^2 mod p), (2^2 mod p), ... , (((p-1)/2)^2 mod p) - эти значениями и будут являться вычетами.&lt;br /&gt;
	// Строим массив residues размера 2*p, в котором первые p элементов заполняются по следующей схеме: 1, если индекс элемента - вычет, -1 - иначе.&lt;br /&gt;
	// Вторая половина массива получается дублированием первой половины&lt;br /&gt;
	int p=n-1;&lt;br /&gt;
	vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
	residues.resize(2*p);&lt;br /&gt;
	// Заполняем массив&lt;br /&gt;
	for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
		residue[i] = -1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
		residue[i^2 % p] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
		residue[i] = residue[i-p];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// 2) Построение матрицы Адамара&lt;br /&gt;
	// Заполнение первой строки 1-цами&lt;br /&gt;
	for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
		result[0][j] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение первого столбца 1-цами&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		result[i][0] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение оставшейся части матрицы с использованием вспомогательного массива вычетов residues&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
			result[i][j] = residues[j-i+p];&lt;br /&gt;
		}&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;
Под сложностью будем понимать зависимость числа операций от задаваемого порядка матрицы &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;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&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;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph2.png]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания, каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&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;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; участков, состоящих из трёх операций: умножения, взятия остатка и присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из этого можно сделать вывод, что высота ярусно-параллельной формы информационного графа равняется 6 (присваивание, умножение, взятие остатка, присваивание, присваивание, присваивание). Ширина ярусно-параллельной формы равняется &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;, что означает, что при использовании &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; процессоров матрица Адамара будет строиться за 6 операций.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - порядок матрицы Адамара &amp;lt;math&amp;gt;H_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;n&amp;lt;/math&amp;gt; - натуральное;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое.&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &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;H_n&amp;lt;/math&amp;gt; (её элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара размера &amp;lt;math&amp;gt;n*n&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;O(1)&amp;lt;/math&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
Алгоритм является полностью детерминированным. &lt;br /&gt;
&lt;br /&gt;
Для вершин &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt; информационного графа степени исхода являются линейными, что означает, что при возможности на этапе реализации необходимо позаботиться об эффективном доступе к элементам массива &amp;quot;&amp;lt;math&amp;gt;residues&amp;lt;/math&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма построения матрицы Адамара проводилось на суперкомпьютере «Ломоносов». Для этого была исследована собственная реализация алгоритма с использованием средств MPI. В ходе исследования  было произведено множество запусков программы с различными значениями параметра &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (размер матрицы Адамара) и числом процессоров.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма:&lt;br /&gt;
*число процессоров (p): [2,64] с шагом 2;&lt;br /&gt;
*размер матрицы: простые числа в диапазоне [4,10000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон эффективности реализации алгоритма:&lt;br /&gt;
*минимальная эффективность реализации 0.0000029% при n=4, p=2;&lt;br /&gt;
*максимальная эффективность реализации 0.323409% при n=908, p=2.&lt;br /&gt;
&lt;br /&gt;
Ниже представлены графики времени работы, производительности и эффективности данной реализации алгоритма построения матрицы Адамара в зависимости от изменяемых параметров запуска.&lt;br /&gt;
[[Файл:time_graph.png|500px|thumb|center|Время работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:perform_graph.png|500px|thumb|center|Изменение производительности параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:efficiency_graph.png|500px|thumb|center|Эффективность работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/snikersman/Hadamard Исследованная параллельная реализация на языке 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;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм построения матрицы Адамара реализован в различных математических пакетах и библиотеках: &lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</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:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=18890</id>
		<title>Участник:Nikita/Построение матрицы Адамара</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:Nikita/%D0%9F%D0%BE%D1%81%D1%82%D1%80%D0%BE%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%90%D0%B4%D0%B0%D0%BC%D0%B0%D1%80%D0%B0&amp;diff=18890"/>
		<updated>2016-11-21T21:04:53Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
{{Assignment|Sleo}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Построение матрицы Адамара&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Авторы статьи: [[Участник:Nikita|Иванов Н.В.]] (1.1,1.7,1.9,1.10,2.4,2.7), [[Участник:Tsyganov Nikita|Цыганов Н.И.]] (1.2,1.3,1.4,1.5,1.6,1.7,1.8,2.4).&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;rt&amp;quot;&amp;gt;http://cyberleninka.ru/article/n/matritsy-adamara-nechetnogo-poryadka.pdf&amp;lt;/ref&amp;gt; Сравнительно недавно (в 1960 г.) было замечено, что эти матрицы могут быть использованы для построения кодов с большим кодовым расстоянием.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Матрицей Адамара порядка n&#039;&#039;&#039;&#039;&#039; называется &amp;lt;math&amp;gt;n*n&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;, элементами которой являются +1 и −1 такая, что &amp;lt;math&amp;gt;H H^T = n E_n&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;E_n&amp;lt;/math&amp;gt; - единичная матрица размера n.&lt;br /&gt;
&lt;br /&gt;
Матрица Адамара обладает следующими &#039;&#039;свойствами&#039;&#039;:&lt;br /&gt;
* Различные строки матрицы ортогональны&lt;br /&gt;
* Скалярное произведение любой строки саму на себя равно n&lt;br /&gt;
* Умножение любой строки или столбца на -1 переводит H в другую матрицу Адамара&lt;br /&gt;
* Если все элементы первой строки и первого столбца равны +1, то матрица Адамара называется нормализованной&lt;br /&gt;
&lt;br /&gt;
Ниже показаны примеры нормализованных матриц Адамара порядка 1,2 и 4, причем нормализованность матриц сохраняется при перестановке любых строк и столбцов, кроме первых:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;H_1 = (1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_2 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1 &amp;amp; -1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&amp;lt;math&amp;gt;,&lt;br /&gt;
H_4 =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; 1 &amp;amp; 1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; 1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; 1 &amp;amp; -1 &amp;amp; -1\\&lt;br /&gt;
1 &amp;amp; -1 &amp;amp; -1 &amp;amp; 1\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Предполагается, что существуют матрицы Адамара порядка 1, 2 и всех порядков n, кратных 4, хотя это до сих пор еще не было доказано. Нет универсального алгоритма построения матрицы Адамара произвольного размера, но известно большое число методов для различных частных случаев, и наименьший порядок, для которого матрица Адамара еще не построена, равен 268 (на 1977 г.). &amp;lt;ref name=&amp;quot;rt2&amp;quot;&amp;gt;Мак-Вильямс Ф. Дж., Слоэн Н. Дж. А. Теория кодов, исправляющих ошибки: Пер. с англ. — М: Связь, 1979. — c. 52-57&amp;lt;/ref&amp;gt; Мы приведем метод построения Пейли, который важен для теории кодирования. &lt;br /&gt;
&lt;br /&gt;
====Метод Пейли====&lt;br /&gt;
Это построение дает матрицы Адамара любого порядка &amp;lt;math&amp;gt;n=p+1&amp;lt;/math&amp;gt;, кратного 4, где p-простое число.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Определение.&#039;&#039;&#039; Пусть p-простое число. Ненулевые квадраты чисел, приведенные по модулю p, называются квадратичными вычетами по модулю p или просто вычетами по модулю p.&lt;br /&gt;
&lt;br /&gt;
Функция &amp;lt;math&amp;gt;X(i)&amp;lt;/math&amp;gt;, называемая символом Лежандра, определяется на целых числах следующим образом:&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=0&amp;lt;/math&amp;gt;, если i кратно p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=1&amp;lt;/math&amp;gt;, если остаток от деления i на p является квадратным вычетом по модулю p;&lt;br /&gt;
* &amp;lt;math&amp;gt;X(i)=-1&amp;lt;/math&amp;gt;, если остаток от деления i на p является невычетом.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Теперь мы построим матрицу Джекобстола &amp;lt;math&amp;gt;Q=(q_{ij})&amp;lt;/math&amp;gt;. Она представляет собой &amp;lt;math&amp;gt;(p*p)&amp;lt;/math&amp;gt;-матрицу, строки и столбцы которой пронумерованы числами 0,1,..., p-1, а элементы &amp;lt;math&amp;gt;q_{ij}=X(j-i)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Пусть теперь &amp;lt;math&amp;gt;&lt;br /&gt;
H =&lt;br /&gt;
\begin{pmatrix}&lt;br /&gt;
1 &amp;amp;  1\\&lt;br /&gt;
1^T &amp;amp; Q-I\end{pmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Доказано, что такая матрица &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; представляет собой нормализованную матрицу Адамара порядка p+1, которую называют матрицей типа Пейли.&amp;lt;ref name=&amp;quot;rt3&amp;quot;&amp;gt;http://tc.nsu.ru/uploads/codingtheory.pdf&amp;lt;/ref&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;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число.&lt;br /&gt;
&lt;br /&gt;
Вспомогательные данные: &lt;br /&gt;
&lt;br /&gt;
* Число &amp;lt;math&amp;gt;p=n-1&amp;lt;/math&amp;gt;;&lt;br /&gt;
* Вектор квадратичных вычетов (по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;) &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;r_i&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;2p&amp;lt;/math&amp;gt;. В этом векторе индексация идёт с нуля.&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные:&lt;br /&gt;
&lt;br /&gt;
* Матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;) размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;. Индексация строчек и столбцов идёт с нуля. &lt;br /&gt;
&lt;br /&gt;
Алгоритм:&lt;br /&gt;
:1. Строится вектор квадратичных вычетов &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt;.&lt;br /&gt;
:: Первые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов вектора &amp;lt;math&amp;gt;R&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;) определяются следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=1&amp;lt;/math&amp;gt;, если &amp;lt;math&amp;gt;i \in \{1^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, 2^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt;p, ... , (\frac{p-1}{2})^2&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; mod&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; p\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;i=0,1,...,p-1&amp;lt;/math&amp;gt;, то есть если &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; является квадратичным вычетом по модулю &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;;&lt;br /&gt;
::: &amp;lt;math&amp;gt;r_i=-1&amp;lt;/math&amp;gt;, иначе.&lt;br /&gt;
::Вторые &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;i=p,1,...,2p-1&amp;lt;/math&amp;gt;) являются копией первых &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; элементов:&lt;br /&gt;
:::&amp;lt;math&amp;gt;r_i=r_{i-p}, i=p,1,...,2p-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
:2. Строится матрица Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt;.&lt;br /&gt;
::Элементы матрицы Адамара &amp;lt;math&amp;gt;H&amp;lt;/math&amp;gt; находятся следующим образом:&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{0j}=1, j=0,1, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{i0}=1, i=1,2, ... ,n-1;&amp;lt;/math&amp;gt;&lt;br /&gt;
::: &amp;lt;math&amp;gt;h_{ij}=r_{j-i+p}, i=1,2, ... ,n-1, j=1,2, ... ,n-1.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Вычислительное ядро алгоритма состоит из &amp;lt;math&amp;gt;(n-1) \times (n-1)&amp;lt;/math&amp;gt; операций присваивания следующего вида:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;h_{ij}=r_{j-i+p},&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; i=1,2, ... ,n-1, j=1,2, ... ,n-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;
Приведем процедуру на языке С++, реализующую описанный алгоритм. На вход процедуре подается порядок матрицы &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; и ссылка на заполняемую матрицу &amp;lt;math&amp;gt;result&amp;lt;/math&amp;gt;. Считаем, что &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; положительно, делится на &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое число, а размер матрицы &amp;lt;math&amp;gt;result&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;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void buildHadamardMatrix(int n, vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt; &amp;amp; result)&lt;br /&gt;
{&lt;br /&gt;
	// 1) Считаем вычеты по модулю p=n-1 и создаем вспомогательный массив вычетов residues&lt;br /&gt;
	// Достаточно посчитать значения (1^2 mod p), (2^2 mod p), ... , (((p-1)/2)^2 mod p) - эти значениями и будут являться вычетами.&lt;br /&gt;
	// Строим массив residues размера 2*p, в котором первые p элементов заполняются по следующей схеме: 1, если индекс элемента - вычет, -1 - иначе.&lt;br /&gt;
	// Вторая половина массива получается дублированием первой половины&lt;br /&gt;
	int p=n-1;&lt;br /&gt;
	vector&amp;lt;int&amp;gt; residues;&lt;br /&gt;
	residues.resize(2*p);&lt;br /&gt;
	// Заполняем массив&lt;br /&gt;
	for (int i=0; i&amp;lt;p; i++) {&lt;br /&gt;
		residue[i] = -1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=1; i&amp;lt;= (p-1)/2; i++) {&lt;br /&gt;
		residue[i^2 % p] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	for (int i=p; i&amp;lt;2*p; i++) {&lt;br /&gt;
		residue[i] = residue[i-p];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// 2) Построение матрицы Адамара&lt;br /&gt;
	// Заполнение первой строки 1-цами&lt;br /&gt;
	for (int j=0; j&amp;lt;n; j++) {&lt;br /&gt;
		result[0][j] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение первого столбца 1-цами&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		result[i][0] = 1;&lt;br /&gt;
	}&lt;br /&gt;
	// Заполнение оставшейся части матрицы с использованием вспомогательного массива вычетов residues&lt;br /&gt;
	for (int i=1; i&amp;lt;n; i++) {&lt;br /&gt;
		for (int j=1; j&amp;lt;n; j++) {&lt;br /&gt;
			result[i][j] = residues[j-i+p];&lt;br /&gt;
		}&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;
Под сложностью будем понимать зависимость числа операций от задаваемого порядка матрицы &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;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций умножения;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-2&amp;lt;/math&amp;gt; операций взятия остатка;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2+\frac{5}{2}n-3&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;n-1&amp;lt;/math&amp;gt; параллельных ветвей, второй блок - &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; параллельных ветвей, третий - &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; и четвёртый - &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:i_graph2.png]]&lt;br /&gt;
&lt;br /&gt;
Каждая вершина из &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;D_1-D_{n^2}&amp;lt;/math&amp;gt; соответствует операции присваивания, каждая вершина из &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&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;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;\frac{n}{2}-1&amp;lt;/math&amp;gt; участков, состоящих из трёх операций: умножения, взятия остатка и присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; операций присваивания;&lt;br /&gt;
* &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; операций присваивания.&lt;br /&gt;
&lt;br /&gt;
Из этого можно сделать вывод, что высота ярусно-параллельной формы информационного графа равняется 6 (присваивание, умножение, взятие остатка, присваивание, присваивание, присваивание). Ширина ярусно-параллельной формы равняется &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt;, что означает, что при использовании &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; процессоров матрица Адамара будет строиться за 6 операций.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные:&#039;&#039;&#039; число &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; - порядок матрицы Адамара &amp;lt;math&amp;gt;H_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;n&amp;lt;/math&amp;gt; - натуральное;&lt;br /&gt;
* &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; делится на 4;&lt;br /&gt;
* &amp;lt;math&amp;gt;n-1&amp;lt;/math&amp;gt; - простое.&lt;br /&gt;
&#039;&#039;&#039;Объем входных данных:&#039;&#039;&#039; 1 (число &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;H_n&amp;lt;/math&amp;gt; (её элементы &amp;lt;math&amp;gt;h_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объем выходных данных:&#039;&#039;&#039; &amp;lt;math&amp;gt;n^2&amp;lt;/math&amp;gt; (количество элементов матрицы Адамара размера &amp;lt;math&amp;gt;n*n&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;O(1)&amp;lt;/math&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
Алгоритм является полностью детерминированным. &lt;br /&gt;
&lt;br /&gt;
Для вершин &amp;lt;math&amp;gt;A_1-A_{n-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_1-B_{\frac{n}{2}-1}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;C_1-C_{n-1}&amp;lt;/math&amp;gt; информационного графа степени исхода являются линейными, что означает, что при возможности на этапе реализации необходимо позаботиться об эффективном доступе к элементам массива &amp;quot;&amp;lt;math&amp;gt;residues&amp;lt;/math&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Исследование масштабируемости параллельной реализации алгоритма построения матрицы Адамара проводилось на суперкомпьютере «Ломоносов». Для этого была исследована собственная реализация алгоритма с использованием средств MPI. В ходе исследования  было произведено множество запусков программы с различными значениями параметра &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; (размер матрицы Адамара) и числом процессоров.&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых параметров запуска реализации алгоритма:&lt;br /&gt;
*число процессоров (p): [2,64] с шагом 2;&lt;br /&gt;
*размер матрицы: простые числа в диапазоне [4,10000].&lt;br /&gt;
&lt;br /&gt;
В результате проведённых экспериментов был получен следующий диапазон эффективности реализации алгоритма:&lt;br /&gt;
*минимальная эффективность реализации 0.0000029% при n=4, p=2;&lt;br /&gt;
*максимальная эффективность реализации 0.323409% при n=908, p=2.&lt;br /&gt;
&lt;br /&gt;
Ниже представлены графики времени работы, производительности и эффективности данной реализации алгоритма построения матрицы Адамара в зависимости от изменяемых параметров запуска.&lt;br /&gt;
[[Файл:time_graph.png|500px|thumb|center|Время работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:perform_graph.png|500px|thumb|center|Изменение производительности параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
[[Файл:efficiency_graph.png|500px|thumb|center|Эффективность работы параллельного алгоритма в зависимости от размерности системы и числа процессоров.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://github.com/snikersman/Hadamard Исследованная параллельная реализация на языке 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;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Алгоритм построения матрицы Адамара реализован в различных математических пакетах и библиотеках: &lt;br /&gt;
* [https://www.mathworks.com/help/matlab/ref/hadamard.html?requestedDomain=www.mathworks.com MATLAB] (вносятся дополнительные ограничения, когда n, или n/12, или n/20 являются степенями по основанию 2)&lt;br /&gt;
* [http://r-survey.r-forge.r-project.org/survey/html/hadamard.html R]&lt;br /&gt;
* [https://reference.wolframcloud.com/cloudplatform/ref/HadamardMatrix.html Wolfram Mathematica]&lt;br /&gt;
* [http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.linalg.hadamard.html SciPy для Python]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</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:Nikita&amp;diff=18889</id>
		<title>Обсуждение участника:Nikita</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:Nikita&amp;diff=18889"/>
		<updated>2016-11-21T21:04:19Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Замечания к оформлению:&lt;br /&gt;
&lt;br /&gt;
1. Пункт 1.7 что обозначают серые вершины на графе?&lt;br /&gt;
&lt;br /&gt;
2. в пункте 1.9 указать чему соответствуют разные входные и выходные данные. Иначе непонятно будет человеку, который первый раз на сайте.&lt;br /&gt;
&lt;br /&gt;
3. Ссылки на литературу внутри текста статьи не нашел.&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;
1. Думаю, описание метода Пейли разумнее переместить в раздел &amp;quot;Математическое описание&amp;quot;&lt;br /&gt;
2. В математическом описании желательно хотя бы минимально кратко обосновать корректность (что достаточно проверить (p-1)/2 квадратов, и что матрица будет состоять только из элементов +1 и -1). &lt;br /&gt;
3. Исправить код. Есть как опечатки, так и ошибки. Вообще говоря, для любой похожей математической задачи необходимо писать тесты. Здесь он очевиден - проверить получившуюся матрицу по определению. В Algowiki тест вставлять не нужно, приведите его здесь.&lt;br /&gt;
4. Информационный граф неправилен. У вас, скорее, отражена макроструктура. Алгоритм довольно прост, поэтому необходимо построить граф по всем правилам, где выход операции переходит строго на вход следующей операции. Разумно будет взять конкретный пример n=4. Лучше построить граф, как с данными, так и без них. Представленный граф тоже можно будет оставить для наглядности. Его основная проблема в том, что не видно, как функция построения итоговой матрицы обращается к элементам residual, что может быть важным для каких-либо архитектур.&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</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:Vika3410/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%A0%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9&amp;diff=16200</id>
		<title>Участник:Vika3410/Метод Разделяй и властвуй</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:Vika3410/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%A0%D0%B0%D0%B7%D0%B4%D0%B5%D0%BB%D1%8F%D0%B9_%D0%B8_%D0%B2%D0%BB%D0%B0%D1%81%D1%82%D0%B2%D1%83%D0%B9&amp;diff=16200"/>
		<updated>2016-11-08T19:03:41Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--{{Assignment|IgorS}}--&amp;gt;&lt;br /&gt;
Авторы статьи: [[Участник:NikoSergAlex|Сергеев Никита]] (группа 614) (1.1, 1.2, 1.5, 1.6, 1.7, 1.8, 1.10), [[Участница:Vika3410|Стрельцова Виктория]] (группа 614) (1.2, 1.3, 1.4, 1.6, 1.7, 1.9, 1.10)&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод &amp;quot;Разделяй и властвуй&amp;quot; вычисления собственных значений и векторов трёхдиагональной матрицы&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt; c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
| parallel_complexity = &amp;lt;math&amp;gt; O(n^{2.3}) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
крайне редко: &amp;lt;math&amp;gt;  O(n^{2}) &amp;lt;/math&amp;gt; &lt;br /&gt;
| pf_width          = &lt;br /&gt;
| input_data        =  &amp;lt;math&amp;gt; 2n - 1 &amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       =  &amp;lt;math&amp;gt; n + n^2 &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; - является наиболее быстрым из существующих методов вычисления всех собственных значений и собственных векторов трехдиагональной матрицы, начиная с порядка n, который примерно равен 26. (Точное значение этого порогового порядка в конкретном случае зависит от компьютера.) &lt;br /&gt;
&lt;br /&gt;
Численно устойчивая реализация данного метода весьма не тривиальна, так как не смотря на то, что впервые метод был предложен в 1981 г., &amp;quot;правильный&amp;quot; способ реализации метода был найден лишь в 1992 г. Этот способ был воплощен при помощи LAPACK-программ ssyevd (для плотных матриц) и sstevd (для трехдиагональных матриц). В этих программах стратегия &amp;quot;разделяй-и-влавствуй&amp;quot; используется для матриц порядка выше 25. &lt;br /&gt;
&lt;br /&gt;
Для матриц порядка ниже 25 (или в тех случаях, когда требуются только собственные значения) автоматически происходит переход к методу QR-итерации.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Пусть &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
L = \begin{bmatrix}&lt;br /&gt;
 a_{1} &amp;amp; b_{1}&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp; b_{m} &amp;amp; a_{m+1} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
= \begin{bmatrix}&lt;br /&gt;
  a_{1} &amp;amp; b_{1} &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 b_{1} &amp;amp; \ddots  &amp;amp; \ddots \\&lt;br /&gt;
   &amp;amp; \ddots &amp;amp; a_{m-1} &amp;amp; b_{m-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp; b_{m-1} &amp;amp; a_{m} - b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; a_{m+1} - b_{m} &amp;amp; b_{m+1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{m+1} &amp;amp; \ddots \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \ddots &amp;amp; b_{n-1} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; b_{n-1} &amp;amp; a_{n} \\&lt;br /&gt;
\end{bmatrix} +&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
+ \begin{bmatrix}&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;b_{m} &amp;amp; b_{m} \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
 &amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp; \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&lt;br /&gt;
= \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m} * \begin{bmatrix} 0 \\ \vdots \\ 0 \\ 1 \\ 1 \\ 0 \\ \vdots \\ 0 \end{bmatrix} \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix} &lt;br /&gt;
&lt;br /&gt;
\equiv \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В предположении, что известны спектральные разложения матриц &amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;math&amp;gt;T_{i}=Q_{i} \Lambda_{i} Q_{i}^{T} &amp;lt;/math&amp;gt;. На самом деле, они будут вычисляться рекурсивно тем же самым алгоритмом. &lt;br /&gt;
&lt;br /&gt;
Можно установить связь между собственными значениями матрицы Т и собственными значениями матриц&lt;br /&gt;
&amp;lt;math&amp;gt;T_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_{2}&amp;lt;/math&amp;gt;. Получается:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; &lt;br /&gt;
T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} \Lambda_{1} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2} L_{2} Q_{2}^{T}\end{bmatrix} + b_{m}vv^{T} &lt;br /&gt;
= \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}(\begin{bmatrix} \Lambda_{1} &amp;amp; \\  &amp;amp; \Lambda_{2}\end{bmatrix} + b_{m}vv^{T})\begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;math&amp;gt; u = \begin{bmatrix} Q_{1}^{T} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}^{T}\end{bmatrix}v &amp;lt;/math&amp;gt; - матрица, в первой строке которой находятся элементы последнего столбца матрицы &amp;lt;math&amp;gt; Q_{1}^{T}&amp;lt;/math&amp;gt;, а во второй - элементы первого столбца матрицы &amp;lt;math&amp;gt; Q_{2}^{T}&amp;lt;/math&amp;gt;, так как &amp;lt;math&amp;gt;v = \begin{bmatrix} 0 , \ldots  ,  0 , 1 , 1 , 0 \ldots , 0 \end{bmatrix}^T&amp;lt;/math&amp;gt;.&lt;br /&gt;
Следовательно, &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; имеет такие же собственные значения, что и подобная ей матрица &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, &lt;br /&gt;
где &amp;lt;math&amp;gt;D = \begin{bmatrix} L_{1} &amp;amp; 0 \\ 0 &amp;amp; L_{2}\end{bmatrix}&amp;lt;/math&amp;gt; - диагональная матрица, &lt;br /&gt;
&amp;lt;math&amp;gt;\rho = b_{m}&amp;lt;/math&amp;gt; - число, а &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; - вектор. &lt;br /&gt;
В дальнейшем предполагаем, не ограничивая общности, что диагональные элементы &amp;lt;math&amp;gt;d_{1}, \ldots, d_{n}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; упорядочены по не возрастанию: &amp;lt;math&amp;gt;d_{n} &amp;lt;= \ldots &amp;lt;=d_{1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Для того, чтобы найти собственные значения матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, потребуется вычислить её характеристический многочлен, считая пока матрицу &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденной.&lt;br /&gt;
Тогда получаем&lt;br /&gt;
&amp;lt;math&amp;gt;det(D + \rho uu^{T} - \lambda I) = det((D - \lambda I)(I + \rho (D- \lambda I)^{-1} uu^{T}))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Так как &amp;lt;math&amp;gt;D - \lambda I&amp;lt;/math&amp;gt; невырожденная, &amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 0&amp;lt;/math&amp;gt; тогда и только тогда, когда &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; - является собственным значением. Можем заметить, что матрица &amp;lt;math&amp;gt;I + \rho (D - \lambda I)^{-1}uu^{T}&amp;lt;/math&amp;gt; получается из единичной путём добавления матрицы ранга 1. Определитель такой матрицы не сложно вычислить.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;Лемма 1.&#039;&#039; Справедливо равенство &amp;lt;math&amp;gt;det(I + xy^{T}) = 1 + y^{T}x&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; - векторы.&lt;br /&gt;
&lt;br /&gt;
Следовательно, получаем&lt;br /&gt;
&amp;lt;math&amp;gt;det(I + \rho (D - \lambda I)^{-1}uu^{T}) = 1 + \rho u^{T}(D - \lambda I)^{-1}u&amp;lt;/math&amp;gt; &amp;lt;math&amp;gt; = 1 + \rho \sum_{i=1, n} \frac{u_{i}^{2}} {d_{i}-\lambda} \equiv f(\lambda)&amp;lt;/math&amp;gt; , &lt;br /&gt;
&lt;br /&gt;
т.е. собственные значения матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; являются корнями так называемого векового уравнения &amp;lt;math&amp;gt;f(\lambda) = 0&amp;lt;/math&amp;gt;. Если все числа &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; различны между собой и все &amp;lt;math&amp;gt;u_{i} &amp;lt;&amp;gt; 0&amp;lt;/math&amp;gt; (случай общего положения), то &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; имеет график типа, который показан на рис.1(где &amp;lt;math&amp;gt;n = 4&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\rho &amp;gt; 0&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
[[File:Сергеев 1.jpg|thumb|center|800px|Рис. 1. График функции &amp;lt;math&amp;gt; f(\lambda) = 1 + \frac{0.5}{1 - \lambda} + \frac{0.5}{2 - \lambda} + \frac{0.5}{3 - \lambda} + \frac{0.5}{4 - \lambda}&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
По рисунку можно заметить, что прямая &amp;lt;math&amp;gt;y = 1&amp;lt;/math&amp;gt; является горизонтальной асимптотой для данного графика, а прямые &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt; есть вертикальные асимптоты. Так как &amp;lt;math&amp;gt;f^{&#039;}(\lambda) =  \rho \sum_{i=1, n} \frac{u_{i}^{2}} {(d_{i}-\lambda)^{2}}&amp;gt; 0 &amp;lt;/math&amp;gt;, функция возрастает всюду, кроме точек &amp;lt;math&amp;gt;\lambda = d_{i}&amp;lt;/math&amp;gt;. Из этого следует, что корни функции разделяются числами &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; и ещё один корень находится справа от точки &amp;lt;math&amp;gt;d_{1}&amp;lt;/math&amp;gt; (на рис. 1 &amp;lt;math&amp;gt;d_{1} = 4&amp;lt;/math&amp;gt;). (При &amp;lt;math&amp;gt;\rho&amp;lt;0&amp;lt;/math&amp;gt; функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; всюду убывает и соответствующий корень будет находиться слева от точки &amp;lt;math&amp;gt;d_{n}&amp;lt;/math&amp;gt;). Для функции &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt;, которая является монотонной и гладкой на каждом из интервалов &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;, можно найти вариант метода Ньютона, который будет быстро и монотонно сходиться к каждому из корней, при условии, что начальная точка взята в &amp;lt;math&amp;gt;(d_{i+1},d_{i})&amp;lt;/math&amp;gt;. Нам достаточно знать тот факт, что на практике метод сходится к каждому собственному значению за строго ограниченное число шагов. Поскольку вычисление &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;f^{&#039;}(\lambda)&amp;lt;/math&amp;gt; стоит &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов, для вычисления одного собственного значения достаточно &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов, следовательно для вычисления всех &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; собственных значений матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; потребуется &amp;lt;math&amp;gt;O(n^{2})&amp;lt;/math&amp;gt; флопов.&lt;br /&gt;
Для собственных векторов матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt; мы легко можем получить явные выражения.&lt;br /&gt;
&lt;br /&gt;
  &#039;&#039;Лемма 2.&#039;&#039; Если &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; - собственное значение матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;, то соответствующий вектор равен &amp;lt;math&amp;gt;(D - \alpha I)^{-1}u&amp;lt;/math&amp;gt;. Поскольку матрица &amp;lt;math&amp;gt;D - \alpha I&amp;lt;/math&amp;gt; диагональная, для вычисления такого вектора достаточно &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; флопов.&lt;br /&gt;
&lt;br /&gt;
Доказательство.&lt;br /&gt;
&amp;lt;math&amp;gt;(D + \rho uu^{T})[(D - \alpha I)^{-1}u] = &lt;br /&gt;
&lt;br /&gt;
(D - \alpha I + \alpha I + \rho uu^{T})(D - \alpha I)^{-1}u = &lt;br /&gt;
&lt;br /&gt;
u + \alpha (D - \alpha I)^{-1}u + u[\rho u^{T}(D - \alpha I)^{-1}u]= &amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; = u + \alpha(D - \alpha I)^{-1}u - u = \alpha [(D - \alpha I)^{-1}u]&amp;lt;/math&amp;gt;, &lt;br /&gt;
&lt;br /&gt;
поскольку &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \rho u^{T}(D - \alpha I)^{-1}u + 1 = f(\alpha) = 0 &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;O(n^{2})&amp;lt;/math&amp;gt; флопов. К сожалению, данная формула не обеспечивает нам численной устойчивости, так как для двух очень близких значений &amp;lt;math&amp;gt;\alpha_{i}&amp;lt;/math&amp;gt; может давать неортогональные приближенные собственные векторы &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt;. Учёным потребовалось целое десятилетие для того, чтобы найти устойчивую альтернативу исходному описанию алгоритма. Подробнее детали будут обсуждаться ниже в данном разделе. &lt;br /&gt;
&lt;br /&gt;
Алгоритм является рекурсивным.&lt;br /&gt;
&lt;br /&gt;
До сих пор полагалось, что все &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; различны и все &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt; отличны от нуля. Если это будет не так, то вековое уравнение &amp;lt;math&amp;gt;f(\lambda)=0&amp;lt;/math&amp;gt; имеет &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; вертикальных асимптот, где &amp;lt;math&amp;gt;k&amp;lt;n&amp;lt;/math&amp;gt;, а следовательно &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; корней. Однако оказывается, что остальные &amp;lt;math&amp;gt;n - k&amp;lt;/math&amp;gt; собственных значений могут быть определены без каких-либо усилий: в случае, если &amp;lt;math&amp;gt;d_{i}=d_{i+1}&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;u_{i}=0&amp;lt;/math&amp;gt;, легко показать, что &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; является собственным значением и для матрицы &amp;lt;math&amp;gt;D + \rho uu^{T}&amp;lt;/math&amp;gt;. В такой ситуации мы говорим о &#039;&#039;&#039;дефляции&#039;&#039;&#039;. На практике выбирается некоторое пороговое значение и дефляция для числа &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; регистрируется, в том случает, если в смысле этого порога &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; достаточно близко к &amp;lt;math&amp;gt;d_{i+1}&amp;lt;/math&amp;gt; либо &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&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;u_{i}=0&amp;lt;/math&amp;gt;, то соответствующий собственный вектор есть i-й столбец &amp;lt;math&amp;gt;e_{i}&amp;lt;/math&amp;gt; единичной матрицы. Это означает, что &amp;lt;math&amp;gt;e_{i}&amp;lt;/math&amp;gt; является i-м столбцом в матрице &amp;lt;math&amp;gt;Q_{&#039;}&amp;lt;/math&amp;gt;, следовательно при формировании матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; применяя левое умножение &amp;lt;math&amp;gt;Q_{1}&amp;lt;/math&amp;gt; на &amp;lt;math&amp;gt;Q_{2}&amp;lt;/math&amp;gt; вычисление i-го столбца не будет требовать никаких затрат. Аналогичное упрощение возможно в случае &amp;lt;math&amp;gt;d_{i} = d_{i+1}&amp;lt;/math&amp;gt;. При дефляции многих собственных значений устраняется большая часть работы, которая связана с матричным умножением.&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительным ядром последовательной схемы решения будет являться вычисление матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; собственных векторов при помощи умножения матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt;. Эта операция имеет сложность &amp;lt;math&amp;gt;cn^{3}&amp;lt;/math&amp;gt; о чём будет говориться ниже, в разделе [[#Последовательная сложность алгоритма]] .&lt;br /&gt;
&lt;br /&gt;
Данной операции предшествует вычисление собственных значений и векторов матрицы &amp;lt;math&amp;gt; D + \rho uu^{T}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
В разделе [[#Информационный граф]] описана структура алгоритма, в которой есть блок умножения матриц для вычисления собственных векторов, являющийся вычислительным ядром алгоритма. В соответствующем разделе ([[#Вычислительное ядро алгоритма]]) мы упоминали о том, что данному блоку предшествует вычисление собственных значений, которое производится [https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%9D%D1%8C%D1%8E%D1%82%D0%BE%D0%BD%D0%B0 методом Ньютона].&lt;br /&gt;
&lt;br /&gt;
Далее пойдет речь о решении &#039;&#039;&#039;векового уравнения&#039;&#039;&#039;, которое является одной из основных частей алгоритма.&lt;br /&gt;
&lt;br /&gt;
Предположим, что некоторое &amp;lt;math&amp;gt;u_{i}&amp;lt;/math&amp;gt;, хотя и мало, все же недостаточно мало для того, чтобы была зарегистрирована дефляция. В этом случае применение метода Ньютона к решению векового уравнения встречается с затруднениями. Вспомним, что пересчет приближённого решения &amp;lt;math&amp;gt;u_{j}&amp;lt;/math&amp;gt; уравнения &amp;lt;math&amp;gt;f(\lambda) = 0&amp;lt;/math&amp;gt; в методе Ньютона основан на следующих положениях:&lt;br /&gt;
&lt;br /&gt;
1. Вблизи точки &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt; функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; аппроксимируется линейной функцией &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt;; график есть прямая линия, касающаяся графика функции &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2. В качестве &amp;lt;math&amp;gt;\lambda_{j+1}&amp;lt;/math&amp;gt; берётся нуль этого линейного приближения, т.е. &amp;lt;math&amp;gt;l(\lambda_{j+1})=0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Функция, показанная на рис.1, не доставляет видимых трудностей методу Ньютона, поскольку вблизи каждого своего нуля &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; достаточно хорошо аппроксимируется линейными функциями. Однако рассмотрим график функции на рис. 2. Она получена из функции на рис. 1 заменой значения .5 для &amp;lt;math&amp;gt;u_{i}^{2}&amp;lt;/math&amp;gt; на .001. Это новое значение недостаточно мало для того, чтобы вызвать дефляцию. График функции в левой части рис.2 визуально не отличим от её вертикальных и горизонтальных асимптот, поэтому в правой части укрупненно воспроизведён фрагмент графика, прилегающий к вертикальной асимптоте &amp;lt;math&amp;gt;\lambda = 2&amp;lt;/math&amp;gt;. Видно, что график слишком быстро &amp;quot;выполняет поворот&amp;quot; и для большей части значений &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; почти горизонтален. Поэтому, применяя метод Ньютона почти к любому начальному приближению &amp;lt;math&amp;gt;\lambda_{0}&amp;lt;/math&amp;gt;, мы получаем линейное приближение &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt; с почти горизонтальным графиком и малым положительным угловым коэффициентом. В результате &amp;lt;math&amp;gt;\lambda_{1}&amp;lt;/math&amp;gt; является отрицательным числом, огромным по абсолютной величине, которое совершенно бесполезно в качестве приближения к истинному корню.&lt;br /&gt;
&lt;br /&gt;
[[File:Сергеев 2.jpg|thumb|center|800px|Рис. 2. График функции &amp;lt;math&amp;gt; f(\lambda) = 1 + \frac{10^{-3}}{1 - \lambda} + \frac{10^{-3}}{2 - \lambda} + \frac{10^{-3}}{3 - \lambda} + \frac{10^{-3}}{4 - \lambda}&amp;lt;/math&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Чтобы найти выход из этого положения, можно модифицировать метод Ньютона следующим образом: раз &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; нельзя хорошо приблизить линейной функцией &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt;, попробуем взять в качестве приближения какую-нибудь другую простую функцию &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;. Нет ничего особого именно в прямых линиях: для метода Ньютона вместо &amp;lt;math&amp;gt;l(\lambda)&amp;lt;/math&amp;gt; можно взять любое приближение &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;, значения и нули которого легко вычисляются. Функция &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt; имеет полюсы в точках &amp;lt;math&amp;gt;d_{i}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;d_{i+1}&amp;lt;/math&amp;gt;, которые определяют её поведение в соответствующих окрестностях. Поэтому при поиске корня в интервале &amp;lt;math&amp;gt;(d_{i+1}, d_{i})&amp;lt;/math&amp;gt; естественно выбрать функцию &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt;, также имеющую эти полюсы, т.е. функцию вида&lt;br /&gt;
&amp;lt;math&amp;gt;h(\lambda)= \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} + c_{3}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Константы &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; обеспечивающие, что &amp;lt;math&amp;gt;h(\lambda)&amp;lt;/math&amp;gt; есть приближение к &amp;lt;math&amp;gt;f(\lambda)&amp;lt;/math&amp;gt;, можно выбрать несколькими способами. Отметим, что если &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; уже известны, то уравнение &amp;lt;math&amp;gt;h(\lambda)=0&amp;lt;/math&amp;gt; легко решается относительно &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt;, поскольку сводится к эквивалентному квадратному уравнению&lt;br /&gt;
&amp;lt;math&amp;gt;c_{1}(d_{i+1}-\lambda)+c_{2}(d_{i}-\lambda)+c_{3}(d_{i}-\lambda)(d_{i+1}-\lambda)=0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;\lambda_{j}&amp;lt;/math&amp;gt; - приближённое значение корня. определим &amp;lt;math&amp;gt;c_{1},c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;c_{3}&amp;lt;/math&amp;gt; так, чтобы&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} + c_{3} = h(\lambda) \approx f(\lambda) = 1 + \rho \sum_{k=1, n} \frac{u_{k}^{2}} {d_{k}-\lambda} &amp;lt;/math&amp;gt;&lt;br /&gt;
для &amp;lt;math&amp;gt;\lambda&amp;lt;/math&amp;gt; в окрестности &amp;lt;math&amp;gt;\lambda_{j}&amp;lt;/math&amp;gt;. Заметим, что&lt;br /&gt;
&amp;lt;math&amp;gt;f(\lambda) = 1 + \rho \sum_{k=1, i} \frac{u_{k}^{2}} {d_{k}-\lambda} + \rho \sum_{k=i+1, n} \frac{u_{k}^{2}} {d_{k}-\lambda} \equiv 1 + \psi_{1}(\lambda) + \psi_{2}(\lambda)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt;\lambda \in (d_{i+1},d_{i})&amp;lt;/math&amp;gt;, то &amp;lt;math&amp;gt;\psi_{1}(\lambda)&amp;lt;/math&amp;gt; есть сумма положительных слагаемых, а &amp;lt;math&amp;gt;\psi_{2}(\lambda)&amp;lt;/math&amp;gt; - сумма отрицательных. Поэтому и &amp;lt;math&amp;gt;\psi_{1}(\lambda)&amp;lt;/math&amp;gt;, и &amp;lt;math&amp;gt;\psi_{2}(\lambda)&amp;lt;/math&amp;gt; могут быть вычислены с высокой точностью; однако при их сложении вполне вероятно взаимное уничтожение верных разрядов и потеря относительной точности в сумме. Возьмем числа &amp;lt;math&amp;gt;c_{1}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{1}}&amp;lt;/math&amp;gt;, такие, что функция &lt;br /&gt;
&amp;lt;math&amp;gt;h_{1}(\lambda) \equiv \hat{c_{1}} + \frac{c_{1}}{d_{i}-\lambda}&amp;lt;/math&amp;gt;   удовлетворяет условиям  &amp;lt;math&amp;gt;h_{1}(\lambda_{j}) = \psi_{1}(\lambda_{j})&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;h_{1}^{&#039;}(\lambda_{j})=\psi_{1}^{&#039;}(\lambda_{j})&amp;lt;/math&amp;gt; (*)&lt;br /&gt;
&lt;br /&gt;
Это означает, что гипербола, являющаяся графиком функции &amp;lt;math&amp;gt;h_{1}(\lambda)&amp;lt;/math&amp;gt;, касается графика функции &amp;lt;math&amp;gt;\psi_{i}(\lambda)&amp;lt;/math&amp;gt; при &amp;lt;math&amp;gt;\lambda = \lambda_{j}&amp;lt;/math&amp;gt;. Два условия в (*) - это обычные условия метода Ньютона, за исключением того, что вместо прямой в качестве приближения используется гипербола. Легко проверить, что &amp;lt;math&amp;gt;c_{1}=\psi_{1}^{&#039;}(\lambda_{j})(d_{i} - \lambda_{j})^{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{1}}=\psi_{1}(\lambda_{j}) - \psi_{1}^{&#039;}(\lambda_{j})(d_{i} - \lambda_{j})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Подобным же образом выбираем &amp;lt;math&amp;gt;c_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\hat{c_{2}}&amp;lt;/math&amp;gt; так, чтобы функция &lt;br /&gt;
&amp;lt;math&amp;gt;h_{2}(\lambda) \equiv \hat{c_{2}} + \frac{c_{2}}{d_{i+1}-\lambda}&amp;lt;/math&amp;gt; удовлетворяла условиям&lt;br /&gt;
&amp;lt;math&amp;gt;h_{2}(\lambda_{j}) = \psi_{2}(\lambda_{j})&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;h_{2}^{&#039;}(\lambda_{j})=\psi_{2}^{&#039;}(\lambda_{j})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Наконец, полагаем&lt;br /&gt;
&amp;lt;math&amp;gt;h(\lambda) = 1 + h_{1}(\lambda) + h_{2}(\lambda) = (1 + \hat{c_{1}} + \hat{c_{2}} + \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda} \equiv c_{3} + \frac{c_{1}}{d_{i}-\lambda} + \frac{c_{2}}{d_{i+1}-\lambda}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Рассмотрим каким именно образом происходит вычисление собственных значений и собственных векторов симметричной трехдиагональной матрицы при помощи стратегии &amp;quot;разделяй и властвуй&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;proc dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T,Q,\Lambda)...&amp;lt;/math&amp;gt; по входной матрице &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; вычисляются выходные матрицы &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;, такие, что &amp;lt;math&amp;gt;T = Q\Lambda Q^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В случае, &#039;&#039;&#039;если&#039;&#039;&#039; &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; - матрица размера &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; x &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; :&lt;br /&gt;
&lt;br /&gt;
1. Присвоить выходным параметрам значения &amp;lt;math&amp;gt; Q = 1, \Lambda = T&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Иначе&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
1.   Представить &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; в виде &amp;lt;math&amp;gt; T = \begin{bmatrix} T_{1} &amp;amp; 0 \\ 0 &amp;amp; T_{2}\end{bmatrix} + b_{m}vv^{T} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{1},Q_{1},\Lambda_{1})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. &#039;&#039;call dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{2},Q_{2},\Lambda_{2})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Построить &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt; по &amp;lt;math&amp;gt; \Lambda_{1},\Lambda_{2}, Q_{1}, Q_{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. Найти матрицу собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
6. Найти матрицу собственных векторов &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
7. Построить матрицу собственных векторов &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; для матрицы &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; : &amp;lt;math&amp;gt; Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}* Q^{&#039;} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
8. Присвоить выходным параметрам значения &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;endif&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
Рассмотрим сложность алгоритма. Пусть &amp;lt;math&amp;gt;t(n)&amp;lt;/math&amp;gt; - число флопов, которое потребуется при обработке матрицы размера &amp;lt;math&amp;gt; n * &lt;br /&gt;
n&amp;lt;/math&amp;gt; процедурой &#039;&#039;dc_eig&#039;&#039;. В таком случае &lt;br /&gt;
&lt;br /&gt;
  &amp;lt;math&amp;gt; t(n) = 2t(n/2) &amp;lt;/math&amp;gt; два рекурсивных обращения к &#039;&#039;dc_eig&#039;&#039;&amp;lt;math&amp;gt;(T_{i},Q_{i},\Lambda_{i})&amp;lt;/math&amp;gt;&lt;br /&gt;
         &amp;lt;math&amp;gt; +O(n^{2})&amp;lt;/math&amp;gt; вычисление собственных значений матрицы &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
         &amp;lt;math&amp;gt; +O(n^{2})&amp;lt;/math&amp;gt; вычисление собственных векторов матрицы &amp;lt;math&amp;gt;D+\rho uu^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
         &amp;lt;math&amp;gt; +c*n^{3}&amp;lt;/math&amp;gt; вычисление матрицы &amp;lt;math&amp;gt;Q = \begin{bmatrix} Q_{1} &amp;amp; 0 \\ 0 &amp;amp; Q_{2}\end{bmatrix}*Q^{&#039;}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Если &amp;lt;math&amp;gt; Q_{1}, Q_{2}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; рассматривать как плотные матрицы и использовать стандартный алгоритм матричного умножения, то константа &amp;lt;math&amp;gt; c &amp;lt;/math&amp;gt; в последней строке будет равна 1. Следовательно, именно это умножение и будет составлять наиболее трудоёмкую часть алгоритма в целом. Игнорируя члены порядка &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;, получаем &amp;lt;math&amp;gt;t(n) = 2t(n/2) + cn^{3}&amp;lt;/math&amp;gt;. Решив это разностное уравнение, находим &amp;lt;math&amp;gt; t \approx c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
На практике константа &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; обычно оказывается гораздо меньше 1, так как матрица &amp;lt;math&amp;gt;Q^{&#039;}&amp;lt;/math&amp;gt; весьма разрежена вследствие явления, которое называется дефляцией, и которое было описано выше.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
На рисунке 3 изображена структура алгоритма.&lt;br /&gt;
[[File:Сергеев 5.jpg|thumb|center|left|1000px|Рис. 3. Дерево алгоритма &amp;quot;Разделяй и властвуй&amp;quot;]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Данная структура алгоритма позволяет выполнять рекурсивный вызов функций для двух подматриц исходной матрицы как последовательно, так и параллельно. &lt;br /&gt;
При последовательной реализации алгоритма вызов функций производится по очереди - сначала для одной подматрицы, затем для другой. При параллельной реализации алгоритма данные функции могут отрабатывать одновременно.&lt;br /&gt;
Поскольку функции являются рекурсивными, их параллельный вызов даст значительный выигрыш во времени.&lt;br /&gt;
При размерности матрицы больше 3 параллельная реализация позволяет сократить количество этапов работы алгоритма больше, чем в два раза.&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;: &amp;lt;math&amp;gt; 2n - 1 &amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица собственных значений размера &amp;lt;math&amp;gt; 1 * n &amp;lt;/math&amp;gt; и матрица собственных векторов размера &amp;lt;math&amp;gt; n * n &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt; n + n^2 &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
Данный алгоритм является самым быстрым алгоритмом среди существующих: Разделяй и властвуй, QR, Бисекция и обратная итерация.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Последовательная сложность данного алгоритма:&#039;&#039;&#039; &amp;lt;math&amp;gt; t = c\frac{4}{3}n^{3} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Параллельная сложность алгоритма (за счет дефляции):&#039;&#039;&#039; &amp;lt;math&amp;gt; O(n^{2.3})&amp;lt;/math&amp;gt;;  в крайне редких случаях: &amp;lt;math&amp;gt; O(n^{2}) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Особенности алгоритма:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1. Дефляция ([[#Дефляция]])&lt;br /&gt;
&lt;br /&gt;
2. Адаптированный метод Ньютона ([[#Макроструктура алгоритма]])&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
Вторая часть описания алгоритмов в рамках AlgoWiki рассматривает все составные части процесса их реализации. Рассматривается как последовательная реализация алгоритма, так и параллельная. Описывается взаимосвязь свойств программ, реализующих алгоритм, и особенностей архитектуры компьютера, на которой они выполняются. Исследуется работа с памятью, локальность данных и вычислений, описывается масштабируемость и эффективность параллельных программ, производительность компьютеров, достигаемая на данной программе. Обсуждаются особенности реализации для разных классов архитектур компьютеров, приводятся ссылки на реализации в существующих библиотеках.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Локальность данных и вычислений ==&lt;br /&gt;
&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ==&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Единственный найденный пример реализации описан в [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf Francoise Tisseury, Jack Dongarra, &amp;quot;Parallelizing the Divide and Conquer Algorithm for the Symmetric Tridiagonal Eigenvalue Problem on Distributed Memory Architectures&amp;quot; ]   ([3] с. 7, 19-20).&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
[1] Дж. Деммель, &amp;quot;Вычислительная линейная алгебра&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[2] [http://www.netlib.org/lapack/lawnspdf/lawn132.pdf Francoise Tisseury, Jack Dongarra, &amp;quot;Parallelizing the Divide and Conquer Algorithm for the Symmetric Tridiagonal Eigenvalue Problem on Distributed Memory Architectures&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
[3] [https://en.wikipedia.org/wiki/Divide-and-conquer_eigenvalue_algorithm Алгоритм &amp;quot;Разделяй и властвуй&amp;quot; - Wikipedia]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[en:Description of algorithm properties and structure]]&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</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:NikoSergAlex&amp;diff=16199</id>
		<title>Обсуждение участника:NikoSergAlex</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:NikoSergAlex&amp;diff=16199"/>
		<updated>2016-11-08T19:02:18Z</updated>

		<summary type="html">&lt;p&gt;Chernyavskiy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Замечания к статье ==&lt;br /&gt;
&lt;br /&gt;
* отсутствует описание вклада каждого автора--[[Участник:IgorS|IgorS]] ([[Обсуждение участника:IgorS|обсуждение]]) 14:53, 26 октября 2016 (MSK)&lt;br /&gt;
** +--[[Участник:IgorS|IgorS]] ([[Обсуждение участника:IgorS|обсуждение]]) 14:52, 2 ноября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
* п.п. 1.7 не соответствует рисунку информационного графа--[[Участник:IgorS|IgorS]] ([[Обсуждение участника:IgorS|обсуждение]]) 14:53, 26 октября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
* п.п. 1.8 и 1.9 не раскрыт--[[Участник:IgorS|IgorS]] ([[Обсуждение участника:IgorS|обсуждение]]) 14:53, 26 октября 2016 (MSK)&lt;br /&gt;
&lt;br /&gt;
===Пример правильно оформленной работы===&lt;br /&gt;
&lt;br /&gt;
* http://algowiki-project.org/ru/Разложение_Холецкого_(метод_квадратного_корня)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Второй этап проверки ==&lt;br /&gt;
&lt;br /&gt;
=== Итерация 1 ===&lt;br /&gt;
&lt;br /&gt;
Начальные замечания и вопросы (возможно будут появляться новые, пишите, пожалуйста, комментарии по ходу исправлений и ответы):&lt;br /&gt;
&lt;br /&gt;
* Исправить ошибки в формулах в разделе 1.2&lt;br /&gt;
* Как решение векового уравнения относится к макроструктуре алгоритма (раздел 1.4)&lt;br /&gt;
* Исправлялся ли информационный граф? То, что имеется сейчас не соответствует инструкции (https://algowiki-project.org/ru/%D0%A1%D1%82%D0%B0%D0%BD%D0%B4%D0%B0%D1%80%D1%82_%D0%B2%D0%B8%D0%B7%D1%83%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_%D0%93%D0%90) &lt;br /&gt;
Граф нужно кардинально переработать.&lt;br /&gt;
* Раздел 1.8 необзодимо написать намного более подробно.&lt;br /&gt;
* Откуда получены значения параллельной сложности алгоритма в разделе 1.10?&lt;/div&gt;</summary>
		<author><name>Chernyavskiy</name></author>
	</entry>
</feed>