<?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=%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2+%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80</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=%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2+%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80"/>
	<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/%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80"/>
	<updated>2026-10-22T15:57:11Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18867</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18867"/>
		<updated>2016-11-21T19:35:10Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)&amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; операции деления, &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; операции взятия корня, &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции умножения и &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В худшем случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами.&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение 8 ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Кроме вышеизложенного, отметим следующую особенность алгоритма.&lt;br /&gt;
Пусть вращение &amp;lt;math&amp;gt;J_1&amp;lt;/math&amp;gt; изменяет строки и столбцы с номерами &amp;lt;math&amp;gt;j_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k_1&amp;lt;/math&amp;gt;, а вращение &amp;lt;math&amp;gt;J_2&amp;lt;/math&amp;gt; изменяет строки и столбцы с номерами &amp;lt;math&amp;gt;j_2&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k_2&amp;lt;/math&amp;gt;, и при этом выполнено:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;j_1 \neq j_2, k_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;k_1 \neq j_2, k_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда вращения &amp;lt;math&amp;gt;J_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;J_2&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;4n&amp;lt;/math&amp;gt;. Таким образом, итоговый алгоритм имеет ширину ЯПФ &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; и высоту &amp;lt;math&amp;gt;O(n^2)&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&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;A&amp;lt;/math&amp;gt; в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;8&amp;lt;/math&amp;gt; полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма:&lt;br /&gt;
*       число процессоров [1 : 48] с шагом 1&lt;br /&gt;
*       размерность матрицы [400:1600] с шагом 200&lt;br /&gt;
&lt;br /&gt;
Использовался компилятор g++ версии 5.4.0  со следующими флагами: -O2, -fopenmp, -std=c++11. &lt;br /&gt;
Флаг -O2 является опциональным, и означает уровень оптимизации кода при компиляции. Все прочие флаги строго обязательны при компиляции, т.к. в коде используются функции из стандарта С++11.   &lt;br /&gt;
&lt;br /&gt;
[[file:parallel11.jpg|thumb|center|700px|Рисунок 2. Изменение производительности в зависимости от числа процессоров и размерности матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Чтобы продемонстрировать важное свойство алгоритма, приведем так же график производительности в зависимости от числа процессов при размере матрицы 1600*1600&lt;br /&gt;
&lt;br /&gt;
[[file:parallel1600.jpg|thumb|center|700px|Рисунок 2. Изменение производительности в зависимости от числа процессоров при размере матрицы 1600х1600.]]&lt;br /&gt;
&lt;br /&gt;
За &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; принята производительность при одном процессе.&lt;br /&gt;
Как видно, производительность резко увеличивается при добавлении числа потоков в начале и снижается при дальнейшем добавлении.&lt;br /&gt;
Это связано с тем, что в одном потоке совершается малое количество арифметических операций. После выполнения операций совершается запись в массив полученных значений, в результате чего возникает конфликт потоков.&lt;br /&gt;
Поэтому наиболее оптимальное число потоков &amp;lt;math&amp;gt;8-16&amp;lt;/math&amp;gt;, что говорит о слабой масштабируемости данного алгоритма.&lt;br /&gt;
&lt;br /&gt;
[http://pastebin.com/yUyh1ziL Параллельная реализация на языке 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;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18866</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18866"/>
		<updated>2016-11-21T19:34:24Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)&amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; операции деления, &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; операции взятия корня, &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции умножения и &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В худшем случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами.&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение 8 ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Кроме вышеизложенного, отметим следующую особенность алгоритма.&lt;br /&gt;
Пусть вращение &amp;lt;math&amp;gt;J_1&amp;lt;/math&amp;gt; изменяет строки и столбцы с номерами &amp;lt;math&amp;gt;j_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k_1&amp;lt;/math&amp;gt;, а вращение &amp;lt;math&amp;gt;J_2&amp;lt;/math&amp;gt; изменяет строки и столбцы с номерами &amp;lt;math&amp;gt;j_2&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k_2&amp;lt;/math&amp;gt;, и при этом выполнено:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;j_1 \neq j_2, k_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;k_1 \neq j_2, k_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда вращения &amp;lt;math&amp;gt;J_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;J_2&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;4n&amp;lt;/math&amp;gt;. Таким образом, итоговый алгоритм имеет ширину ЯПФ &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt; и высоту &amp;lt;math&amp;gt;O(N^2)&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&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;A&amp;lt;/math&amp;gt; в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;8&amp;lt;/math&amp;gt; полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма:&lt;br /&gt;
*       число процессоров [1 : 48] с шагом 1&lt;br /&gt;
*       размерность матрицы [400:1600] с шагом 200&lt;br /&gt;
&lt;br /&gt;
Использовался компилятор g++ версии 5.4.0  со следующими флагами: -O2, -fopenmp, -std=c++11. &lt;br /&gt;
Флаг -O2 является опциональным, и означает уровень оптимизации кода при компиляции. Все прочие флаги строго обязательны при компиляции, т.к. в коде используются функции из стандарта С++11.   &lt;br /&gt;
&lt;br /&gt;
[[file:parallel11.jpg|thumb|center|700px|Рисунок 2. Изменение производительности в зависимости от числа процессоров и размерности матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Чтобы продемонстрировать важное свойство алгоритма, приведем так же график производительности в зависимости от числа процессов при размере матрицы 1600*1600&lt;br /&gt;
&lt;br /&gt;
[[file:parallel1600.jpg|thumb|center|700px|Рисунок 2. Изменение производительности в зависимости от числа процессоров при размере матрицы 1600х1600.]]&lt;br /&gt;
&lt;br /&gt;
За &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; принята производительность при одном процессе.&lt;br /&gt;
Как видно, производительность резко увеличивается при добавлении числа потоков в начале и снижается при дальнейшем добавлении.&lt;br /&gt;
Это связано с тем, что в одном потоке совершается малое количество арифметических операций. После выполнения операций совершается запись в массив полученных значений, в результате чего возникает конфликт потоков.&lt;br /&gt;
Поэтому наиболее оптимальное число потоков &amp;lt;math&amp;gt;8-16&amp;lt;/math&amp;gt;, что говорит о слабой масштабируемости данного алгоритма.&lt;br /&gt;
&lt;br /&gt;
[http://pastebin.com/yUyh1ziL Параллельная реализация на языке 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;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18865</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18865"/>
		<updated>2016-11-21T19:34:05Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)&amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; операции деления, &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; операции взятия корня, &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции умножения и &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В худшем случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами.&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение 8 ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Кроме вышеизложенного, отметим следующую особенность алгоритма.&lt;br /&gt;
Пусть вращение &amp;lt;math&amp;gt;J_1&amp;lt;/math&amp;gt; изменяет строки и столбцы с номерами &amp;lt;math&amp;gt;j_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k_1&amp;lt;/math&amp;gt;, а вращение &amp;lt;math&amp;gt;J_2&amp;lt;/math&amp;gt; изменяет строки и столбцы с номерами &amp;lt;math&amp;gt;j_2&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k_2&amp;lt;/math&amp;gt;, и при этом выполнено:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;j_1 \neq j_2, k_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;k_1 \neq j_2, k_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда вращения &amp;lt;math&amp;gt;J_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;J_2&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;4n&amp;lt;/math&amp;gt;. Таким образом, итоговый алгоритм имеет ширину ЯПФ &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt; и высоту &amp;lt;math&amp;gt;O(n^2)&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&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;A&amp;lt;/math&amp;gt; в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;8&amp;lt;/math&amp;gt; полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма:&lt;br /&gt;
*       число процессоров [1 : 48] с шагом 1&lt;br /&gt;
*       размерность матрицы [400:1600] с шагом 200&lt;br /&gt;
&lt;br /&gt;
Использовался компилятор g++ версии 5.4.0  со следующими флагами: -O2, -fopenmp, -std=c++11. &lt;br /&gt;
Флаг -O2 является опциональным, и означает уровень оптимизации кода при компиляции. Все прочие флаги строго обязательны при компиляции, т.к. в коде используются функции из стандарта С++11.   &lt;br /&gt;
&lt;br /&gt;
[[file:parallel11.jpg|thumb|center|700px|Рисунок 2. Изменение производительности в зависимости от числа процессоров и размерности матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Чтобы продемонстрировать важное свойство алгоритма, приведем так же график производительности в зависимости от числа процессов при размере матрицы 1600*1600&lt;br /&gt;
&lt;br /&gt;
[[file:parallel1600.jpg|thumb|center|700px|Рисунок 2. Изменение производительности в зависимости от числа процессоров при размере матрицы 1600х1600.]]&lt;br /&gt;
&lt;br /&gt;
За &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; принята производительность при одном процессе.&lt;br /&gt;
Как видно, производительность резко увеличивается при добавлении числа потоков в начале и снижается при дальнейшем добавлении.&lt;br /&gt;
Это связано с тем, что в одном потоке совершается малое количество арифметических операций. После выполнения операций совершается запись в массив полученных значений, в результате чего возникает конфликт потоков.&lt;br /&gt;
Поэтому наиболее оптимальное число потоков &amp;lt;math&amp;gt;8-16&amp;lt;/math&amp;gt;, что говорит о слабой масштабируемости данного алгоритма.&lt;br /&gt;
&lt;br /&gt;
[http://pastebin.com/yUyh1ziL Параллельная реализация на языке 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;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18860</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18860"/>
		<updated>2016-11-21T19:26:43Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)&amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; операции деления, &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; операции взятия корня, &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции умножения и &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В худшем случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами.&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение 8 ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Кроме вышеизложенного, отметим следующую особенность алгоритма.&lt;br /&gt;
Пусть вращение &amp;lt;math&amp;gt;J_1&amp;lt;/math&amp;gt; изменяет строки и столбцы с номерами &amp;lt;math&amp;gt;j_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k_1&amp;lt;/math&amp;gt;, а вращение &amp;lt;math&amp;gt;J_2&amp;lt;/math&amp;gt; изменяет строки и столбцы с номерами &amp;lt;math&amp;gt;j_2&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k_2&amp;lt;/math&amp;gt;, и при этом выполнено:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;j_1 \neq j_2, k_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;k_1 \neq j_2, k_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тогда вращения &amp;lt;math&amp;gt;J_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;J_2&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;4n&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;
&#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;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&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;A&amp;lt;/math&amp;gt; в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;8&amp;lt;/math&amp;gt; полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма:&lt;br /&gt;
*       число процессоров [1 : 48] с шагом 1&lt;br /&gt;
*       размерность матрицы [400:1600] с шагом 200&lt;br /&gt;
&lt;br /&gt;
Использовался компилятор g++ версии 5.4.0  со следующими флагами: -O2, -fopenmp, -std=c++11. &lt;br /&gt;
Флаг -O2 является опциональным, и означает уровень оптимизации кода при компиляции. Все прочие флаги строго обязательны при компиляции, т.к. в коде используются функции из стандарта С++11.   &lt;br /&gt;
&lt;br /&gt;
[[file:parallel11.jpg|thumb|center|700px|Рисунок 2. Изменение производительности в зависимости от числа процессоров и размерности матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Чтобы продемонстрировать важное свойство алгоритма, приведем так же график производительности в зависимости от числа процессов при размере матрицы 1600*1600&lt;br /&gt;
&lt;br /&gt;
[[file:parallel1600.jpg|thumb|center|700px|Рисунок 2. Изменение производительности в зависимости от числа процессоров при размере матрицы 1600х1600.]]&lt;br /&gt;
&lt;br /&gt;
За &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; принята производительность при одном процессе.&lt;br /&gt;
Как видно, производительность резко увеличивается при добавлении числа потоков в начале и снижается при дальнейшем добавлении.&lt;br /&gt;
Это связано с тем, что в одном потоке совершается малое количество арифметических операций. После выполнения операций совершается запись в массив полученных значений, в результате чего возникает конфликт потоков.&lt;br /&gt;
Поэтому наиболее оптимальное число потоков &amp;lt;math&amp;gt;8-16&amp;lt;/math&amp;gt;, что говорит о слабой масштабируемости данного алгоритма.&lt;br /&gt;
&lt;br /&gt;
[http://pastebin.com/yUyh1ziL Параллельная реализация на языке 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;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18359</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18359"/>
		<updated>2016-11-18T20:58:49Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)&amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; операции деления, &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; операции взятия корня, &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции умножения и &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В худшем случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами.&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&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;A&amp;lt;/math&amp;gt; в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;8&amp;lt;/math&amp;gt; полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма:&lt;br /&gt;
*       число процессоров [1 : 48] с шагом 1&lt;br /&gt;
*       размерность матрицы [400:1600] с шагом 200&lt;br /&gt;
&lt;br /&gt;
[[file:parallel11.jpg|thumb|center|700px|Рисунок 2. Изменение производительности в зависимости от числа процессоров и размерности матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Чтобы продемонстрировать важное свойство алгоритма, приведем так же график производительности в зависимости от числа процессов при размере матрицы 1600*1600&lt;br /&gt;
&lt;br /&gt;
[[file:parallel1600.jpg|thumb|center|700px|Рисунок 2. Изменение производительности в зависимости от числа процессоров при размере матрицы 1600х1600.]]&lt;br /&gt;
&lt;br /&gt;
За &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; принята производительность при одном процессе.&lt;br /&gt;
Как видно, производительность резко увеличивается при добавлении числа потоков в начале и снижается при дальнейшем добавлении.&lt;br /&gt;
Это связано с тем, что в одном потоке совершается малое количество арифметических операций. После выполнения операций совершается запись в массив полученных значений, в результате чего возникает конфликт потоков.&lt;br /&gt;
Поэтому наиболее оптимальное число потоков &amp;lt;math&amp;gt;8-16&amp;lt;/math&amp;gt;, что говорит о слабой масштабируемости данного алгоритма.&lt;br /&gt;
&lt;br /&gt;
[http://pastebin.com/yUyh1ziL Параллельная реализация на языке 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;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18355</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18355"/>
		<updated>2016-11-18T20:57:35Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)&amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; операции деления, &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; операции взятия корня, &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции умножения и &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В худшем случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами.&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&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;A&amp;lt;/math&amp;gt; в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;8&amp;lt;/math&amp;gt; полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма:&lt;br /&gt;
*       число процессоров [1 : 48] с шагом 1&lt;br /&gt;
*       размерность матрицы [400:1600] с шагом 200&lt;br /&gt;
&lt;br /&gt;
[[file:parallel11.jpg|thumb|center|700px|Рисунок 2. Изменение производительности в зависимости от числа процессоров и размерности матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Чтобы продемонстрировать важное свойство алгоритма, приведем так же график производительности в зависимости от числа процессов при размере матрицы 1600*1600&lt;br /&gt;
&lt;br /&gt;
[[file:parallel1600.jpg|thumb|center|700px|Рисунок 2. Изменение производительности в зависимости от числа процессоров при размере матрицы 1600х1600.]]&lt;br /&gt;
&lt;br /&gt;
За &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; принята производительность при одном процессе.&lt;br /&gt;
Как видно, производительность резко увеличивается при добавлении числа потоков в начале и снижается при дальнейшем добавлении.&lt;br /&gt;
Это связано с тем, что в одном потоке совершается малое количество арифметических операций. После выполнения операций совершается запись в массив полученных значений, в результате чего возникает конфликт потоков.&lt;br /&gt;
Поэтому наиболее оптимальное число потоков &amp;lt;math&amp;gt;8-16&amp;lt;/math&amp;gt;, что говорит о слабой масштабируемости данного алгоритма.&lt;br /&gt;
&lt;br /&gt;
[http://pastebin.com/yUyh1ziL Параллельная реализация на языке 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;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18338</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18338"/>
		<updated>2016-11-18T20:53:37Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)&amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; операции деления, &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; операции взятия корня, &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции умножения и &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В худшем случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами.&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&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;A&amp;lt;/math&amp;gt; в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;8&amp;lt;/math&amp;gt; полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма:&lt;br /&gt;
*       число процессоров [1 : 48] с шагом 1&lt;br /&gt;
*       размерность матрицы [400:1600] с шагом 200&lt;br /&gt;
&lt;br /&gt;
[[file:parallel11.jpg|thumb|center|700px|Рисунок 2. Изменение производительности в зависимости от числа процессоров и размерности матрицы.]]&lt;br /&gt;
&lt;br /&gt;
Чтобы продемонстрировать важное свойство алгоритма, приведем так же график производительности в зависимости от числа процессов при размере матрицы 1600*1600&lt;br /&gt;
&lt;br /&gt;
[[file:parallel1600.jpg|thumb|center|700px|Рисунок 2. Изменение производительности в зависимости от числа процессоров при размере матрицы 1600х1600.]]&lt;br /&gt;
&lt;br /&gt;
За &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt; принята производительность при одном процессе.&lt;br /&gt;
Как видно, производительность резко увеличивается при добавлении числа потоков в начале и снижается при дальнейшем добавлении.&lt;br /&gt;
Это связано с тем, что в одном потоке совершается малое количество арифметических операций. После выполнения операций совершается запись в массив полученных значений, в результате чего возникает конфликт потоков.&lt;br /&gt;
Поэтому наиболее оптимальное число потоков 12-16, что говорит о слабой масштабируемости данного алгоритма.&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18325</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18325"/>
		<updated>2016-11-18T20:49:02Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)&amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; операции деления, &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; операции взятия корня, &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции умножения и &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В худшем случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами.&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&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;A&amp;lt;/math&amp;gt; в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;8&amp;lt;/math&amp;gt; полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма:&lt;br /&gt;
*       число процессоров [1 : 48] с шагом 1&lt;br /&gt;
*       размерность матрицы [400:1600] с шагом 200&lt;br /&gt;
&lt;br /&gt;
[[file:parallel11.jpg|thumb|center|700px|Рисунок 2. Изменение производительности в зависимости от числа процессоров и размерности матрицы.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18324</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18324"/>
		<updated>2016-11-18T20:48:44Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)&amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; операции деления, &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; операции взятия корня, &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции умножения и &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В худшем случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами.&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&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;A&amp;lt;/math&amp;gt; в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;8&amp;lt;/math&amp;gt; полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма:&lt;br /&gt;
*       число процессоров [1 : 48] с шагом 1&lt;br /&gt;
*       размерность матрицы [400:1600] с шагом 200&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18316</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18316"/>
		<updated>2016-11-18T20:44:27Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)&amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; операции деления, &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; операции взятия корня, &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции умножения и &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В худшем случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами.&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&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;A&amp;lt;/math&amp;gt; в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;8&amp;lt;/math&amp;gt; полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма:&lt;br /&gt;
*       число процессоров [1 : 48] с шагом 1&lt;br /&gt;
*       размерность матрицы [400:1600] с шагом 200&lt;br /&gt;
&lt;br /&gt;
[[file:parallel11.jpg|thumb|center|700px|Рисунок 2. Изменение производительности в зависимости от числа процессоров и размерности матрицы.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18312</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18312"/>
		<updated>2016-11-18T20:43:04Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)&amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; операции деления, &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; операции взятия корня, &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции умножения и &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В худшем случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами.&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&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;A&amp;lt;/math&amp;gt; в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;8&amp;lt;/math&amp;gt; полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
Исследование проводилось на 1U сервере со следующими характеристиками:&lt;br /&gt;
*	2 x Intel® Xeon® Processor E5-2697 v2;&lt;br /&gt;
*	128GB RAM;&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма:&lt;br /&gt;
*       число процессоров [1 : 48] с шагом 1&lt;br /&gt;
*       размерность матрицы [400:1600] с шагом 200&lt;br /&gt;
&lt;br /&gt;
[[file:parallel.jpg|thumb|center|700px|Рисунок 2. Изменение производительности в зависимости от числа процессоров и размерности матрицы.]]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18246</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18246"/>
		<updated>2016-11-18T19:01:17Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)&amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; операции деления, &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; операции взятия корня, &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции умножения и &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В худшем случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами.&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&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;A&amp;lt;/math&amp;gt; в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;8&amp;lt;/math&amp;gt; полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18245</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18245"/>
		<updated>2016-11-18T19:00:47Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)&amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; операции деления, &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; операции взятия корня, &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции умножения и &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В худшем случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами.&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&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;A&amp;lt;/math&amp;gt; в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18243</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18243"/>
		<updated>2016-11-18T18:57:08Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)&amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; операции деления, &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; операции взятия корня, &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции умножения и &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В худшем случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами.&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Отдельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18242</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18242"/>
		<updated>2016-11-18T18:54:47Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)&amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; операции деления, &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; операции взятия корня, &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции умножения и &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В худшем случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами.&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18239</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18239"/>
		<updated>2016-11-18T18:53:08Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)&amp;lt;math&amp;gt;3&amp;lt;/math&amp;gt; операции деления, &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; операции взятия корня, &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции умножения и &amp;lt;math&amp;gt;4&amp;lt;/math&amp;gt; операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В худшем случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18236</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18236"/>
		<updated>2016-11-18T18:48:49Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18053</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18053"/>
		<updated>2016-11-18T08:43:59Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;2&amp;lt;/math&amp;gt; строки и &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; столбца, что означает изменение &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов. Отметим, что вычисление нового значения одного элемента требует &amp;lt;math&amp;gt;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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18052</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=18052"/>
		<updated>2016-11-18T08:42:29Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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; при применении поворота Якоби. Конкретно, изменяются 2 строки и 2 столбца, что означает изменение 4n элементов. Отметим, что вычисление нового значения одного элемента требует 2 операции умножения и одну операцию сложения, что позволяет утверждать, что основной вклад в вычислительное ядро вносят умножения. &lt;br /&gt;
Однако в целом, следует отметить, что число операций в алгоритме во многом определяется общим числом итераций, а оно квадратично, в то время как отдельная итерация имеет линейную сложность. Более того, так как алгоритм является итерационным и останавливается при достижении некоторой точности, число итераций может изменяться в зависимости от желаемой точности.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На макроуровне имеет смысл выделять следующие блоки алгоритма: &lt;br /&gt;
&lt;br /&gt;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=17996</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=17996"/>
		<updated>2016-11-17T19:23:28Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;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;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a+{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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; при применении поворота Якоби. Конкретно, изменяются 2 строки и 2 столбца, что означает изменение 4n элементов. Отметим, что вычисление нового значения одного элемента требует 2 операции умножения и одну операцию сложения, что позволяет утверждать, что основной вклад в вычислительное ядро вносят умножения. &lt;br /&gt;
Однако в целом, следует отметить, что число операций в алгоритме во многом определяется общим числом итераций, а оно квадратично, в то время как отдельная итерация имеет линейную сложность. Более того, так как алгоритм является итерационным и останавливается при достижении некоторой точности, число итераций может изменяться в зависимости от желаемой точности.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На макроуровне имеет смысл выделять следующие блоки алгоритма: &lt;br /&gt;
&lt;br /&gt;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=17995</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=17995"/>
		<updated>2016-11-17T19:22:37Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a+{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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; при применении поворота Якоби. Конкретно, изменяются 2 строки и 2 столбца, что означает изменение 4n элементов. Отметим, что вычисление нового значения одного элемента требует 2 операции умножения и одну операцию сложения, что позволяет утверждать, что основной вклад в вычислительное ядро вносят умножения. &lt;br /&gt;
Однако в целом, следует отметить, что число операций в алгоритме во многом определяется общим числом итераций, а оно квадратично, в то время как отдельная итерация имеет линейную сложность. Более того, так как алгоритм является итерационным и останавливается при достижении некоторой точности, число итераций может изменяться в зависимости от желаемой точности.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На макроуровне имеет смысл выделять следующие блоки алгоритма: &lt;br /&gt;
&lt;br /&gt;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=17967</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=17967"/>
		<updated>2016-11-17T17:36:38Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a+{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a_{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a_{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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; при применении поворота Якоби. Конкретно, изменяются 2 строки и 2 столбца, что означает изменение 4n элементов. Отметим, что вычисление нового значения одного элемента требует 2 операции умножения и одну операцию сложения, что позволяет утверждать, что основной вклад в вычислительное ядро вносят умножения. &lt;br /&gt;
Однако в целом, следует отметить, что число операций в алгоритме во многом определяется общим числом итераций, а оно квадратично, в то время как отдельная итерация имеет линейную сложность. Более того, так как алгоритм является итерационным и останавливается при достижении некоторой точности, число итераций может изменяться в зависимости от желаемой точности.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На макроуровне имеет смысл выделять следующие блоки алгоритма: &lt;br /&gt;
&lt;br /&gt;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p \neq k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=14273</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=14273"/>
		<updated>2016-10-27T20:51:36Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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; при применении поворота Якоби. Конкретно, изменяются 2 строки и 2 столбца, что означает изменение 4n элементов. Отметим, что вычисление нового значения одного элемента требует 2 операции умножения и одну операцию сложения, что позволяет утверждать, что основной вклад в вычислительное ядро вносят умножения. &lt;br /&gt;
Однако в целом, следует отметить, что число операций в алгоритме во многом определяется общим числом итераций, а оно квадратично, в то время как отдельная итерация имеет линейную сложность. Более того, так как алгоритм является итерационным и останавливается при достижении некоторой точности, число итераций может изменяться в зависимости от желаемой точности.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На макроуровне имеет смысл выделять следующие блоки алгоритма: &lt;br /&gt;
&lt;br /&gt;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p!=k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT1.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=14272</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=14272"/>
		<updated>2016-10-27T20:47:46Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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; при применении поворота Якоби. Конкретно, изменяются 2 строки и 2 столбца, что означает изменение 4n элементов. Отметим, что вычисление нового значения одного элемента требует 2 операции умножения и одну операцию сложения, что позволяет утверждать, что основной вклад в вычислительное ядро вносят умножения. &lt;br /&gt;
Однако в целом, следует отметить, что число операций в алгоритме во многом определяется общим числом итераций, а оно квадратично, в то время как отдельная итерация имеет линейную сложность. Более того, так как алгоритм является итерационным и останавливается при достижении некоторой точности, число итераций может изменяться в зависимости от желаемой точности.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На макроуровне имеет смысл выделять следующие блоки алгоритма: &lt;br /&gt;
&lt;br /&gt;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;2n+2&amp;lt;/math&amp;gt; элементов матрицы и &amp;lt;math&amp;gt;2n-2&amp;lt;/math&amp;gt; операций присваивания. На данном ярусе ширина графа достигает максимального значения. Вначале вычисляются значения в строках &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (это соответствует умножению матрицы &amp;lt;math&amp;gt;R^T&amp;lt;/math&amp;gt; на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;). Далее, в силу того, что при умножении результата на матрицу &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; изменяются только столбцы &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и итоговая матрица симметрична, можно не пересчитывать значения в столбцах, а получить их простым присваиванием по формуле: &amp;lt;math&amp;gt;a_{pk}=a_{kp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a_{pj}=a_{jp}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p!=k,j&amp;lt;/math&amp;gt;. Для элементов &amp;lt;math&amp;gt;a_{jj}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;a_{kk}&amp;lt;/math&amp;gt; необходимо произвести вычисления, аналогичные вычислениям для элементов строк. &lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:ROT.png|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=13267</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=13267"/>
		<updated>2016-10-20T14:25:25Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
Авторы: [[Участник:Зиновьев Владимир|Зиновьев В.С.]] (написание кода, информационный граф, общее и мат описание алгоритма), [[Участник:Пронин Андрей|Пронин А.М.]] (написание кода, информационный граф, вычислительное ядро алгоритма, макроструктура алгоритма). В остальные разделы статьи вклад равноценный.&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из внедиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих внедиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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; при применении поворота Якоби. Конкретно, изменяются 2 строки и 2 столбца, что означает изменение 4n элементов. Отметим, что вычисление нового значения одного элемента требует 2 операции умножения и одну операцию сложения, что позволяет утверждать, что основной вклад в вычислительное ядро вносят умножения. &lt;br /&gt;
Однако в целом, следует отметить, что число операций в алгоритме во многом определяется общим числом итераций, а оно квадратично, в то время как отдельная итерация имеет линейную сложность. Более того, так как алгоритм является итерационным и останавливается при достижении некоторой точности, число итераций может изменяться в зависимости от желаемой точности.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На макроуровне имеет смысл выделять следующие блоки алгоритма: &lt;br /&gt;
&lt;br /&gt;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
Канонический вариант:&lt;br /&gt;
&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Вообще говоря, несмотря на то, что поворот, обеспечивающий обнуление наибольшего внедиагонального элемента, обеспечивает схождение метода за наименьшее число итераций, поиск данного наибольшего элемента добавляет порядка &amp;lt;math&amp;gt;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;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций в теории равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&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;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
Если выбирать не наибольший элемент матрицы, а все по очереди, порядок числа итераций сохраняется, но исчезают операции сравнения. Таким образом, итоговая сложность алгоритма будет составлять  &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов матрицы. На данном ярусе ширина графа достигает максимального значения.&lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Rotate.jpg|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *8* ярусов с конечным числом операций сложения, умножения, взятия квадратного корня и нахождения знака.&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
==== Локальность реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
===== Структура обращений в память и качественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
===== Количественная оценка локальности =====&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8575</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8575"/>
		<updated>2016-10-15T00:35:54Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. &amp;lt;ref&amp;gt;Чечин Г.М., Зехцер М.Ю. Собственные значения и собственные векторы матриц&amp;lt;/ref&amp;gt; С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих недиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На отдельной итерации вычислительным ядром является вычисление новых значений элементов матрицы. Конкретно, изменяются 2 строки и 2 столбца матрицы.&lt;br /&gt;
Однако в целом, можно отметить, что число операций в алгоритме во многом определяется общую числом итераций, а оно квадратично, в то время как отдельная итерация имеет линейную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На макроуровне имеет смысл выделять следующие блоки алгоритма: &lt;br /&gt;
&lt;br /&gt;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(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;
1)Последовательно идущие макроярусы вычисления параметров текущей итерации и вращения Якоби с этими параметрами&lt;br /&gt;
Число данных ярусов варьируется в зависимости от входных данных, но порядок составляет &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
2)Вычисление параметров текущей итерации содержит конечное число операций умножения, сложения и вычисления квадратного корня.&lt;br /&gt;
&lt;br /&gt;
3)Макроярус вращения Якоби содержит вычисление &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; элементов матрицы. На данном ярусе ширина графа достигает максимального значения.&lt;br /&gt;
&lt;br /&gt;
Визуальное представление графа алгоритма представлено на схемах ниже:  &lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Rotate.jpg|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *число_ярусов* ярусов с конечным числом операций&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&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;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
3)&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8571</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8571"/>
		<updated>2016-10-15T00:32:15Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих недиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;Дж. Деммель, Вычислительная линейная алгебра. Теория и приложения. Перевод Х.Д.Икрамов&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На отдельной итерации вычислительным ядром является вычисление новых значений элементов матрицы. Конкретно, изменяются 2 строки и 2 столбца матрицы.&lt;br /&gt;
Однако в целом, можно отметить, что число операций в алгоритме во многом определяется общую числом итераций, а оно квадратично, в то время как отдельная итерация имеет линейную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На макроуровне имеет смысл выделять следующие блоки алгоритма: &lt;br /&gt;
&lt;br /&gt;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Rotate.jpg|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *число_ярусов* ярусов с конечным числом операций&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&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;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
3)&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8569</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8569"/>
		<updated>2016-10-15T00:30:22Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих недиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; &amp;lt;ref&amp;gt;плплп&amp;lt;/ref&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На отдельной итерации вычислительным ядром является вычисление новых значений элементов матрицы. Конкретно, изменяются 2 строки и 2 столбца матрицы.&lt;br /&gt;
Однако в целом, можно отметить, что число операций в алгоритме во многом определяется общую числом итераций, а оно квадратично, в то время как отдельная итерация имеет линейную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На макроуровне имеет смысл выделять следующие блоки алгоритма: &lt;br /&gt;
&lt;br /&gt;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Rotate.jpg|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *число_ярусов* ярусов с конечным числом операций&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&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;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
3)&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8568</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8568"/>
		<updated>2016-10-15T00:26:24Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих недиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На отдельной итерации вычислительным ядром является вычисление новых значений элементов матрицы. Конкретно, изменяются 2 строки и 2 столбца матрицы.&lt;br /&gt;
Однако в целом, можно отметить, что число операций в алгоритме во многом определяется общую числом итераций, а оно квадратично, в то время как отдельная итерация имеет линейную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На макроуровне имеет смысл выделять следующие блоки алгоритма: &lt;br /&gt;
&lt;br /&gt;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Rotate.jpg|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *число_ярусов* ярусов с конечным числом операций&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&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;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится [http://ieeexplore.ieee.org/document/6310877/ аннотация] статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA.&lt;br /&gt;
&lt;br /&gt;
3)&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8565</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8565"/>
		<updated>2016-10-15T00:23:51Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Литература */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих недиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На отдельной итерации вычислительным ядром является вычисление новых значений элементов матрицы. Конкретно, изменяются 2 строки и 2 столбца матрицы.&lt;br /&gt;
Однако в целом, можно отметить, что число операций в алгоритме во многом определяется общую числом итераций, а оно квадратично, в то время как отдельная итерация имеет линейную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На макроуровне имеет смысл выделять следующие блоки алгоритма: &lt;br /&gt;
&lt;br /&gt;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Rotate.jpg|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *число_ярусов* ярусов с конечным числом операций&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&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;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится аннотация статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA(Здесь должна быть ссылка).&lt;br /&gt;
&lt;br /&gt;
3)&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8557</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8557"/>
		<updated>2016-10-15T00:19:02Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих недиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На отдельной итерации вычислительным ядром является вычисление новых значений элементов матрицы. Конкретно, изменяются 2 строки и 2 столбца матрицы.&lt;br /&gt;
Однако в целом, можно отметить, что число операций в алгоритме во многом определяется общую числом итераций, а оно квадратично, в то время как отдельная итерация имеет линейную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На макроуровне имеет смысл выделять следующие блоки алгоритма: &lt;br /&gt;
&lt;br /&gt;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Rotate.jpg|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *число_ярусов* ярусов с конечным числом операций&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&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;
1)Библиотека [https://people.sc.fsu.edu/~jburkardt/f_src/jacobi_eigenvalue/jacobi_eigenvalue.html JACOBI_EIGENVALUE] содержит последовательную реализацию алгоритма.&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится аннотация статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA(Здесь должна быть ссылка).&lt;br /&gt;
&lt;br /&gt;
3)&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8555</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8555"/>
		<updated>2016-10-15T00:17:05Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих недиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На отдельной итерации вычислительным ядром является вычисление новых значений элементов матрицы. Конкретно, изменяются 2 строки и 2 столбца матрицы.&lt;br /&gt;
Однако в целом, можно отметить, что число операций в алгоритме во многом определяется общую числом итераций, а оно квадратично, в то время как отдельная итерация имеет линейную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На макроуровне имеет смысл выделять следующие блоки алгоритма: &lt;br /&gt;
&lt;br /&gt;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Rotate.jpg|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *число_ярусов* ярусов с конечным числом операций&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&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;
1)&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится аннотация статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA(Здесь должна быть ссылка).&lt;br /&gt;
&lt;br /&gt;
3)&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8550</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8550"/>
		<updated>2016-10-15T00:15:13Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих недиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&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;&lt;br /&gt;
J_i = &lt;br /&gt;
\begin{matrix}&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
j \\&lt;br /&gt;
  \\&lt;br /&gt;
k \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
  \\&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;  &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp; &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 \\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На отдельной итерации вычислительным ядром является вычисление новых значений элементов матрицы. Конкретно, изменяются 2 строки и 2 столбца матрицы.&lt;br /&gt;
Однако в целом, можно отметить, что число операций в алгоритме во многом определяется общую числом итераций, а оно квадратично, в то время как отдельная итерация имеет линейную сложность.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
На макроуровне имеет смысл выделять следующие блоки алгоритма: &lt;br /&gt;
&lt;br /&gt;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Rotate.jpg|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *число_ярусов* ярусов с конечным числом операций&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&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;
1)&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится аннотация статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA(Здесь должна быть ссылка).&lt;br /&gt;
&lt;br /&gt;
3)&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8537</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8537"/>
		<updated>2016-10-15T00:04:17Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2n&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих недиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv \begin{bmatrix}&lt;br /&gt;
  1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp;  &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp;  &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp;   &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Rotate.jpg|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *число_ярусов* ярусов с конечным числом операций&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&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;
1)&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится аннотация статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA(Здесь должна быть ссылка).&lt;br /&gt;
&lt;br /&gt;
3)&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8525</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8525"/>
		<updated>2016-10-14T23:57:54Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Симметричность и положительная определённость матрицы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2*n&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих недиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv \begin{bmatrix}&lt;br /&gt;
  1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp;  &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp;  &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp;   &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Rotate.jpg|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *число_ярусов* ярусов с конечным числом операций&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&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;
1)&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится аннотация статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA(Здесь должна быть ссылка).&lt;br /&gt;
&lt;br /&gt;
3)&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8524</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8524"/>
		<updated>2016-10-14T23:57:17Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2*n&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих недиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность и положительная определённость матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv \begin{bmatrix}&lt;br /&gt;
  1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp;  &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp;  &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp;   &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[file:Rotate.jpg|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *число_ярусов* ярусов с конечным числом операций&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&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;
1)&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится аннотация статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA(Здесь должна быть ссылка).&lt;br /&gt;
&lt;br /&gt;
3)&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8522</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8522"/>
		<updated>2016-10-14T23:56:13Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2*n&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих недиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность и положительная определённость матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv \begin{bmatrix}&lt;br /&gt;
  1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp;  &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp;  &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp;   &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;
1) Блок вычисления параметров вращения на текущей итерации (выбор обнуляемого элемента и расчет угла вращения).&lt;br /&gt;
&lt;br /&gt;
2)Блок, реализующий непосредственно вращение Якоби.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(N^3)&amp;lt;/math&amp;gt; сложений и умножений.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
[[file:SI.jpg|thumb|center|1400px|Рисунок 1. Граф алгоритма на макроуровне. Rarams - вычисление параметров, Rotate - получение &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; из &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt;.]]&lt;br /&gt;
&lt;br /&gt;
[[file:exec_params.jpg|thumb|center|1400px|Рисунок 2. Структура блока Params.]]&lt;br /&gt;
&lt;br /&gt;
[[file:Rotate.jpg|thumb|center|1400px|Рисунок 3. Структура блока Rotate.]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *число_ярусов* ярусов с конечным числом операций&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&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;
1)&lt;br /&gt;
&lt;br /&gt;
2)В цифровой библиотеке ieee.org приводится аннотация статьи 2012 года, в которой авторы описывают реализацию данного алгоритма на CUDA(Здесь должна быть ссылка).&lt;br /&gt;
&lt;br /&gt;
3)&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8506</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=8506"/>
		<updated>2016-10-14T23:45:46Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(n^3)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;2*n&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;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира.Кроме того, данная проблема важна в теории автоматического управления, как инструмент исследования устойчивости линейных систем.&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых обнуляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих недиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность и положительная определённость матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv \begin{bmatrix}&lt;br /&gt;
  1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp;  &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp;  &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp;   &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(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;
Как видно из представления алгоритма в ярусно-параллельной форме ([[#Информационный граф| п.1.7]]), максимальная ширина ярусов составляет &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; вершин.&lt;br /&gt;
Для выполнения данного алгоритма в параллельном варианте следует выполнить &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&amp;lt;/math&amp;gt; итераций.&lt;br /&gt;
Рассмотрим отдельную итерацию с точки зрения ярусно-параллельной формы алгоритма.&lt;br /&gt;
&lt;br /&gt;
1)Выполнение *число_ярусов* ярусов с конечным числом операций&lt;br /&gt;
&lt;br /&gt;
2)Выполнение 2 ярусов вычисления элементов в изменяемых строках и столбцах.&lt;br /&gt;
&lt;br /&gt;
На данных двух ярусах осуществляется &amp;lt;math&amp;gt;4n&amp;lt;/math&amp;gt; умножений и &amp;lt;math&amp;gt;2n&amp;lt;/math&amp;gt; сложений. Данный вид параллелизма относится к координатному. Так как каждая последующая итерация алгоритма зависит от предыдущей, их выполнение распараллелить не представляется возможным. Таким образом, при наличии бесконечного числа процессоров, итоговая сложность алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2})&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;a_{ij}&amp;lt;/math&amp;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Параллельная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Последовательная сложность выполнения алгоритма составляет &amp;lt;math&amp;gt;O(\frac{n^2(n+1)}{2}).&amp;lt;/math&amp;gt;&lt;br /&gt;
Таким образом, соотношение сложностей является линейным.&lt;br /&gt;
Более того, и вычислительная мощность данного алгоритма линейна.&lt;br /&gt;
&lt;br /&gt;
В алгоритме используется примерно в два раза больше операций умножения, чем сложения.&lt;br /&gt;
Одельно стоит рассмотреть вопрос хранения матрицы А в процессе работы алгоритма. Хранение лишь нижней или верхней части матрицы в виде одномерного массива возможно; более того, хранение в таком виде обеспечивает экономию памяти в 2 раза и защищает от ассиметричности матрицы в результате накопления математических ошибок. Однако, вычисление индексов &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; элементов &amp;lt;math&amp;gt;a_{ij}&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;
1)Несмотря на то, что выбор наибольшего наддиагонального элемента, как кандидата на обнуление, кажется оптимальным, на самом деле он таковым не является. При таком выборе элемента, на каждой итерации необходимо находить текущий наибольший элемент в матрице, что требует дополнительных &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; операций сравнения и приводит к увеличению сложности алгоритма до &amp;lt;math&amp;gt;O(n^4)&amp;lt;/math&amp;gt;. Вместо этого рекомендуется перебирать по очереди все наддиагональные элементы, большие заданного параметра. В большинстве случаев от 4 до 8 полных проходов достаточно для приближения исходной матрицы к диагональной.&lt;br /&gt;
&lt;br /&gt;
2)Если при выборе в качестве обнуляемого элемента &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt; элементы &amp;lt;math&amp;gt;a_{ii} = a_{jj}&amp;lt;/math&amp;gt;, то, как видно из формул в пунктах выше, матрицы поворота вырождаются в единичные и матрица на данной итерации не изменяется. Это еще один довод в пользу отказа от выбора наибольшего элемента, т.к. в данном случае произойдет зацикливание алгоритма.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=6018</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=6018"/>
		<updated>2016-10-12T19:53:09Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира. Действительно, согласно одному из основных положений квантовой механики, все наблюдаемые величины (т.е. величины, которые могут быть измерены в результате проведения конкретных физических экспериментов) суть собственные значения некоторых бесконечномерных эрмитовых матриц (эрмитовых операторов).&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых зануляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих недиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность и положительная определённость матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv \begin{bmatrix}&lt;br /&gt;
  1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp;  &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp;  &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp;   &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(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;
&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;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;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>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=6017</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=6017"/>
		<updated>2016-10-12T19:52:11Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира. Действительно, согласно одному из основных положений квантовой механики, все наблюдаемые величины (т.е. величины, которые могут быть измерены в результате проведения конкретных физических экспериментов) суть собственные значения некоторых бесконечномерных эрмитовых матриц (эрмитовых операторов).\\&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых зануляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными. Число шагов, за которое матрица A приводится таким способом к диагональной форме, в общем случае является бесконечным. (это свойство метода Якоби более подробно рассмотрено в разделе &amp;quot;[[#Свойства алгоритма|Свойства алгоритма]]&amp;quot;) В результате метод Якоби представляет собой некоторый бесконечный итерационный процесс, на каждом шаге которого преобразующаяся матрица становится всё более и более близкой к диагональной форме (в смысле уменьшения суммы квадратов всех своих недиагональных элементов). На практике обычно выбирается заранее заданная погрешность &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; и процесс приведения исходной матрицы к диагональному виду прекращается, когда наибольший по модулю внедиагональный элемент матрицы становится меньше &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt;. Таким образом, применяя на практике метод Якоби, мы приводим исходную матрицу к диагональной форме с точностью до некоторой вычислительной погрешности &amp;lt;math&amp;gt;\varepsilon&amp;lt;/math&amp;gt; в результате конечного числа шагов. Повышение этой точности требует увеличения числа шагов метода Якоби. В конечном итоге у полученной в результате этого процесса матрицы на диагонали будут находиться все собственные значения (с определённой погрешностью) исходной симметрической матрицы.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Симметричность и положительная определённость матрицы ====&lt;br /&gt;
&lt;br /&gt;
Симметричность матрицы позволяет хранить и вычислять только чуть больше половины её элементов, что почти вдвое экономит как необходимые для вычислений объёмы памяти, так и количество операций в сравнении с, например, разложением по методу Гаусса.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv \begin{bmatrix}&lt;br /&gt;
  1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp;  &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp;  &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp;   &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(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;
&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;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;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>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=6012</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=6012"/>
		<updated>2016-10-12T19:40:58Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира. Действительно, согласно одному из основных положений квантовой механики, все наблюдаемые величины (т.е. величины, которые могут быть измерены в результате проведения конкретных физических экспериментов) суть собственные значения некоторых бесконечномерных эрмитовых матриц (эрмитовых операторов).&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых зануляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты &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;k&amp;lt;/math&amp;gt;. При таком шаге матрица &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; отличается от матрицы &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; лишь элементами двух строк с номерами &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; и двух столбцов с теми же номерами (&amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;). Все же другие элементы матрицы A остаются неизменными.&lt;br /&gt;
&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;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv \begin{bmatrix}&lt;br /&gt;
  1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp;  &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp;  &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp;   &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(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;
&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;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;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>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=5944</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=5944"/>
		<updated>2016-10-12T18:43:45Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод Якоби вычисления собственных значений симметричной матрицы ЗП&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира. Действительно, согласно одному из основных положений квантовой механики, все наблюдаемые величины (т.е. величины, которые могут быть измерены в результате проведения конкретных физических экспериментов) суть собственные значения некоторых бесконечномерных эрмитовых матриц (эрмитовых операторов).&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых зануляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты n-мерных векторов, а именно, координаты с номерами i0 и j0. При таком шаге матрица Aнов отличается от матрицы Aст лишь элементами двух строк с номерами i0, j0 и двух столбцов с&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;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv \begin{bmatrix}&lt;br /&gt;
  1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp;  &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp;  &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp;   &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(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;
&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;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;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>Зиновьев Владимир</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Lineprinter&amp;diff=5943</id>
		<title>Обсуждение участника:Lineprinter</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA%D0%B0:Lineprinter&amp;diff=5943"/>
		<updated>2016-10-12T18:42:57Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Перенос */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Перенос ==&lt;br /&gt;
&lt;br /&gt;
Статья:[[ЕМ-алгоритм_(Тематическое_моделирование)]];&lt;br /&gt;
Выполняют: Мурат Апишев и Андрей Заночкин&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_Ланцоша_с_полной_переортогонализацией]];&lt;br /&gt;
Выполняет:[[Участник:Sfedotov| Федотов С.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм_k-средних]]&lt;br /&gt;
Выполняют: [[Участник:Error2407|Богомазов Евгений]], [[Участник:Илья_Егоров|Егоров Илья]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Решение_задачи_Коши_для_системы_ОДУ_методом_Рунге-Кутты_4_порядка]];&lt;br /&gt;
Выполняют: [[Участник:Алимов_Дамир_Алиевич|Алимов Дамир]] и [[Участник:Лесничий_Антон_Андреевич|Антон Лесничий]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм кластеризации, основанный на минимальном остовном дереве]];&lt;br /&gt;
Выполняет: Стандрик Антон Сергеевич (Astandrik)&lt;br /&gt;
&lt;br /&gt;
Статья: [[Нахождение_собственных_чисел_квадратной_матрицы_методом_QR_разложения_(3)|Нахождение собственных чисел квадратной матрицы методом QR разложения (3)]];&lt;br /&gt;
Выполняют: [[Участник:Смирнова_Александра|Смирнова А.С.]], [[Участник:Александра_Киямова|Киямова А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод_Якоби_вычисления_сингулярных_чисел_и_векторов]];&lt;br /&gt;
Выполняют: [[Участница:Почернина_Елена| Почернина Елена]] и [[Участница:Светлана|Костюкова Светлана]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод_Ньютона_для_решения_систем_нелинейных_уравнений(2)]];&lt;br /&gt;
Выполняют: [[Участник:Oleggium|Гирняк О.Р.]], [[Участник:Dimx19|Васильков Д.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Алгоритм_кластеризации_с_использованием_представлений]];&lt;br /&gt;
Выполняют: [[Участник:Cookie|Шатков С.А.]], [[Антохина Ю.А.]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Быстрое_преобразование_Фурье_(FFT)|Быстрое преобразование Фурье (FFT)]];&lt;br /&gt;
Выполняют: [[Участник:Victoria_Stepanischeva|Степанищева Виктория]] и [[Участник:Igor_Munkin|Мунькин Игорь]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Быстрое_дискретное_преобразование_Фурье|Быстрое_дискретное_преобразование_Фурье]];&lt;br /&gt;
Выполняют: [[Участник:ivanov.kir.m | К.М.Иванов]], [[Участник:Pumpkin | А.C.Сапин]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_k_средних]]&lt;br /&gt;
Выполняют: [[Участник:Parkhomenko|Пархоменко Павел]], [[Участник:ivan.mashonskiy|Машонский Иван]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[EM-алгоритм кластеризации]]&lt;br /&gt;
Выполняет: [[Участник:Noite|Зинченко Дмитрий]]&lt;br /&gt;
&lt;br /&gt;
Статья:[[Алгоритм_k_means]]&lt;br /&gt;
Выполняют: [[Участник:IanaV| Валуйская Яна]], [[Глотов Евгений]]&lt;br /&gt;
&lt;br /&gt;
Статья: [[Метод Якоби вычисления собственных значений симметричной матрицы ЗП |Метод Якоби вычисления собственных значений симметричной матрицы ЗП]];&lt;br /&gt;
Выполняют: [[Участник:Зиновьев Владимир|Зиновьев В.С.]], [[Участник:Пронин Андрей|Пронин А.М.]]&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=5939</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=5939"/>
		<updated>2016-10-12T18:36:57Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Разложение Холецкого&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира. Действительно, согласно одному из основных положений квантовой механики, все наблюдаемые величины (т.е. величины, которые могут быть измерены в результате проведения конкретных физических экспериментов) суть собственные значения некоторых бесконечномерных эрмитовых матриц (эрмитовых операторов).&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых зануляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения &amp;lt;math&amp;gt;J_{i}&amp;lt;/math&amp;gt; (подробное описание матрицы плоского вращения приведено ниже в разделе &amp;quot;[[#Математическое описание алгоритма|Математическое описание алгоритма]]&amp;quot;), которая изменяет лишь две координаты n-мерных векторов, а именно, координаты с номерами i0 и j0. При таком шаге матрица Aнов отличается от матрицы Aст лишь элементами двух строк с номерами i0, j0 и двух столбцов с&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;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv \begin{bmatrix}&lt;br /&gt;
  1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp;  &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp;  &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp;   &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(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;
&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;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;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>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=5918</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=5918"/>
		<updated>2016-10-12T18:24:22Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Разложение Холецкого&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Задача нахождения собственных значений и собственных векторов матриц(СЗВМ) является одной из основных задач для многих разделов физики. С такой вычислительной проблемой приходится сталкиваться, например, при исследовании собственных колебаний различных механических систем, колебательных и электронных спектров молекул и кристаллов. Совершенно принципиальное значение эта проблема приобрела после создания в тридцатых годах прошлого века квантовой механики, которая стала базовой дисциплиной исследования микромира. Действительно, согласно одному из основных положений квантовой механики, все наблюдаемые величины (т.е. величины, которые могут быть измерены в результате проведения конкретных физических экспериментов) суть собственные значения некоторых бесконечномерных эрмитовых матриц (эрмитовых операторов).&lt;br /&gt;
Метод Якоби приводит симметричную действительную матрицу к диагональной форме с помощью некоторой (в принципе, бесконечной) последовательности плоских вращений в разных плоскостях исходного n-мерного векторного пространства. Метод Якоби состоит из некоторой последовательности шагов, на каждом из которых зануляется один из недиагональных элементов (обычно наибольший по модулю), в результате чего старая матрица &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; преобразуется в некоторую новую матрицу &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt;. Делается это с помощью преобразования подобия, использующего матрицу плоского вращения Ui0j0, которая изменяет лишь две координаты n-мерных векторов, а именно, координаты с номерами i0 и j0. При таком шаге матрица Aнов отличается от матрицы Aст лишь элементами двух строк с номерами i0, j0 и двух столбцов с&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;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv \begin{bmatrix}&lt;br /&gt;
  1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp;  &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp;  &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp;   &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(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;
&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;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;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>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80&amp;diff=5899</id>
		<title>Участник:Зиновьев Владимир</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80&amp;diff=5899"/>
		<updated>2016-10-12T17:34:53Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: Новая страница: «Студент группы 618/2 ВМК МГУ.»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Студент группы 618/2 ВМК МГУ.&lt;/div&gt;</summary>
		<author><name>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=5510</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=5510"/>
		<updated>2016-10-11T21:24:37Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Разложение Холецкого&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&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;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv \begin{bmatrix}&lt;br /&gt;
  1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp;  &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp;  &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp;   &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign(r)}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(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;
&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;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;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>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=5505</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=5505"/>
		<updated>2016-10-11T21:22:30Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Разложение Холецкого&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&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;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv \begin{bmatrix}&lt;br /&gt;
  1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp;  &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp;  &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp;   &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;c = \cos(\theta)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s = sin(\theta)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;a^{i}_{lk} = a_{lk}&amp;lt;/math&amp;gt;. Тогда из предыдущего равенства получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a_{jj}c^2 + a_{kk}s^2+2sca_{jk}&amp;amp;sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)\\&lt;br /&gt;
sc(a_{kk} - a{jj}) + a_{jk}(c^2-s^2)&amp;amp;a_{jj}s^2 + a_{kk}c^2-2sca_{jk}\\&lt;br /&gt;
\end{bmatrix} &lt;br /&gt;
 .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Приравнивая внедиагональный элемент к нулю, получаем&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\frac{a_{jj} - a{kk}}{2a_{jk}} = \frac{c^2-s^2}{2sc} = ctg(2\theta) = r.&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Пусть &amp;lt;math&amp;gt;tg(\theta) = t = \frac{s}{c}&amp;lt;/math&amp;gt; . Заметим, что выполняется квадратное уравнение &amp;lt;math&amp;gt;t^2 + 2rt - 1 = 0&amp;lt;/math&amp;gt; . Решая уравнение, получаем &amp;lt;math&amp;gt;t = \frac{sign{r}}{|r| + \sqrt{1+r^2}}&amp;lt;/math&amp;gt; . Следовательно &amp;lt;math&amp;gt;c = \frac{1}{\sqrt{1+t^2}}&amp;lt;/math&amp;gt;,  &amp;lt;math&amp;gt;s = ct&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;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(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;
&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;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;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>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=5405</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=5405"/>
		<updated>2016-10-11T17:20:58Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Разложение Холецкого&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&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;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i ,&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;. Таким образом,&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{m}=J^{T}_{m-1}A_{m-1}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}J^{T}_{m-2}A_{m-2}J_{m-2}J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}_{m-1}...J^{T}_{0}A_{0}J_{0}...J_{m-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
        &amp;lt;math&amp;gt;=J^{T}AJ&amp;lt;/math&amp;gt;&lt;br /&gt;
При подходящем выборе вращений &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; матрица &amp;lt;math&amp;gt;A_m&amp;lt;/math&amp;gt; для больших &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; будет близкой к диагональной матрице &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt;. Таким образом, &amp;lt;math&amp;gt;\Lambda \approx J^{T}AJ&amp;lt;/math&amp;gt; или &amp;lt;math&amp;gt;J\Lambda J^{T} \approx A&amp;lt;/math&amp;gt;, следовательно, столбцы матрицы &amp;lt;math&amp;gt;J&amp;lt;/math&amp;gt; являются собственными значениями матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;.&lt;br /&gt;
Матрица &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; выбирается таким образом, чтобы сделать нулями пару внедиагональных элементов матрицы &amp;lt;math&amp;gt;A_{i+1}=J^{T}_{i}A_{i}J_{i}&amp;lt;/math&amp;gt;:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
J_i = R(j,k,\theta) \equiv \begin{bmatrix}&lt;br /&gt;
 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; 1 &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \cos(\theta) &amp;amp;  &amp;amp; -\sin(\theta) &amp;amp; &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp;  &amp;amp; \ddots &amp;amp; &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; \sin(\theta) &amp;amp;   &amp;amp; \cos(\theta) &amp;amp; &amp;amp; &amp;amp; \\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; \ddots &amp;amp; &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1 &amp;amp;\\&lt;br /&gt;
  &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; &amp;amp; 1\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Угол вращения &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; выбирается так, чтобы элементы &amp;lt;math&amp;gt;(j,k)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;(k,j)&amp;lt;/math&amp;gt; в &amp;lt;math&amp;gt;A_{i+1}&amp;lt;/math&amp;gt; стали нулями. Для того, чтобы найти &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;, составляется уравнение:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i+1}_{jj}&amp;amp;a^{i+1}_{jk}\\&lt;br /&gt;
a^{i+1}_{kj}&amp;amp;a^{i+1}_{kk}\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix}^T&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix}&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\cos(\theta)&amp;amp;-\sin(\theta)\\&lt;br /&gt;
\sin(\theta)&amp;amp;\cos(\theta)\\&lt;br /&gt;
\end{bmatrix} = &lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
\lambda_1&amp;amp;0\\&lt;br /&gt;
0&amp;amp;\lambda_2\\&lt;br /&gt;
\end{bmatrix} ,&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
где &amp;lt;math&amp;gt;\lambda_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\lambda_2&amp;lt;/math&amp;gt; - собственные значения подматрицы &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{bmatrix}&lt;br /&gt;
a^{i}_{jj}&amp;amp;a^{i}_{jk}\\&lt;br /&gt;
a^{i}_{kj}&amp;amp;a^{i}_{kk}\\&lt;br /&gt;
\end{bmatrix} .&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(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;
&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;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;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>Зиновьев Владимир</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%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=5245</id>
		<title>Участник:Зиновьев Владимир/Метод Якоби вычисления собственных значений симметричной матрицы ЗП</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:%D0%97%D0%B8%D0%BD%D0%BE%D0%B2%D1%8C%D0%B5%D0%B2_%D0%92%D0%BB%D0%B0%D0%B4%D0%B8%D0%BC%D0%B8%D1%80/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%AF%D0%BA%D0%BE%D0%B1%D0%B8_%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_%D1%81%D0%B8%D0%BC%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%BD%D0%BE%D0%B9_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86%D1%8B_%D0%97%D0%9F&amp;diff=5245"/>
		<updated>2016-10-10T20:15:08Z</updated>

		<summary type="html">&lt;p&gt;Зиновьев Владимир: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Разложение Холецкого&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
&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;A = A_0&amp;lt;/math&amp;gt; — симметричная матрица. В методе Якоби для &amp;lt;math&amp;gt;A_0&amp;lt;/math&amp;gt; строится последовательность ортогонально подобных матриц &amp;lt;math&amp;gt;A_1, A_2,...&amp;lt;/math&amp;gt;, которая в конечном счёте сходится к диагональной матрице, у которой диагональными элементами являются все собственные значения матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. Матрица &amp;lt;math&amp;gt;A_{i}&amp;lt;/math&amp;gt; получается из матрицы &amp;lt;math&amp;gt;A_{i-1}&amp;lt;/math&amp;gt; по формуле&lt;br /&gt;
   &amp;lt;math&amp;gt;A_{i}=J^{T}_iA_{i-1}J_i&amp;lt;/math&amp;gt;&lt;br /&gt;
,где &amp;lt;math&amp;gt;J_i&amp;lt;/math&amp;gt; - ортогональная матрица, называемая &#039;&#039;вращением Якоби&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
1)Находится максимальный наддиагональный элемент &amp;lt;math&amp;gt;a_{jk}&amp;lt;/math&amp;gt; матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
2)Вычисляются параметры вращения Якоби:&lt;br /&gt;
   &amp;lt;math&amp;gt;\tau= \frac{(a_{jj}-a_{kk})}{2a_{jk}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;t=sign(\tau)(|\tau|+\sqrt{1+\tau^2})&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;c= \frac{1}{1+\sqrt{1+\tau^2}}&amp;lt;/math&amp;gt;&lt;br /&gt;
   &amp;lt;math&amp;gt;s=c*t&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3)К текущей матрице А применяются вращения с вычисленными параметрами:&lt;br /&gt;
   &amp;lt;math&amp;gt;A=R^T(j,k,\theta)*A*R(j,k,\theta)&amp;lt;/math&amp;gt;&lt;br /&gt;
Стоит отметить, что вычисленные на предыдущем шаге &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; есть &amp;lt;math&amp;gt;\cos {\theta}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;\sin {\theta}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
&lt;br /&gt;
4)Если матрица А не достаточно близка к диагональной, происходит переход к шагу 1.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что за &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt; итераций алгоритма гарантируется получение результата, т.к. сумма квадратов наддиагональных элементов матрицы А на каждой итерации уменьшается на &amp;lt;math&amp;gt;a_{jk}^2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Сначала оценим сложность одной итерации: &lt;br /&gt;
&lt;br /&gt;
1)Так как элементы матрицы никак не упорядоченны, поиск наибольшего элемента линейно зависит от числа элементов над диагональю.&lt;br /&gt;
Конкретнее, на данном шаге происходит &amp;lt;math&amp;gt;\frac{n*(n-1)}{2} -1&amp;lt;/math&amp;gt; сравнение.&lt;br /&gt;
&lt;br /&gt;
2)3 операции деления, 2 операции взятия корня, 4 операции умножения и 4 операции сложения/вычитания.&lt;br /&gt;
&lt;br /&gt;
3)&amp;lt;math&amp;gt;4*n&amp;lt;/math&amp;gt;  операций умножения и &amp;lt;math&amp;gt;2*n&amp;lt;/math&amp;gt; операций сложения.&lt;br /&gt;
&lt;br /&gt;
4)операция сравнения&lt;br /&gt;
&lt;br /&gt;
В наиболее неудачном случае количество итераций равняется числу наддиагональных элементов, т.е. &amp;lt;math&amp;gt;\frac{n*(n-1)}{2}&amp;lt;/math&amp;gt;.&lt;br /&gt;
Таким образом, суммарная сложность алгоритма составляет &amp;lt;math&amp;gt;O(N^4)&amp;lt;/math&amp;gt; сравнений, и &amp;lt;math&amp;gt;O(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;
&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;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;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; (в силу симметричности достаточно хранить только диагональ и над/поддиагональные элементы). &lt;br /&gt;
Конкретный вариант хранения данных зависит от реализации. В качестве примеров можно привести хранение в одномерном массиве длины &amp;lt;math&amp;gt;\frac{n (n + 1)}{2}&amp;lt;/math&amp;gt; по строкам своей нижней части, хранение в виде так называемого ступенчатого массива (такой вариант двумерного массива, в котором каждая строка имеет свой размер).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: вектор собственных значений &amp;lt;math&amp;gt;\Lambda&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;\lambda_{ij}&amp;lt;/math&amp;gt;) длины &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;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>Зиновьев Владимир</name></author>
	</entry>
</feed>